CBuild wiki: Internal structure of CBuild

CBuild project file structure

This project feathures two build targets and simple script with no additional files.


    project-root/
    ├── build                       // Build output and build data
    │   ├── <target>
    │   │   ├── <target>.meta  // Target metadata file
    │   │   ├── hash
    │   │   │   └── hash            // File hashes, old, before version 11.0
    │   │   ├── config              // Metadata for a files of this toolchain
    │   │   │   └── <target>_src.main.meta
    │   │   ├── objs                // Caches objects
    │   │   │   └── <target>_src.main.o
    │   │   └── out                 // Output binary
    │   │       └── <Target_name>.so
    │   └── <other_target>
    │       ├── <other_target>.meta  // Target metadata file
    │       ├── hash
    │       │   └── hash            // File hashes, old, before version 11.0
    │       ├── config              // Metadata for a files of this toolchain
    │       │   └── <other_target>_src.main.meta
    │       ├── objs                // Caches objects
    │       │   └── <other_target>_src.main.o
    │       └── out                 // Output binary
    │           └── <Other_target_name>.so
    ├── cache                       // Temporary data for CBuild runtime
    │   ├── headers
    │   ├── libs
    │   └── tmp
    ├── CBuild.run
    ├── compile_commands.json
    ├── scripts
    │   ├── main.cpp                // CBuild loader, main.cpp of CBuild
    │   ├── user_init.cpp           // User scripts
    │   └── user_init.hpp           // Header to call user funcs from CBuild main.cpp
    ├── <target>_src                // Source code of one target
    │   ├── main.cpp
    │   └── main.hpp
    └── <other_target>_src          // Source code of other target
        └── main.cpp
        




CBuild basic classes

CBuild contains a few major parts: a CLI args parser + main loop, a registry + base classes and a few standard libs of CBuild.

The CLI args parser and main loop consists of, as described in name, of parser of useer provided console arguments and main CBuild loop that setup all environment and call user script. It supports adding environment variables for a call to every shell command(this is not target-specific or task-specific!). Also it supports adding new parse rules for a custom arguments encoding.

The registry includes some big tables and user-faced function to add object to this table (plus it's name) and get it back. Also there is some base classes:

Standard CBuild library includes:


What CBuild does when user runs ./CBuild.run <some args>

Disclaimer: this section assumes that you don't modify main.cpp in scripts folder, that is provided by CBuild.

Firstly, code execution enters main() and then it runs user_init() function. It is a base of build-script. Then, when all user scripts is evalueated it creates lib::map<std::string, std::string> for storing user arguments after processing and then CBuild calls CBuild::parse function. This function return CBuild::RType(RunType) and aslo it takes pointer to lib::map created earlier, in function this map is populated with values. Then CBuild performs some checks - if RType is ERROR then CBuild exits. If user specifyes other run mode, than runtiime stores current path, obtained by std::string(std::filesystem::current_path().c_str()) to map with key "curr_path". Then CBuild core calls CBuild:loop() that preprocess all arguments, check run mode and run selected task, toolchain etc.


Build process overview

Disclaimer: this is based on CBuild:GXX toolchain implementation.

From the start, CBuild::Toolchain::call is called. We get args array pointer, and three booleans - are this compilation mode is force recompilation mode, are user is doing debug build or does this is a dummycall to resolve compilation args. Then CBuild core store these booleans and array to intenal variables and performs some checks. From the start CBuild::Toolchain::call checks if this target is dynamick library and if so, add -shared flag for linker. If debug build is specified, -g is added as compilation flag. Then, unconditionally -fPIC, -Icache/headers and -Lcache/libs is added. The we do toolchain init. This steps initializes directory structure for this target compilation. Then, if build type is dynamic library, runtime generates name of output binary, and add it as -Wl,-soname,<binary_name>. Then every dependancy task marked as PRE is called. Then every dependancy toolchain is called, all call arguments is passed from input argument to this call to CBuild::Toolchain::call, then we add so search pass and linker sear pass to find this dependancy library. Then pre_build, build, post_build and pre_link compilation steps are performed. These will be described later. Then, based on Build type we use standard linker to link object to binary, by calling link or use specific linker for packing static libraries by calling link_pack. And then last stepps of compilation - post_link is called! Now all that is left to do is to call all dependancy tasks, that is marked as POST and function can safely exits. Compilation is done!

build() This is toolchain implementation specific function, for CBuild::GXX it consists of: mergins compilation args list to one std::string, generating a list of files, that need to be recompiled using hasher and the constriction command to recompile each file in loop, for every file.

link() This is toolchain implementation specific function, for CBuild::GXX it consists of: merging linker args list to one std::string, getting list of object files in build/<toolchain_id>/objs/, merging this list to one std::string and then constring call to linker.

link_pack() This is toolchain implementation specific function, for CBuild::GXX it consists of: merging linker args list to one std::string, getting list of object files in build/<toolchain_id>/objs/, merging this list to one std::string and then constructing call to linker for static libraries (ar cr call).

Also, CBuild:GXX toolchain implementation unconditionally add this compilation and link arguments in it's constructor: -Wl,-z,origin and -Wl,-rpath,"\$ORIGIN".


BACK