Skip to content

Api documentation for Args, Register and Supported Plugin #185

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jan 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/linux_gcc_cmake_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ jobs:

- name: System Packages
run: |
sudo apt-get install ninja-build doxygen graphviz gcovr cppcheck clang-tidy
sudo apt-get install ninja-build doxygen graphviz cppcheck clang-tidy

- name: Install LCOV
run: |
Expand All @@ -179,7 +179,6 @@ jobs:
clang --version
ninja --version
doxygen --version
gcovr --version
cppcheck --version
clang-tidy --version

Expand Down
68 changes: 68 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,71 @@
# Versions

# 0.1.1

Complete working proof of concept of the following

- BuildCC library
- BuildCC bootstrap "script" files (Basic)
- BuildExe executable (Standalone)

Contains the following working features

**BuildCC**
- Supported plugin
- Clang Compile Commands
- Toolchain, Generator, TargetInfo and Target interfaces
- Specialized Toolchain for GCC, MSVC and MINGW
- Specialized Target for GCC, MSVC and MINGW

**BuildExe**
- Immediate mode
- Script mode
- Local Package Manager with git

## 0.1.2

- Serialization Interface
- Namespace changes
- Remove ``buildcc::base``
- Remove ``buildcc::env``
- We should only have 3 namespaces ``buildcc``, ``buildcc::plugin`` and ``buildcc::internal``
- Environment updates
- Remove ``buildcc::env``
- Refactor free / static functions and variables into classes with static members and variables. For example. ``buildcc::env::init`` should become ``buildcc::Environment::Init``
- Args and Register module updates
- Pch command from command line
- Make Register functions static. ``Register::Build``
- Update ``CallbackIf``, ``Build`` and ``Test`` APIs for the ``state`` variable usage
- Unit testing and mocking for BuildExe

## 0.1.3

- Make a common interface / internal library which contains all utility functions and libraries
- New generators
- Currently we only have a simple Generator which is similar to our FileIOGenerator (input -> subprocess commands -> outputs)
- Read the ``faq`` generators to make more varied and robust generators.

## 0.1.4

- Config options updates as per Target requirements
- Update configs to use ``fmt::format`` with format specifiers for "{prefix}{value}{suffix}" for customizability. For example: `/D{preprocessor}` for msvc or `-D{preprocessor}` for gcc etc
- Target specialized clang
- Clang behaves differently depending on its backend
- Option 1: Consider adding more options to ``ToolchainId`` and different Clang specializations. For example: ``Target_gcc_clang`` or ``Target_msvc_clang`` or ``Target_mingw_clang`` etc
- Option 2: Consider making a ``Target_clang`` that changes behaviour as per the ``target_triple_architecture`` present in the ``toolchain``
- What other flavours of clang are present?

## 0.2.x

- `Append*` APIs
- `Add*WithFormat` or `Append*WithFormat` APIs

## Long Term goals

- [Discussion] Supported plugin requirements by users
- [Discussion] Customizability requirements by users
- [Discussion] Target and Generator interfaces for standardization by compilers. (White paper)
- [Community Support] MacOS testing and CI/CD

# Feature

Expand Down
28 changes: 25 additions & 3 deletions buildcc/lib/args/include/args/args.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ struct ArgToolchain {
c_compiler(initial_c_compiler), cpp_compiler(initial_cpp_compiler),
archiver(initial_archiver), linker(initial_linker) {}

/**
* @brief Construct a BaseToolchain from the arguments supplied through the
* command line information
*/
BaseToolchain ConstructToolchain() const {
BaseToolchain toolchain(id, name, asm_compiler, c_compiler, cpp_compiler,
archiver, linker);
Expand Down Expand Up @@ -88,10 +92,22 @@ class Args {
Args() { Initialize(); }
Args(const Args &) = delete;

/**
* @brief Parse command line information to CLI11
*
* @param argc from int main(int argc, char ** argv)
* @param argv from int main(int argc, char ** argv)
*/
void Parse(int argc, const char *const *argv);

// TODO, Check if these are necessary
/**
* @brief Modifiable reference to CLI::App (CLI11)
*/
CLI::App &Ref() { return app_; }

/**
* @brief Constant reference to CLI::App (CLI11)
*/
const CLI::App &ConstRef() const { return app_; }

// Setters
Expand All @@ -106,8 +122,14 @@ class Args {
ArgToolchain &out,
const ArgToolchain &initial = ArgToolchain());

// NOTE, Incomplete TargetArg
// TODO, Update for pch_compile_command
/**
* @brief Add Target config commands with a unique name and description
*
* @param out Receive the target command information through the CLI
* @param initial Set the default target command information as a fallback
*
* TODO, Update with other options for TargetConfig
*/
void AddTarget(const std::string &name, const std::string &description,
ArgTarget &out, const ArgTarget &initial = ArgTarget());

Expand Down
48 changes: 31 additions & 17 deletions buildcc/lib/args/include/args/register.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,20 @@ class Register {
* Can be used to organize code into functional chunks
*/
template <typename C, typename... Params>
void Callback(const C &build_cb, Params &...params) {
build_cb(std::forward<Params &>(params)...);
void Callback(const C &build_cb, Params &&...params) {
build_cb(std::forward<Params>(params)...);
}

/**
* @brief Generic register callback that is run when `expression ==
* true`
* Can be used to add Toolchain-Target specific information
*/
template <typename C, typename... Params>
void CallbackIf(bool expression, const C &build_cb, Params &&...params) {
if (expression) {
Callback(build_cb, std::forward<Params>(params)...);
}
}

/**
Expand All @@ -57,35 +69,34 @@ class Register {
*/
template <typename C, typename... Params>
void CallbackIf(const ArgToolchainState &toolchain_state, const C &build_cb,
Params &...params) {
if (toolchain_state.build) {
Callback(build_cb, std::forward<Params &>(params)...);
}
Params &&...params) {
CallbackIf(toolchain_state.build, build_cb,
std::forward<Params>(params)...);
}

/**
* @brief Register the Target to be built
*/
template <typename C, typename... Params>
void Build(const ArgToolchainState &toolchain_state, const C &build_cb,
base::Target &target, Params &...params) {
BaseTarget &target, Params &&...params) {
tf::Task task;
CallbackIf(
toolchain_state,
[&](base::Target &ltarget, Params &...lparams) {
build_cb(ltarget, std::forward<Params &>(lparams)...);
[&](BaseTarget &ltarget, Params &&...lparams) {
build_cb(ltarget, std::forward<Params>(lparams)...);
task = BuildTargetTask(ltarget);
},
target, std::forward<Params &>(params)...);
target, std::forward<Params>(params)...);
BuildStoreTask(target.GetUniqueId(), task);
}

/**
* @brief Register the generator to be built
*/
template <typename C, typename... Params>
void Build(const C &build_cb, base::Generator &generator, Params &...params) {
build_cb(generator, std::forward<Params &>(params)...);
void Build(const C &build_cb, BaseGenerator &generator, Params &&...params) {
build_cb(generator, std::forward<Params>(params)...);
tf::Task task = BuildGeneratorTask(generator);
BuildStoreTask(generator.GetUniqueId(), task);
}
Expand All @@ -102,12 +113,15 @@ class Register {
/**
* @brief Register the Target to be run
* PreReq: Call `Register::Build` before calling `Register::Test`
* PreReq: Requires toolchain_state.build && test to be true
* PreReq: Requires ArgToolchainState::build && ArgToolchainState::test to be
* true
*
* Target is added as the `{executable}` argument
* Target is added as the `{executable}` argument.
* We can add more fmt::format arguments using the TestConfig arguments
* parameter
*/
void Test(const ArgToolchainState &toolchain_state,
const std::string &command, const base::Target &target,
const std::string &command, const BaseTarget &target,
const TestConfig &config = TestConfig());

/**
Expand Down Expand Up @@ -135,8 +149,8 @@ class Register {
void Env();

// BuildTasks
tf::Task BuildTargetTask(base::Target &target);
tf::Task BuildGeneratorTask(base::Generator &generator);
tf::Task BuildTargetTask(BaseTarget &target);
tf::Task BuildGeneratorTask(BaseGenerator &generator);
void BuildStoreTask(const std::string &unique_id, const tf::Task &task);

private:
Expand Down
28 changes: 22 additions & 6 deletions buildcc/lib/args/include/args/register/test_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,21 @@ namespace buildcc {

struct TestOutput {
enum class Type {
DefaultBehaviour, // Do not redirect to user or tests, default printed on
// console
TestPrintOnStderr, // Test only redirects stderr and prints
TestPrintOnStdout, // Test only redirects stdout and prints
TestPrintOnStderrAndStdout, // Test redirects both and prints
UserRedirect, // Redirects to user
DefaultBehaviour, ///< Do not redirect to user or tests, default printed on
///< console
TestPrintOnStderr, ///< Test only redirects stderr and prints
TestPrintOnStdout, ///< Test only redirects stdout and prints
TestPrintOnStderrAndStdout, ///< Test redirects both and prints
UserRedirect, ///< Redirects to user variables
};

/**
* @brief Configure your Register::Test to get test output
*
* @param output_type Select your output type (behaviour)
* @param redirect_stdout User stdout redirection
* @param redirect_stderr User stderr redirection
*/
TestOutput(Type output_type = Type::TestPrintOnStderrAndStdout,
std::vector<std::string> *redirect_stdout = nullptr,
std::vector<std::string> *redirect_stderr = nullptr)
Expand All @@ -56,6 +63,13 @@ struct TestOutput {

struct TestConfig {
public:
/**
* @brief Configure your Register::Test using TestConfig
*
* @param arguments fmt::format args passed to test commands
* @param working_directory Working directory from which the test runs
* @param output Output from tests
*/
TestConfig(
const std::unordered_map<const char *, std::string> &arguments = {},
const std::optional<fs::path> &working_directory = {},
Expand All @@ -77,6 +91,8 @@ struct TestConfig {
TestOutput output_;
};

// PRIVATE

struct TestInfo {
TestInfo(const BaseTarget &target, const std::string &command,
const TestConfig &config = TestConfig())
Expand Down
62 changes: 62 additions & 0 deletions docs/source/user_api/args.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,65 @@ Args
args.h
-------

.. doxygenclass:: buildcc::Args
:members: Args, Parse, Ref, ConstRef, AddToolchain, Clean, GetLogLevel, GetProjectRootDir, GetProjectBuildDir

.. doxygenstruct:: buildcc::ArgToolchainState

.. doxygenstruct:: buildcc::ArgToolchain

Example
---------

.. code-block:: cpp
:linenos:

int main(int argc, char ** argv) {
Args args;
ArgToolchain arg_gcc_toolchain;
args.AddToolchain("gcc", "Generic GCC toolchain", arg_gcc_toolchain);

// TODO, Add ArgTarget example (Currently incomplete)
args.Parse(argc, argv);

// Root
args.GetProjectRootDir(); // Contains ``root_dir`` value
args.GetProjectBuildDir(); // Contains ``build_dir`` value
args.GetLogLevel(); // Contains ``loglevel`` enum
args.Clean(); // Contains ``clean`` value

// Toolchain
// .build, .test
arg_gcc_toolchain.state;
// .id, .name, .asm_compiler, .c_compiler, .cpp_compiler, .archiver, .linker -> BaseToolchain
BaseToolchain gcc_toolchain = arg_gcc_toolchain.ConstructToolchain();

// Underlying CLI11 library
auto & app = args.Ref();
const auto & app = args.ConstRef();

return 0;
}

.. code-block:: toml
:linenos:

# Root
root_dir = ""
build_dir = "_build"
loglevel = "trace"
clean = true

# Toolchain
[toolchain.gcc]
build = true
test = true

id = "gcc"
name = "x86_64-linux-gnu"
asm_compiler = "as"
c_compiler = "gcc"
cpp_compiler = "g++"
archiver = "ar"
linker = "ld"

Loading