cxxbuild is a python script to easily generate C/C++ build files for cmake and bazel.
MIT License
cxxbuild (or "cplusplusbuild") is a python script to easily generate C/C++ build files for cmake and bazel.
cxxbuild version=1.6.4
pip install cxxbuild
(or pipx install cxxbuild
for newer distributions)For basic introduction, read the post: Using cxxbuild to easily build C++ project with tests and dependencies
We know it is very hard to start a C++ project and learn basics of build systems such as CMake and Bazel, and package managers like conan and vcpkg... so just type "cxxbuild" and be happy! But you MUST follow the canonical organization below:
project1/
|
| include/
| | package1/
| | file1.h
| | file2.hpp
| | ...
| src/
| | file1.cpp
| | file2.c
| | file_main.cpp
| | ...
| cxxdeps.txt
The strongest point of this project is the cxxdeps.txt
format,
that allow easy specification of dependencies from different package managers (in similar style of python requirements.txt
format)
To use it locally, just copy cxxbuild/cxxbuild.py file to your project and execute it: python3 cxxbuild.py help
Or, just install it from pip: pip install cxxbuild
(or pipx install cxxbuild
for newer distributions)
Then, just run: cxxbuild help
From this point, we assume cxxbuild is installed in your system :)
IMPORTANT: do not forget to install cmake (or bazel) too: pip install cmake
(or pipx install cmake
for newer distributions)
cxxbuild
has four main modes (three unimplemented, yet):
cxxbuild demo/project1
cxxbuild demo/project2
cxxbuild demo/project3
cxxbuild demo/project4 --c++20
cxxbuild demo/project5
cxxbuild demo/project6
All of them support both CMake and Bazel build systems, for common platforms Linux, Windows and Mac.
(*) Some limitations on windows/cmd are related to fmt dependency on cmake, not cxxbuild.
python3 cxxbuild/cxxbuild.py demo/project1
OR, after installation:
cxxbuild demo/project1
It will:
Generated binaries will be on demo/project1/build/
demo1
: binary with entrypoint (main) for demo (file: src/demo1.cpp
)my_test
: binary with unit tests (file: tests/my_test.cpp
)To clean it (since clean
command is still unimplemented), just delete build/
folder.
The tool cxxbuild assumes that:
src/
folder
--src SRC_PATH
optiontests/
folder
--tests TEST_PATH
optioninclude/
folder
--include INCLUDE_PATH
optionThe reason for src/
folder is:
src/
folder...)build/
folder in same directory level becomes contaminated with external .cpp dependencies, thus requiring some clever exclusion algorithmThe reason for tests/
folder is:
tests/
folder...).cpp
files and unit test files,tests.cpp
(but what about multiple tests then?)The reason for include/
folder is:
src/
folder and that is fine!These things can be easily changed, either manually on cxxbuild.py script, or by opening an issue and we discuss if some other option is really necessary... Note that this project does not aim to have many personalizations and complications, let's use KISS method!
Greatest advantage of this project is to easily describe dependencies on a cxxdeps.txt
file.
An example is:
fmt == "9.1.0" [ fmt ] git * https://github.com/fmtlib/fmt.git
Catch2 == "v3.3.1" [ Catch2::Catch2WithMain ] git test https://github.com/catchorg/Catch2.git
m
!std c++17
!build cmake
# this is a comment
This is quite simple and powerful, with few lines describing the following:
fmt
project from git repository in specific versionCatch2
project from git repository in specific version and use it for tests only-lm
dependencyc++17
is usedcmake
is usedThe git
part could be any package manager, such as conan and vcpkg, although not implemented yet!
The git
can be specified for cmake
or bazel
, like cmake+git
or bazel+git
.
The local
can be specified for cmake
or bazel
, like cmake+local
or bazel+local
.
On cmake
it represents a find_package
, while on bazel
it is a local_repository
(to implement, yet).
It can also be bcr
, for the Bazel Central Registry, or more specifically: bazel+bcr
(not supported for cmake+bcr
)
Some ongoing extensions will allow managing dev dependencies,
such as build systems (cmake, bazel, etc) and C/C++ package managers (conan, etc), all automatically on cxxdeps.txt
(or exclusively on cxxdeps.dev.txt
):
cmake == * [ cmake ] pip dev [ ninja ]
ninja:windows == * [ ninja ] choco dev
ninja:linux == * [ ninja-build ] apt dev
bazel:windows == * [ bazelisk ] choco dev
bazel:linux == * [ bazelisk ] npm dev
conan == * [ conan ] pip dev
Note that we can support triplet package notation on project name, so as different system package managers (such as apt on ubuntu/debian). Some package dependency notation can be useful as well to orchestrate installation flow, when necessary (as an example, ninja could be forcefully installed before cmake).
Other extension is some build
section... similar to dev
, but it installs automatically
before build process. The build
can be seen as a mandatory dev
dependency.
Some configure actions and patches could also happen in build
phase
(which are in fact some pre-build actions).
cxxdeps is a cool thing!
.toml
formatIt is currently possible to write cxxdeps.toml
file, that automatically generates cxxdeps.txt
and cxxdeps.dev.txt
files. Some users may find this easier to understand:
[all]
fmt={ git="https://github.com/fmtlib/fmt.git", tag="9.1.0", links=["fmt"] }
m={ links=["m"] }
pthread={}
[test]
catch2={ git="https://github.com/catchorg/Catch2.git", tag="v3.3.1", links=[
"Catch2::Catch2WithMain"
] }
[dev]
bazel=[{ choco=["bazelisk"], platform="windows" }, { npm=["bazelisk"], platform="linux" }]
ninja=[{ choco=["ninja"], platform="windows" }, { apt=["ninja-build"], platform="linux" }]
cmake={ pip=["cmake"], deps=["ninja"] }
conan={ pip=["conan"] }
Here one can find sections all
(equivalent to *
), test
and dev
.
This example install system libraries -lm
and -lpthread
for runtime dependencies (all
),
catch2
test library linked with cmake Catch2::Catch2WithMain
, and defines several dev packages.
Check an example in project3 with: python3 cxxbuild/cxxbuild.py demo/project3
None that I know, yet :)
Some people may dislike the imposed organization, like src/
and tests/
, but it can be changed manually on script. The idea here is to really make a simplistic script, that really works with highly complex setups (such as taking dependencies from remote and dealing with build systems like cmake and bazel). These things are hard to do even for some experienced c++ programmers... so, as long as it is simple and it works, that is fine! If it doesn't work, file an issue!
!options
on cxxdepsThe cxxdeps.txt
file allows defining some usual command line parameters with !
prefix.
Examples:
--c++20
appears on file as !std c++20
--cmake
appears on file as !build cmake
--bazel
appears on file as !build bazel
--include dir
appears on file as !include "dir"
Command-line parameters have priority over cxxdeps.txt
and can overwrite or complement them (with exception of !build
parameter that cannot be overwritten).
In the future, the !options
could be limited by operating system, e.g., !option:windows
.
None of them support dependencies, such as cxxdeps.txt
, or even build systems such as cmake and bazel.
Hopefully, when this project is fully finished, C++ will be a better place for all of us :)
A very interesting case of study is the use of cxxbuild to build the C/C++ ccbuild tool. It is currently very easy to build it, using the following cxxdeps file:
bobcat
gnutls
fl
png
FLEX == * [ ] local * _ false patch_flex.txt
!std c++20
!tests test
!include "src"
!include "src/sourceScanner"
!define VERSION="v2.0.7-39-gdf7b35c"
!extrasrc ${FLEX_SourceScanner_OUTPUTS}
# apt install flex
# apt install libboost-all-dev
# apt install gnutls-dev
# apt install libbobcat-dev
# apt install libpng-dev
Also create the following patch_flex.txt
file:
FLEX_TARGET(SourceScanner "src/sourceScanner/lexer" "src/sourceScanner/yylex.cc" )
cxxbuild . --tests test --include src --include src/sourceScanner --c++20
(or just cxxbuild
, since build options will come directly from cxxdeps.txt)add_definitions(-DVERSION="v2.0.7-39-gdf7b35c")
${FLEX_SourceScanner_OUTPUTS}
find_package(FLEX)
FLEX_TARGET(SourceScanner "src/sourceScanner/lexer" "src/sourceScanner/yylex.cc" )
And that's it! It builds all avaliable targets and tests for ccbuild.
See complete example on folder usecases/ccbuild.
Thanks for those trying to use and improve this software. Specially, thanks Fellipe Pessanha for early suggesting integrating toml support for cxxdeps.
Igor Machado Coelho. (2023). cxxbuild project. Zenodo. https://doi.org/10.5281/zenodo.10447208
Dual licensed: Creative Commons Attribution 4.0 International OR MIT License
Copyleft 2023
Igor Machado Coelho