Skip to main content

Tutorial: Your First Buck2 Application

Welcome! This tutorial will help you learn the basics of building your first Rust application with Buck2. We will start from the very beginning, guiding you step-by-step to get a "Hello, World!" message displayed in your terminal. Through this practical exercise, you'll acquire foundational skills for working with Buck2.

What We'll Do:

  1. Set up a simple project directory.
  2. Write a "Hello, World!" program in Rust.
  3. Create a BUCK file to tell Buck2 how to build our program.
  4. Build the Rust program using Buck2.
  5. Run our compiled program using Buck2.
  6. Briefly inspect the build targets we created.

Preqrequisites:

  • For this tutorial, we will use Rust. You don't need to know how to write Rust. We will only use a few basic of Rust.

Step 1: Create a New Project

First, we need to create a new buck2 project directory and set up a folder to put all our files in.

  1. Create a new buck2 project directory and create a new directory named buck2_lab inside it.
buck2 init hello_world

mkdir hello_world/buck2_lab

cd hello_world/buck2_lab
  1. Inside buck2_lab, create another directory named greeter_bin, this is where all files of our Buck2 binary package will be stored.
mkdir greeter_bin
  1. Create greeter_bin/src directory, this is where all source files of our binary will live.
mkdir greeter_bin/src

Our project structure should look like this:

buck2_lab
└── greeter_bin
└── src

Step 2: Writing the "Hello, World!" Program

Now, let's write our simple Rust program.

  1. Inside the src directory, create a new file named main.rs.
  2. Open src/main.rs in your favorite text editor and add the following code:
fn main() {
println!("Hello world!");
}

This is the main function of our program. It prints "Hello world!" to the console. But we are not done yet, we need to tell Buck2 how to build our program.

Step 3: Defining the Build Target in a BUCK File

Next, we need to tell Buck2 about our program and how to build it. We do this using a BUCK file.

  1. In the root of your greeter_bin directory (not inside src), create a new file named BUCK.

  2. Add the following content to this BUCK file:

rust_binary(
name = "main",
srcs = ["src/main.rs"],
)

Let's briefly see what this does (we'll keep explanations minimal, just enough for this step! ):

  • load(...) is a load statement. It tells Buck2 to load the definition of the rust_binary.
  • rust_binary is a Buck2 rule that tells Buck2 how to build a Rust binary.
  • name = "main": We're giving our build target a name, "main". This is how we'll refer to it in Buck2 commands.
  • srcs = ["src/main.rs"]: This tells Buck2 that the source code for this "main" target is our src/main.rs file.

Our project structure should look like this:

buck2_lab
└── greeter_bin
├── BUCK
└── src
└── main.rs

Step 4: Building the Application with Buck2

With our Rust code and BUCK file in place, let's build the application!

  1. Open your terminal and make sure you are in the greeter_bin directory.
  2. Run the following command:
buck2 build :main --show-output
  • buck2 build :main tells Buck2 to build the target named main. The :main part means the target is defined in the BUCK file in the root of this package (greeter_bin).
  • --show-output tells Buck2 to show the path of our built binary.
  1. Expected Output: You should see output similar to this
...
BUILD SUCCEEDED
root//buck2_lab/greeter_bin:main /.../buck2_lab/buck-out/v2/gen/root/200212f73efcd57d/buck2_lab/greeter_bin/__main__/main
  • BUILD SUCCEEDED indicates that Buck2 successfully build our target.
  • root//buck2_lab/greeter_bin:main is the full target label name of our target.
  • Think of the :main we used in the step 2 as a relative path to the target from within its package (greeter_bin).
  • The full name root//buck2_lab/greeter_bin:main is like an absolute path, uniquely identifying the target within your entire project (fbsource).
  • buck-out/.../__main__/main is the path of our binary output. It is the path relative path to fbsource. You can use --show-full-output instead of --show-output to get the absulate path.

Step 5: Running Your Application with Buck2

Since our target is a runnable target, we can run it by buck2 run

  1. In your terminal (still in the greeter_bin directory), execute:
buck2 run :main

This command tells Buck2 to run the main target. Buck2 will build it if it hasn't been built already, and then execute it. (i.e. We can do this whithout step 4)

  1. Expected Output: You will see:
Hello world!

There it is! Our program ran successfully and printed the message.

Step 6: Inspecting Your Target (Optional)

This step is optional, but it's good to know how you can ask Buck2 about the targets you've defined.

  1. To see the target that we defined (still in the greeter_bin directory), run:
buck2 targets :

or

buck2 targets fbcode//scripts/nero/buck2_lab/greeter_bin:
  1. Expected Output:

This will show all the targets we defined,

root//buck2_lab/greeter_bin:main

Conclusion

Congratulations! 🎉

You have successfully created, built, and run your first application using Buck2! We've walked through

  • Setting up the project structure.
  • Writing a simple Rust program.
  • Defining a rust_binary target in a BUCK file.
  • Using buck2 build to compile the code.
  • Using buck2 run to execute the program.
  • Using buck2 targets to inspect the target.

You've taken your first concrete steps into the world of Buck2.