Skip to content

Commit

Permalink
porting bazel c++ example to hancho
Browse files Browse the repository at this point in the history
  • Loading branch information
aappleby committed Nov 2, 2024
1 parent d1e5181 commit 74a310a
Show file tree
Hide file tree
Showing 20 changed files with 260 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/bazel-cpp-tutorial/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a copy of Bazel's C++ build tutorial, ported to Hancho for comparison.
39 changes: 39 additions & 0 deletions examples/bazel-cpp-tutorial/stage1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Stage 1

This showcases how to build a single file to create a runnable application.

This BUILD file shows that we want to build a C++ binary using the ```cc_binary``` rule provided by Bazel.
In the ```cc_binary``` rule, name of the binary is specified in ```name``` attribute (in this example, it's ```hello-world```), required source files to be built are provided in ```srcs``` attribute.

```
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
```

To build this example, use
```
bazel build //main:hello-world
```

If the build is successful, Bazel prints the output similar to
```
____Loading complete. Analyzing...
____Found 1 target...
____Building...
Target //main:hello-world up-to-date:
C:/tools/msys64/tmp/_bazel_woden/vqeu6v3v/execroot/__main__/bazel-out/msvc_x64-fastbuild/bin/main/hello-world.exe
____Elapsed time: 0,400s, Critical Path: 0,01s
```

In the run log above you can see where the executable was built so you can locate it and use it.

You can also get the output path with the bazel cquery command. For
example, the command below would print the path to the output file. This
is a useful technique for use in scripts, where you do not want to parse the
`bazel build` output.

```
bazel cquery --output=files //main:hello-world
```
20 changes: 20 additions & 0 deletions examples/bazel-cpp-tutorial/stage1/build.hancho
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ----------------------------------------

compile_cpp = hancho.Config(
desc="Compiling C++ {rel(in_src)} -> {rel(out_obj)} ({build_tag})",
command="g++ -c {in_src} -o {out_obj}",
out_obj="{swap_ext(in_src, '.o')}",
in_depfile="{swap_ext(in_src, '.d')}",
)

link_cpp_lib = hancho.Config(
desc="Bundling C++ lib {rel(out_lib)}",
in_objs=None,
out_lib=None,
command="ar rcs {rel(out_lib)} {rel(in_objs)}",
)

cc_binary = hancho.Config(
desc="Linking C++ bin {rel(out_bin)}",
command="g++ {in_srcs} {in_objs} {in_libs} -o {out_bin}",
)
5 changes: 5 additions & 0 deletions examples/bazel-cpp-tutorial/stage1/main/build.hancho
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
hancho(
hancho.cc_binary,
name = "hello-world",
in_srcs = ["hello-world.cc"],
)
22 changes: 22 additions & 0 deletions examples/bazel-cpp-tutorial/stage1/main/hello-world.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <ctime>
#include <string>
#include <iostream>

std::string get_greet(const std::string& who) {
return "Hello " + who;
}

void print_localtime() {
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result));
}

int main(int argc, char** argv) {
std::string who = "world";
if (argc > 1) {
who = argv[1];
}
std::cout << get_greet(who) << std::endl;
print_localtime();
return 0;
}
Empty file.
30 changes: 30 additions & 0 deletions examples/bazel-cpp-tutorial/stage2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Stage 2

### Library

Here, we introduce the ```cc_library``` rule for building C++ libraries. We have a ```cc_library``` named ```hello-greet``` and its header and source files are defined accordingly.
```
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
```

### Binary

The ```cc_binary``` rule we saw in stage 1 has not changed, except that we now depend on the ```cc_library``` ```hello-greet```.
```
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
],
)
```

To build this example, use
```
bazel build //main:hello-world
```
13 changes: 13 additions & 0 deletions examples/bazel-cpp-tutorial/stage2/main/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)

cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
],
)
6 changes: 6 additions & 0 deletions examples/bazel-cpp-tutorial/stage2/main/hello-greet.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "hello-greet.h"
#include <string>

std::string get_greet(const std::string& who) {
return "Hello " + who;
}
8 changes: 8 additions & 0 deletions examples/bazel-cpp-tutorial/stage2/main/hello-greet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef MAIN_HELLO_GREET_H_
#define MAIN_HELLO_GREET_H_

#include <string>

std::string get_greet(const std::string &thing);

#endif
19 changes: 19 additions & 0 deletions examples/bazel-cpp-tutorial/stage2/main/hello-world.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "hello-greet.h"
#include <ctime>
#include <iostream>
#include <string>

void print_localtime() {
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result));
}

int main(int argc, char** argv) {
std::string who = "world";
if (argc > 1) {
who = argv[1];
}
std::cout << get_greet(who) << std::endl;
print_localtime();
return 0;
}
Empty file.
32 changes: 32 additions & 0 deletions examples/bazel-cpp-tutorial/stage3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Stage 3

In this stage we step it up and showcase how to integrate multiple ```cc_library``` targets from different packages.

Below, we see a similar configuration from Stage 2, except that this BUILD file is in a subdirectory called lib. In Bazel, subdirectories containing BUILD files are known as packages. The new property ```visibility``` will tell Bazel which package(s) can reference this target, in this case the ```//main``` package can use ```hello-time``` library.

```
cc_library(
name = "hello-time",
srcs = ["hello-time.cc"],
hdrs = ["hello-time.h"],
visibility = ["//main:__pkg__"],
)
```

To use our ```hello-time``` library, an extra dependency is added in the form of //path/to/package:target_name, in this case, it's ```//lib:hello-time```

```
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
"//lib:hello-time",
],
)
```

To build this example, use
```
bazel build //main:hello-world
```
7 changes: 7 additions & 0 deletions examples/bazel-cpp-tutorial/stage3/lib/build.hancho
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
hancho(
hancho.rules.cpp_
name = "hello-time",
srcs = ["hello-time.cc"],
hdrs = ["hello-time.h"],
visibility = ["//main:__pkg__"],
)
8 changes: 8 additions & 0 deletions examples/bazel-cpp-tutorial/stage3/lib/hello-time.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "lib/hello-time.h"
#include <ctime>
#include <iostream>

void print_localtime() {
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result));
}
6 changes: 6 additions & 0 deletions examples/bazel-cpp-tutorial/stage3/lib/hello-time.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef LIB_HELLO_TIME_H_
#define LIB_HELLO_TIME_H_

void print_localtime();

#endif
16 changes: 16 additions & 0 deletions examples/bazel-cpp-tutorial/stage3/main/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
hello_greet = hancho(
hancho.cc_library,
name = "hello-greet",
in_srcs = ["hello-greet.cc"],
in_hdrs = ["hello-greet.h"],
)

hancho(
hancho.cc_binary,
name = "hello-world",
in_srcs = ["hello-world.cc"],
in_deps = [
hello-greet,
hancho.lib.hello-time
],
)
6 changes: 6 additions & 0 deletions examples/bazel-cpp-tutorial/stage3/main/hello-greet.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "main/hello-greet.h"
#include <string>

std::string get_greet(const std::string& who) {
return "Hello " + who;
}
8 changes: 8 additions & 0 deletions examples/bazel-cpp-tutorial/stage3/main/hello-greet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef MAIN_HELLO_GREET_H_
#define MAIN_HELLO_GREET_H_

#include <string>

std::string get_greet(const std::string &thing);

#endif
14 changes: 14 additions & 0 deletions examples/bazel-cpp-tutorial/stage3/main/hello-world.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "lib/hello-time.h"
#include "main/hello-greet.h"
#include <iostream>
#include <string>

int main(int argc, char** argv) {
std::string who = "world";
if (argc > 1) {
who = argv[1];
}
std::cout << get_greet(who) << std::endl;
print_localtime();
return 0;
}

0 comments on commit 74a310a

Please sign in to comment.