is a fast build tool developed by Facebook. There are , but how should you get started? Buck many reasons to choose Buck This walk-through will cover: How to organize your project Integration of Google Test Explanation of the basic Buck commands TL;DR Browse , or clone them onto your system: the project files on GitHub git clone :njlr/buck-cpp-example.git git@github.com Install existing Buck ports from . Buckaroo.pm How Buck Works Before we start, it might be helpful to understand how Buck works. Rather than retread old ground, take a look at this talk from the Buck devs. Ludicrously Fast Builds with Buck Installing Buck The official guide for installing Buck is . However, the quickest way is probably to use Homebrew or Linuxbrew. available on their website If you are using Linux, you can install Linuxbrew using a . one-liner on their website Ditto for on macOS. Homebrew Once you have a “brew” installed, add the Facebook tap and install Buck: brew tap facebook/fbbrew install --HEAD facebook/fb/buck Verify your installation with: buck --version Organizing Your Files Once Buck is installed, it’s time to create the project folders. Buck makes it easy to support any folder structure you like, but for this demo we will be following the C/C++ convention of and folders. src include This project will consist of two parts: — an executable that computes and prints the result demo 3 + 4 — a library that provides simple adding functionality mathutils Note: This is a simple example for demonstration purposes; Buck is capabable of building complex C/C++ projects ! First, create the following structure somewhere on your drive: .├── .buckconfig├── BUCK└── demo├── include└── src└── main.cpp Using the command-line: touch .buckconfigtouch BUCK mkdir demomkdir demo/includemkdir demo/srctouch demo/src/main.cpp That’s quite a few files — let’s run through them: A is required before you can run any Buck commands. It tells Buck where the root of your project is and can also be used to configure any settings that are global to your project. For now we can leave it empty. .buckconfig The file is where we will define the target for our binary. There can be multiple files in a Buck project, which is useful when you want to seperate the build logic for different aspects of your project, such as libraries and tests. BUCK BUCK is where we will be putting any headers used by the binary. demo/include is where we will be putting our translation-units (in this case files) for the binary. demo/src .cpp will be the entry-point for our application. demo/src/main.cpp main.cpp To get started, we will write a simple hello-world program. Paste the following into : main.cpp BUCK To build the file, we need to write a Buck target for it. Into the file, paste the following: main.cpp BUCK files are written in a dialect of Python 2, with a few extensions. When you call , Buck will execute the Python and record any targets the are defined. Once the list of targets has been resolved, each target is built in accordance with its type. BUCK buck build You can see the full list of target-types in , but the important ones for C/C++ are , and . the Buck docs cxx_binary cxx_library prebuilt_cxx_library — a bundle of C/C++ translation-units and headers that contain an entry-point (e.g. ). A can be executed once compiled. It should not be a dependency. cxx_binary int main() cxx_binary — a bundle of C/C++ translation-units that can be used by other targets. Unlike a , a library also defines a list of , which are the header-files made available to its dependents. cxx_library cxx_binary exported_headers — like a , but with an optional object-file in the place of translation units. Header-only libraries are implemented as a with no object-file. prebuilt_cxx_library cxx_library prebuilt_cxx_library Buck Commands Now that the file is in place, Buck can build the target. Run the following: BUCK buck build //:demo The command tells Buck to build the target found in the file adjacent to . :demo BUCK .buckconfig Buck uses a simple addressing system for targets based on the actual folder-structure of the project. For example, refers to the target defined in . //examples/basic/:demo demo examples/basic/BUCK After the build completes, you should find an executable at . You can build and run this using: buck-out/gen/demo buck build //:demo && ./buck-out/gen/demo Or, Buck can do it for you: buck run //:buck-cpp-example You will notice that running the build for a second time is extremely fast. This is because Buck caches everything, including the output of the Python scripts! Adding a Dependency Let’s implement so that we can use it in the demo application. mathutils Create the following folder structure in your project: .└── mathutils├── BUCK├── include│ └── add.hpp└── src└── add.cpp Using the command-line: mkdir mathutilsmkdir mathutils/includemkdir mathutils/src touch mathutils/BUCKtouch mathutils/include/add.hpptouch mathutils/src/add.cpp And the files themselves: There are a few important points about this file: BUCK The is set to . This puts every header-file that the library exports into a folder with that name, making file-name collisions with other libraries less likely. header_namespace 'mathutils' The rules are rooted at the file, so actually corresponds to from the project root. glob BUCK src/**/*.cpp mathutils/src/**/*.cpp The visibility is set to so that the target can be taken as a dependency by all other targets in the project. In English it means “this library is visibile to every other target below root”. //... Using the Add Function Now we can use the library in the executable. mathutils demo First, declare the dependency of on . Change the file at the root of the project to: demo mathutils BUCK Now update to: main.cpp Use Buck to run to see the result. You will notice that Buck knows how to link for you. demo mathutils Google Test Our application is working, but to be diligent we should add some unit-tests! Buck supports all C/C++ testing frameworks via , but it provides additional integration with Google Test. buck run Fetching the Google Test Source-code Git provides a simple way to grab the Google Test source-code using submodules. We will be using that contains a file, but you can use the master and write your own if desired. a fork BUCK git submodule add git@github.com:njlr/googletest.gitcd googletest/git checkout 48072820e47a607d000b101c05d796ebf9c4aad2cd ../ Now we need to tell Buck where to find the Google Test sources. Open the and add the following: .buckconfig This tells Buck where to find the Google Test target that it can use for your tests. There are other config properties that can be set; have a browse in the . Buck docs Writing a Test We will put the tests into a , alongside and : mathutils/test mathutils/src mathutils/include .└── mathutils├── BUCK├── include│ └── add.hpp├── src│ └── add.cpp└── test├── BUCK└── add.cpp Using the command-line: mkdir mathutils/testtouch mathutils/test/add.cpp And the test itself: Finally, we need to declare the test in the file: BUCK Now the tests can be run by Buck: buck test //mathutils/test:add Or, to run all tests: buck test Conclusion And that’s it! Buck is a powerful tool that will . To learn more, read or watch some of the . save you hours of waiting over the development cycle of a project the docs Buck presentations If there is a library you need to port to Buck, take a look at . We’ve already ported 300 projects, and are ! Buckaroo.pm working on even more
Share Your Thoughts