-
Notifications
You must be signed in to change notification settings - Fork 17
Repobuild Cpp Tutorial
This will help you create a new "repobuild" based project. This tutorial is in C++.
If you have not already, install repobuild (see README)
- Fork the example_cpp project: https://github.com/chrisvana/repobuild_cpp_example
- Set up the repository locally:
$ git clone https://github.com/<username>/repobuild_cpp_example
$ cd repobuild_cpp_example
Currently, the BUILD file looks like this:
[
// This is empty!
]
We are going to create a new library called "printer"
[
{ "cc_library": {
"name": "printer",
"cc_headers": [ "printer.h" ],
"cc_sources": [ "printer.cc" ]
} }
]
And now create printer.h:
// This is an example printer!
#ifndef _PRINTER_H__
#define _PRINTER_H__
namespace printer {
class Printer {
public:
Printer() {}
~Printer() {}
void PrintMyLines();
};
} // namespace printer
#endif // _PRINTER_H__
And printer.cc:
// My printer implementation!
#include <iostream>
#include "printer.h"
namespace printer {
void Printer::PrintMyLines() {
std::cout << "My lines are pretty uninteresting." << std::endl;
}
} // namespace printer
Run repobuild:
$ repobuild ":printer"
Processing: //:printer
Generating: Makefile
$ # Note: if your ld binary is old, you may need to run:
$ # repobuild ":printer" --enable_flto_object_files=false
$
Now run make:
$ make
Compiling: printer.cc (c++)
$ # This should have built a .o file:
$ ls .gen-obj/*.o
.gen-obj/printer.o
$
Great, you have now built a static library for printer!
Optionally, commit your changes:
$ # The makefile was auto-generated by repobuild:
$ git add Makefile
$ git add BUILD
$ git add printer.h printer.cc
$ git commit -m 'up to step 5'
$ git push
$
Your client should now look like this.
We are going to add a binary, so edit the BUILD file:
[
{ "cc_library": {
"name": "printer",
"cc_headers": [ "printer.h" ],
"cc_sources": [ "printer.cc" ]
} },
{ "cc_binary": {
"name": "printer_main",
"cc_sources": [ "printer_main.cc" ],
"dependencies": [ ":printer" ]
} }
]
And now add printer_main.cc:
// Binary to run our printer!
#include "printer.h"
int main(int argc, char** argv) {
printer::Printer print;
print.PrintMyLines();
return 0;
}
And run repobuild/make again:
$ repobuild ":printer_main"
Processing: //:printer_main
Processing: //:printer
Processing: //:printer_main.0
Processing: //:printer_main
Generating: Makefile
$ make
Compiling: printer_main.cc (c++)
Linking: .gen-obj/printer_main
$ # This should have generated a binary:
$ ls bin/printer_main
bin/printer_main
Now you can run your binary
$ bin/printer_main
My lines are pretty uninteresting.
Optionally, commit your changes:
$ # The makefile was auto-generated by repobuild:
$ git add Makefile
$ git add BUILD
$ git add printer_main.cc
$ git commit -m 'up to step 7'
$ git push
$
Your client should now look like this.
Add the "common" submodule
$ git submodule add https://github.com/chrisvana/common.git
$ ls common
BUILD LICENSE README.md __init__.py base file log strings test third_party util
$
Note: If you were clone this project after adding "common", repobuild would automatically initialize "common" when required without manually running "git submodule ...". This allows submodules to collectively contain a lot of code without having to pull it all down locally.
Now, let's add binary flags to printer.cc. First, update printer's dependencies in the BUILD file:
[
{ "cc_library": {
"name": "printer",
"cc_headers": [ "printer.h" ],
"cc_sources": [ "printer.cc" ],
"dependencies": [ "//common/base:flags" ]
} },
{ "cc_binary": {
"name": "printer_main",
"cc_sources": [ "printer_main.cc" ],
"dependencies": [ ":printer" ]
} }
]
Second, update printer with a flag:
// My printer implementation!
#include <iostream>
#include "printer.h"
#include "common/base/flags.h"
// These flag values can be specified at run time like:
// bin/printer_main --my_lines="something else!"
DEFINE_string(my_lines, "My lines are user controlled.",
"User specified lines.");
namespace printer {
void Printer::PrintMyLines() {
std::cout << FLAGS_my_lines << std::endl;
}
} // namespace printer
Next, let's update our binary to make sure it parses the flag. Step 1, update the BUILD file again:
[
{ "cc_library": {
"name": "printer",
"cc_headers": [ "printer.h" ],
"cc_sources": [ "printer.cc" ],
"dependencies": [ "//common/base:flags" ]
} },
{ "cc_binary": {
"name": "printer_main",
"cc_sources": [ "printer_main.cc" ],
"dependencies": [ ":printer", "//common/base:init" ]
} }
]
And printer_main.cc to do the parsing:
// Binary to run our printer!
#include "common/base/init.h"
#include "printer.h"
int main(int argc, char** argv) {
InitProgram(&argc, &argv); // command line flag parsing, etc.
printer::Printer print;
print.PrintMyLines();
return 0;
}
Ok, let's build it!
$ repobuild ":printer_main"
Processing: //:printer_main
Processing: //:printer
Processing: //common/base:init
Processing: //:printer_main.0
Processing: //common/base:flags
Processing: //common/log:log
Processing: //common/third_party/google/init:init
Processing: //common:auto_.0
Processing: //:printer_main
Processing: //common/third_party/google/gflags:gflags
Processing: //common/third_party/google/glog:glog
Processing: //common/third_party/google/glog:glog_gen
Processing: //common/third_party/google/glog:glog_gen.0
Processing: //common/third_party/google/glog:glog_gen.1
Processing: //common/third_party/google/glog:glog_gen.1.0
Generating: Makefile
$ make -j8
Compiling: common/third_party/google/gflags/src/gflags.cc (c++)
Compiling: common/third_party/google/gflags/src/gflags_completions.cc (c++)
Compiling: common/third_party/google/gflags/src/gflags_nc.cc (c++)
Compiling: common/third_party/google/gflags/src/gflags_reporting.cc (c++)
Compiling: printer.cc (c++)
Autoconf: //common/third_party/google/glog:glog_gen.0
Make: //common/third_party/google/glog:glog_gen.1.0
Compiling: common/base/init.cc (c++)
Compiling: printer_main.cc (c++)
Linking: .gen-obj/printer_main
You can now run a command like:
$ bin/printer_main --my_lines="That's not a knife"
That's not a knife
Your client should now look like this.
Optionally, commit your changes:
$ git add BUILD Makefile printer.cc printer_main.cc common
$ git commit -m 'up to step 9'
$ git push
Congratulations, you've built a binary that depends on a bunch of other libraries. Check out some other examples: https://github.com/chrisvana/repobuild/wiki/Examples