diff --git a/README.md b/README.md index be53f7bb..4dc85912 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,7 @@ Basic Installation steps # FAQ - [Why has _this_ third-party library been chosen?](doc/faq/why_this_lib.md) +- [How do I create my own custom target commands?](doc/custom_target/commands.md) ## Design diff --git a/buildcc/lib/target/cmake/mock_target.cmake b/buildcc/lib/target/cmake/mock_target.cmake index 3911def5..a6f54dd1 100644 --- a/buildcc/lib/target/cmake/mock_target.cmake +++ b/buildcc/lib/target/cmake/mock_target.cmake @@ -19,7 +19,8 @@ target_sources(mock_target PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/fbs/fbs_storer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/util/util.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/mock/util/command.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/util/command.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock/util/execute.cpp ) target_compile_options(mock_target PUBLIC ${TEST_COMPILE_FLAGS} ${BUILD_COMPILE_FLAGS}) diff --git a/buildcc/lib/target/cmake/target.cmake b/buildcc/lib/target/cmake/target.cmake index 7cc7d5d9..d4800541 100644 --- a/buildcc/lib/target/cmake/target.cmake +++ b/buildcc/lib/target/cmake/target.cmake @@ -31,6 +31,7 @@ target_sources(target PRIVATE src/util/util.cpp src/util/command.cpp + src/util/execute.cpp include/target.h include/internal/fbs_loader.h diff --git a/buildcc/lib/target/cmake/target_install.cmake b/buildcc/lib/target/cmake/target_install.cmake index 85155947..5124de70 100644 --- a/buildcc/lib/target/cmake/target_install.cmake +++ b/buildcc/lib/target/cmake/target_install.cmake @@ -7,6 +7,7 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/internal/fbs_loader.h ${CMAKE_CURRENT_SOURCE_DIR}/include/internal/path.h ${CMAKE_CURRENT_SOURCE_DIR}/include/internal/util.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/internal/command.h DESTINATION "${BUILDCC_INSTALL_HEADER_PREFIX}/internal" ) install(EXPORT targetConfig DESTINATION "${BUILDCC_INSTALL_LIB_PREFIX}/target") diff --git a/buildcc/lib/target/include/internal/command.h b/buildcc/lib/target/include/internal/command.h new file mode 100644 index 00000000..e0cd5352 --- /dev/null +++ b/buildcc/lib/target/include/internal/command.h @@ -0,0 +1,50 @@ +/* + * Copyright 2021 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TARGET_INCLUDE_INTERNAL_COMMAND_H_ +#define TARGET_INCLUDE_INTERNAL_COMMAND_H_ + +#include + +#include "internal/path.h" + +#include "toolchain.h" + +namespace buildcc::internal { + +class Command { +public: + explicit Command() = default; + + void AddDefaultArguments( + const std::unordered_map &arguments); + + std::string Construct(std::string_view format, + const std::unordered_map + &arguments = {}) const; + bool ConstructAndExecute(std::string_view format, + const std::unordered_map + &arguments = {}) const; + + static bool Execute(const std::string &command); + +private: + std::unordered_map default_values_; +}; + +} // namespace buildcc::internal + +#endif diff --git a/buildcc/lib/target/include/internal/util.h b/buildcc/lib/target/include/internal/util.h index 16be53d9..6baafecb 100644 --- a/buildcc/lib/target/include/internal/util.h +++ b/buildcc/lib/target/include/internal/util.h @@ -24,18 +24,6 @@ namespace buildcc::internal { -// System -/** - * @brief Executes an external command - * Internally command uses `std::system` - * TODO, Replace with `subprocess` - * - * @param command - * @return true - * @return false - */ -bool command(const std::string &command); - // Additions /** * @brief Existing path is stored inside stored_paths diff --git a/buildcc/lib/target/include/target.h b/buildcc/lib/target/include/target.h index 3642664c..75daa18a 100644 --- a/buildcc/lib/target/include/target.h +++ b/buildcc/lib/target/include/target.h @@ -25,6 +25,7 @@ #include // Internal +#include "internal/command.h" #include "internal/fbs_loader.h" #include "internal/path.h" @@ -260,29 +261,21 @@ class Target { std::unordered_set current_cpp_compile_flags_; std::unordered_set current_link_flags_; - // TODO, Make appending to this more efficient // TODO, Might not need to be persistent - // TODO, aggregates might not need to exist, check `std::insert` APIs over - // vector and unordered_set - std::string aggregated_include_dirs_; - std::string aggregated_lib_dirs_; - // NOTE, This contains current_external_lib_deps_ + current_lib_deps_ - std::string aggregated_lib_deps_; - - std::string aggregated_preprocessor_flags_; std::string aggregated_c_compile_flags_; std::string aggregated_cpp_compile_flags_; - std::string aggregated_link_flags_; // TODO, Add more internal variables internal::FbsLoader loader_; - bool dirty_ = false; + internal::Command command_; // Build states + bool dirty_ = false; bool first_build_ = false; bool rebuild_ = false; + // Dependency static constexpr const char *const kCompileTaskName = "Compile"; static constexpr const char *const kLinkTaskName = "Link"; diff --git a/buildcc/lib/target/mock/expect_target.h b/buildcc/lib/target/mock/expect_target.h index 9aba49c0..7e53c505 100644 --- a/buildcc/lib/target/mock/expect_target.h +++ b/buildcc/lib/target/mock/expect_target.h @@ -7,7 +7,7 @@ namespace buildcc { namespace internal::m { -void Expect_command(unsigned int calls, bool expectation); +void CommandExpect_Execute(unsigned int calls, bool expectation); } // namespace internal::m diff --git a/buildcc/lib/target/mock/util/command.cpp b/buildcc/lib/target/mock/util/command.cpp deleted file mode 100644 index dabf52f9..00000000 --- a/buildcc/lib/target/mock/util/command.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "internal/util.h" - -#include "CppUTestExt/MockSupport.h" - -namespace buildcc::internal { - -static constexpr const char *const COMMAND_FUNCTION = "command"; - -// command -bool command(const std::string &command) { - (void)command; - return mock().actualCall(COMMAND_FUNCTION).returnBoolValue(); -} - -namespace m { - -void Expect_command(unsigned int calls, bool expectation) { - mock().expectNCalls(calls, COMMAND_FUNCTION).andReturnValue(expectation); -} - -} // namespace m - -} // namespace buildcc::internal diff --git a/buildcc/lib/target/mock/util/execute.cpp b/buildcc/lib/target/mock/util/execute.cpp new file mode 100644 index 00000000..21ded68b --- /dev/null +++ b/buildcc/lib/target/mock/util/execute.cpp @@ -0,0 +1,23 @@ +#include "internal/command.h" + +#include "CppUTestExt/MockSupport.h" + +namespace buildcc::internal { + +static constexpr const char *const EXECUTE_FUNCTION = "execute"; + +// command +bool Command::Execute(const std::string &command) { + (void)command; + return mock().actualCall(EXECUTE_FUNCTION).returnBoolValue(); +} + +namespace m { + +void CommandExpect_Execute(unsigned int calls, bool expectation) { + mock().expectNCalls(calls, EXECUTE_FUNCTION).andReturnValue(expectation); +} + +} // namespace m + +} // namespace buildcc::internal diff --git a/buildcc/lib/target/src/target/build.cpp b/buildcc/lib/target/src/target/build.cpp index 8a18fc5d..522f2d4a 100644 --- a/buildcc/lib/target/src/target/build.cpp +++ b/buildcc/lib/target/src/target/build.cpp @@ -34,21 +34,31 @@ void Target::Build() { env::log_trace(name_, __FUNCTION__); // TODO, Optimize these - aggregated_preprocessor_flags_ = - internal::aggregate(current_preprocessor_flags_); aggregated_c_compile_flags_ = internal::aggregate(current_c_compile_flags_); aggregated_cpp_compile_flags_ = internal::aggregate(current_cpp_compile_flags_); - aggregated_link_flags_ = internal::aggregate(current_link_flags_); - aggregated_lib_deps_ = - fmt::format("{} {}", internal::aggregate(current_external_lib_deps_), - internal::aggregate(current_lib_deps_)); + command_.AddDefaultArguments({ + {"include_dirs", internal::aggregate_with_prefix(prefix_include_dir_, + current_include_dirs_)}, + {"lib_dirs", + internal::aggregate_with_prefix(prefix_lib_dir_, current_lib_dirs_)}, - aggregated_include_dirs_ = internal::aggregate_with_prefix( - prefix_include_dir_, current_include_dirs_); - aggregated_lib_dirs_ = - internal::aggregate_with_prefix(prefix_lib_dir_, current_lib_dirs_); + // TODO, Segregate this if needed + {"lib_deps", + fmt::format("{} {}", internal::aggregate(current_external_lib_deps_), + internal::aggregate(current_lib_deps_))}, + + {"preprocessor_flags", internal::aggregate(current_preprocessor_flags_)}, + {"link_flags", internal::aggregate(current_link_flags_)}, + + // Toolchain executables here + {"asm_compiler", toolchain_.GetAsmCompiler()}, + {"c_compiler", toolchain_.GetCCompiler()}, + {"cpp_compiler", toolchain_.GetCppCompiler()}, + {"archiver", toolchain_.GetArchiver()}, + {"linker", toolchain_.GetLinker()}, + }); const bool is_loaded = loader_.Load(); // TODO, Add more checks for build files physically present @@ -120,19 +130,11 @@ void Target::LinkTarget() { const std::string output_target = internal::Path::CreateNewPath(GetTargetPath()).GetPathAsString(); - std::string link_command = - fmt::format(Link(), fmt::arg("output", output_target), - fmt::arg("link_flags", aggregated_link_flags_), - fmt::arg("compiled_sources", aggregated_compiled_sources), - fmt::arg("lib_dirs", aggregated_lib_dirs_), - fmt::arg("lib_deps", aggregated_lib_deps_), - // Toolchain executables here - fmt::arg("asm_compiler", toolchain_.GetAsmCompiler()), - fmt::arg("c_compiler", toolchain_.GetCCompiler()), - fmt::arg("cpp_compiler", toolchain_.GetCppCompiler()), - fmt::arg("archiver", toolchain_.GetArchiver()), - fmt::arg("linker", toolchain_.GetLinker())); - bool success = internal::command(link_command); + const bool success = command_.ConstructAndExecute( + Link(), { + {"output", output_target}, + {"compiled_sources", aggregated_compiled_sources}, + }); env::assert_fatal(success, fmt::format("Compilation failed for: {}", name_)); } diff --git a/buildcc/lib/target/src/target/source.cpp b/buildcc/lib/target/src/target/source.cpp index d5a0e3a0..207b5f0e 100644 --- a/buildcc/lib/target/src/target/source.cpp +++ b/buildcc/lib/target/src/target/source.cpp @@ -172,7 +172,8 @@ void Target::RecompileSources() { } void Target::CompileSource(const fs::path ¤t_source) const { - const bool success = internal::command(CompileCommand(current_source)); + const bool success = + internal::Command::Execute(CompileCommand(current_source)); env::assert_fatal(success, fmt::format("Compilation failed for: {}", current_source.string())); } @@ -193,13 +194,13 @@ std::string Target::CompileCommand(const fs::path ¤t_source) const { : type == FileExtType::Cpp ? aggregated_cpp_compile_flags_ : ""; - // Construct the Compile Command - return fmt::format( - CompileCommand(), fmt::arg("compiler", compiler), - fmt::arg("preprocessor_flags", aggregated_preprocessor_flags_), - fmt::arg("compile_flags", aggregated_compile_flags), - fmt::arg("include_dirs", aggregated_include_dirs_), - fmt::arg("output", output), fmt::arg("input", input)); + return command_.Construct(CompileCommand(), + { + {"compiler", compiler}, + {"compile_flags", aggregated_compile_flags}, + {"output", output}, + {"input", input}, + }); } std::string_view Target::CompileCommand() const { diff --git a/buildcc/lib/target/src/util/command.cpp b/buildcc/lib/target/src/util/command.cpp index a26e8096..4a364a6a 100644 --- a/buildcc/lib/target/src/util/command.cpp +++ b/buildcc/lib/target/src/util/command.cpp @@ -14,21 +14,51 @@ * limitations under the License. */ -#include "internal/util.h" +#include "internal/command.h" +#include + +#include "fmt/format.h" #include "logging.h" -#include "process.hpp" +namespace buildcc::internal { -namespace tpl = TinyProcessLib; +void Command::AddDefaultArguments( + const std::unordered_map &arguments) { + default_values_.insert(arguments.begin(), arguments.end()); +} -namespace buildcc::internal { +std::string Command::Construct( + std::string_view format, + const std::unordered_map &arguments) const { + // Construct your arguments + fmt::dynamic_format_arg_store store; + std::string constructed_string; + try { -bool command(const std::string &command) { - buildcc::env::log_debug("system", command); + std::for_each(default_values_.cbegin(), default_values_.cend(), + [&store](const std::pair &p) { + store.push_back(fmt::arg(p.first, p.second)); + }); + + std::for_each(arguments.cbegin(), arguments.cend(), + [&store](const std::pair &p) { + store.push_back(fmt::arg(p.first, p.second)); + }); + + // Construct your command + constructed_string = fmt::vformat(format, store); + } catch (const std::exception &e) { + env::assert_fatal(false, e.what()); + } + return constructed_string; +} - tpl::Process process(command); - return process.get_exit_status() == 0; +bool Command::ConstructAndExecute( + std::string_view format, + const std::unordered_map &arguments) const { + const std::string constructed_command = Construct(format, arguments); + return Execute(constructed_command); } } // namespace buildcc::internal diff --git a/buildcc/lib/target/src/util/execute.cpp b/buildcc/lib/target/src/util/execute.cpp new file mode 100644 index 00000000..7983b39e --- /dev/null +++ b/buildcc/lib/target/src/util/execute.cpp @@ -0,0 +1,34 @@ +/* + * Copyright 2021 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "internal/command.h" + +#include "logging.h" + +#include "process.hpp" + +namespace tpl = TinyProcessLib; + +namespace buildcc::internal { + +bool Command::Execute(const std::string &command) { + // Run the process + buildcc::env::log_debug("system", command); + tpl::Process process(command); + return process.get_exit_status() == 0; +} + +} // namespace buildcc::internal diff --git a/buildcc/lib/target/test/target/test_target_c_compile_flags.cpp b/buildcc/lib/target/test/target/test_target_c_compile_flags.cpp index 7e900674..02071eba 100644 --- a/buildcc/lib/target/test/target/test_target_c_compile_flags.cpp +++ b/buildcc/lib/target/test/target/test_target_c_compile_flags.cpp @@ -49,8 +49,8 @@ TEST(TargetTestCCompileFlagsGroup, Target_AddCompileFlag) { simple.AddSource(DUMMY_MAIN); simple.AddCCompileFlag("-std=c11"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); mock().checkExpectations(); @@ -79,8 +79,8 @@ TEST(TargetTestCCompileFlagsGroup, Target_ChangedCompileFlag) { simple.AddSource(DUMMY_MAIN); simple.AddCCompileFlag("-std=c11"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } { @@ -89,8 +89,8 @@ TEST(TargetTestCCompileFlagsGroup, Target_ChangedCompileFlag) { gcc, "data"); simple.AddSource(DUMMY_MAIN); buildcc::base::m::TargetExpect_FlagChanged(1, &simple); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } @@ -101,8 +101,8 @@ TEST(TargetTestCCompileFlagsGroup, Target_ChangedCompileFlag) { simple.AddSource(DUMMY_MAIN); simple.AddCCompileFlag("-std=c11"); buildcc::base::m::TargetExpect_FlagChanged(1, &simple); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } diff --git a/buildcc/lib/target/test/target/test_target_cpp_compile_flags.cpp b/buildcc/lib/target/test/target/test_target_cpp_compile_flags.cpp index 2528a10e..7afec236 100644 --- a/buildcc/lib/target/test/target/test_target_cpp_compile_flags.cpp +++ b/buildcc/lib/target/test/target/test_target_cpp_compile_flags.cpp @@ -49,8 +49,8 @@ TEST(TargetTestCppCompileFlagsGroup, Target_AddCompileFlag) { simple.AddSource(DUMMY_MAIN); simple.AddCppCompileFlag("-std=c++17"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); mock().checkExpectations(); @@ -79,8 +79,8 @@ TEST(TargetTestCppCompileFlagsGroup, Target_ChangedCompileFlag) { simple.AddSource(DUMMY_MAIN); simple.AddCCompileFlag("-std=c++17"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } { @@ -89,8 +89,8 @@ TEST(TargetTestCppCompileFlagsGroup, Target_ChangedCompileFlag) { gcc, "data"); simple.AddSource(DUMMY_MAIN); buildcc::base::m::TargetExpect_FlagChanged(1, &simple); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } @@ -101,8 +101,8 @@ TEST(TargetTestCppCompileFlagsGroup, Target_ChangedCompileFlag) { simple.AddSource(DUMMY_MAIN); simple.AddCCompileFlag("-std=c++17"); buildcc::base::m::TargetExpect_FlagChanged(1, &simple); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } diff --git a/buildcc/lib/target/test/target/test_target_external_lib.cpp b/buildcc/lib/target/test/target/test_target_external_lib.cpp index 6cd7e774..6e88deca 100644 --- a/buildcc/lib/target/test/target/test_target_external_lib.cpp +++ b/buildcc/lib/target/test/target/test_target_external_lib.cpp @@ -45,8 +45,8 @@ TEST(TargetTestExternalLib, TestAddLibDir) { exe.AddSource("foo_main.cpp"); exe.AddLibDir(exe.GetTargetPath().parent_path()); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); exe.Build(); mock().checkExpectations(); @@ -71,8 +71,8 @@ TEST(TargetTestExternalLib, TestAddExternalLibDep_Simple) { exe.AddLibDir(exe.GetTargetPath().parent_path()); exe.AddLibDep("-lfoo"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); exe.Build(); mock().checkExpectations(); @@ -98,8 +98,8 @@ TEST(TargetTestExternalLib, TestAddExternalLibDep_RebuildChanged) { exe.AddSource("foo_main.cpp"); exe.AddLibDir(exe.GetTargetPath().parent_path()); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); exe.Build(); } @@ -112,7 +112,7 @@ TEST(TargetTestExternalLib, TestAddExternalLibDep_RebuildChanged) { exe.AddLibDep("-lfoo"); buildcc::base::m::TargetExpect_ExternalLibChanged(1, &exe); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); exe.Build(); } @@ -124,7 +124,7 @@ TEST(TargetTestExternalLib, TestAddExternalLibDep_RebuildChanged) { exe.AddLibDir(exe.GetTargetPath().parent_path()); buildcc::base::m::TargetExpect_ExternalLibChanged(1, &exe); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); exe.Build(); } diff --git a/buildcc/lib/target/test/target/test_target_include_dir.cpp b/buildcc/lib/target/test/target/test_target_include_dir.cpp index d25c7126..bbc5ab05 100644 --- a/buildcc/lib/target/test/target/test_target_include_dir.cpp +++ b/buildcc/lib/target/test/target/test_target_include_dir.cpp @@ -108,8 +108,8 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { // Duplicate include directory include_compile.AddIncludeDir(RELATIVE_INCLUDE_DIR); - buildcc::internal::m::Expect_command(2, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(2, true); + buildcc::internal::m::CommandExpect_Execute(1, true); include_compile.Build(); buildcc::internal::FbsLoader loader(NAME, intermediate_path); @@ -139,8 +139,8 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { include_compile.AddIncludeDir(""); buildcc::base::m::TargetExpect_DirChanged(1, &include_compile); - buildcc::internal::m::Expect_command(2, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(2, true); + buildcc::internal::m::CommandExpect_Execute(1, true); include_compile.Build(); buildcc::internal::FbsLoader loader(NAME, intermediate_path); @@ -167,8 +167,8 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { include_compile.AddIncludeDir(RELATIVE_INCLUDE_DIR); buildcc::base::m::TargetExpect_DirChanged(1, &include_compile); - buildcc::internal::m::Expect_command(2, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(2, true); + buildcc::internal::m::CommandExpect_Execute(1, true); include_compile.Build(); buildcc::internal::FbsLoader loader(NAME, intermediate_path); @@ -219,8 +219,8 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { add_header.AddSource(INCLUDE_HEADER_SOURCE); add_header.AddIncludeDir(RELATIVE_INCLUDE_DIR); - buildcc::internal::m::Expect_command(2, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(2, true); + buildcc::internal::m::CommandExpect_Execute(1, true); add_header.Build(); buildcc::internal::FbsLoader loader(NAME, intermediate_path); @@ -241,8 +241,8 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { add_header.AddIncludeDir(RELATIVE_INCLUDE_DIR); buildcc::base::m::TargetExpect_PathAdded(1, &add_header); - buildcc::internal::m::Expect_command(2, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(2, true); + buildcc::internal::m::CommandExpect_Execute(1, true); add_header.Build(); buildcc::internal::FbsLoader loader(NAME, intermediate_path); @@ -269,8 +269,8 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { add_header.AddIncludeDir(RELATIVE_INCLUDE_DIR); buildcc::base::m::TargetExpect_PathUpdated(1, &add_header); - buildcc::internal::m::Expect_command(2, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(2, true); + buildcc::internal::m::CommandExpect_Execute(1, true); add_header.Build(); buildcc::internal::FbsLoader loader(NAME, intermediate_path); @@ -290,8 +290,8 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { add_header.AddIncludeDir(RELATIVE_INCLUDE_DIR); buildcc::base::m::TargetExpect_PathRemoved(1, &add_header); - buildcc::internal::m::Expect_command(2, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(2, true); + buildcc::internal::m::CommandExpect_Execute(1, true); add_header.Build(); buildcc::internal::FbsLoader loader(NAME, intermediate_path); diff --git a/buildcc/lib/target/test/target/test_target_lib_dep.cpp b/buildcc/lib/target/test/target/test_target_lib_dep.cpp index d43e3a0b..897222a6 100644 --- a/buildcc/lib/target/test/target/test_target_lib_dep.cpp +++ b/buildcc/lib/target/test/target/test_target_lib_dep.cpp @@ -46,8 +46,8 @@ TEST(TargetTestLibDep, StaticLibrary_SimpleBuildTest) { foolib.AddSource("foo.cpp", "foo"); foolib.AddIncludeDir("foo"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); foolib.Build(); mock().checkExpectations(); @@ -75,8 +75,8 @@ TEST(TargetTestLibDep, TargetDep_RebuildTest) { foolib.AddSource("foo/foo.cpp"); foolib.AddIncludeDir("foo"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); foolib.Build(); flatbuffers::SaveFile(foolib.GetTargetPath().string().c_str(), std::string{""}, false); @@ -88,8 +88,8 @@ TEST(TargetTestLibDep, TargetDep_RebuildTest) { exe_target.AddIncludeDir("foo"); exe_target.AddLibDep(foolib); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); exe_target.Build(); } @@ -124,8 +124,8 @@ TEST(TargetTestLibDep, TargetDep_AddRemoveTest) { foolib.AddSource("foo/foo.cpp"); foolib.AddIncludeDir("foo"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); foolib.Build(); flatbuffers::SaveFile(foolib.GetTargetPath().string().c_str(), @@ -139,8 +139,8 @@ TEST(TargetTestLibDep, TargetDep_AddRemoveTest) { exe_target.AddSource("empty_main.cpp"); exe_target.AddIncludeDir("foo"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); exe_target.Build(); } @@ -154,7 +154,7 @@ TEST(TargetTestLibDep, TargetDep_AddRemoveTest) { exe_target.AddLibDep(foolib); buildcc::base::m::TargetExpect_PathAdded(1, &exe_target); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); exe_target.Build(); } @@ -166,7 +166,7 @@ TEST(TargetTestLibDep, TargetDep_AddRemoveTest) { exe_target.AddIncludeDir("foo"); buildcc::base::m::TargetExpect_PathRemoved(1, &exe_target); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); exe_target.Build(); } @@ -187,8 +187,8 @@ TEST(TargetTestLibDep, TargetDep_UpdateExistingLibraryTest) { foolib.AddSource("foo/foo.cpp"); foolib.AddIncludeDir("foo"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); foolib.Build(); bool saved = flatbuffers::SaveFile(foolib.GetTargetPath().string().c_str(), @@ -201,8 +201,8 @@ TEST(TargetTestLibDep, TargetDep_UpdateExistingLibraryTest) { exe_target.AddIncludeDir("foo"); exe_target.AddLibDep(foolib); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); exe_target.Build(); } @@ -215,8 +215,8 @@ TEST(TargetTestLibDep, TargetDep_UpdateExistingLibraryTest) { foolib.AddIncludeDir(""); buildcc::base::m::TargetExpect_DirChanged(1, &foolib); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); foolib.Build(); // * To make sure that SaveFile is newer @@ -232,7 +232,7 @@ TEST(TargetTestLibDep, TargetDep_UpdateExistingLibraryTest) { exe_target.AddLibDep(foolib); buildcc::base::m::TargetExpect_PathUpdated(1, &exe_target); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); exe_target.Build(); } diff --git a/buildcc/lib/target/test/target/test_target_link_flags.cpp b/buildcc/lib/target/test/target/test_target_link_flags.cpp index 430a901b..45670915 100644 --- a/buildcc/lib/target/test/target/test_target_link_flags.cpp +++ b/buildcc/lib/target/test/target/test_target_link_flags.cpp @@ -49,8 +49,8 @@ TEST(TargetTestLinkFlagsGroup, Target_AddLinkFlag) { simple.AddSource(DUMMY_MAIN); simple.AddLinkFlag("-lm"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); mock().checkExpectations(); @@ -79,8 +79,8 @@ TEST(TargetTestLinkFlagsGroup, Target_ChangedLinkFlag) { simple.AddSource(DUMMY_MAIN); simple.AddLinkFlag("-lm"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } { @@ -89,7 +89,7 @@ TEST(TargetTestLinkFlagsGroup, Target_ChangedLinkFlag) { gcc, "data"); simple.AddSource(DUMMY_MAIN); buildcc::base::m::TargetExpect_FlagChanged(1, &simple); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } @@ -100,7 +100,7 @@ TEST(TargetTestLinkFlagsGroup, Target_ChangedLinkFlag) { simple.AddSource(DUMMY_MAIN); simple.AddLinkFlag("-lm"); buildcc::base::m::TargetExpect_FlagChanged(1, &simple); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } diff --git a/buildcc/lib/target/test/target/test_target_preprocessor_flags.cpp b/buildcc/lib/target/test/target/test_target_preprocessor_flags.cpp index fafb7689..79792611 100644 --- a/buildcc/lib/target/test/target/test_target_preprocessor_flags.cpp +++ b/buildcc/lib/target/test/target/test_target_preprocessor_flags.cpp @@ -49,8 +49,8 @@ TEST(TargetTestPreprocessorFlagGroup, Target_AddPreprocessorFlag) { simple.AddSource(DUMMY_MAIN); simple.AddPreprocessorFlag("-DCOMPILE=1"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); mock().checkExpectations(); @@ -79,8 +79,8 @@ TEST(TargetTestPreprocessorFlagGroup, Target_ChangedPreprocessorFlag) { simple.AddSource(DUMMY_MAIN); simple.AddPreprocessorFlag("-DCOMPILE=1"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } { @@ -89,8 +89,8 @@ TEST(TargetTestPreprocessorFlagGroup, Target_ChangedPreprocessorFlag) { gcc, "data"); simple.AddSource(DUMMY_MAIN); buildcc::base::m::TargetExpect_FlagChanged(1, &simple); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } @@ -101,8 +101,8 @@ TEST(TargetTestPreprocessorFlagGroup, Target_ChangedPreprocessorFlag) { simple.AddSource(DUMMY_MAIN); simple.AddPreprocessorFlag("-DRANDOM=1"); buildcc::base::m::TargetExpect_FlagChanged(1, &simple); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } diff --git a/buildcc/lib/target/test/target/test_target_source.cpp b/buildcc/lib/target/test/target/test_target_source.cpp index 8c0e74ff..0483bfd8 100644 --- a/buildcc/lib/target/test/target/test_target_source.cpp +++ b/buildcc/lib/target/test/target/test_target_source.cpp @@ -98,8 +98,8 @@ TEST(TargetTestSourceGroup, Target_Build_SourceCompile) { buildcc::base::Target simple(NAME, buildcc::base::TargetType::Executable, gcc, "data"); - buildcc::internal::m::Expect_command(1, true); // compile - buildcc::internal::m::Expect_command(1, true); // link + buildcc::internal::m::CommandExpect_Execute(1, true); // compile + buildcc::internal::m::CommandExpect_Execute(1, true); // link simple.AddSource(DUMMY_MAIN); simple.Build(); @@ -132,7 +132,7 @@ TEST(TargetTestSourceGroup, Target_Build_SourceCompileError) { gcc, "data"); simple.AddSource(DUMMY_MAIN); - buildcc::internal::m::Expect_command(1, false); // compile + buildcc::internal::m::CommandExpect_Execute(1, false); // compile CHECK_THROWS(std::exception, simple.Build()); } @@ -142,8 +142,8 @@ TEST(TargetTestSourceGroup, Target_Build_SourceCompileError) { gcc, "data"); simple.AddSource(DUMMY_MAIN); - buildcc::internal::m::Expect_command(1, true); // compile - buildcc::internal::m::Expect_command(1, false); // compile + buildcc::internal::m::CommandExpect_Execute(1, true); // compile + buildcc::internal::m::CommandExpect_Execute(1, false); // compile CHECK_THROWS(std::exception, simple.Build()); } @@ -176,9 +176,9 @@ TEST(TargetTestSourceGroup, Target_Build_SourceRecompile) { simple.AddSource(DUMMY_MAIN_C); simple.AddSource(NEW_SOURCE); - buildcc::internal::m::Expect_command(1, true); // compile - buildcc::internal::m::Expect_command(1, true); // compile - buildcc::internal::m::Expect_command(1, true); // link + buildcc::internal::m::CommandExpect_Execute(1, true); // compile + buildcc::internal::m::CommandExpect_Execute(1, true); // compile + buildcc::internal::m::CommandExpect_Execute(1, true); // link simple.Build(); buildcc::internal::FbsLoader loader(NAME, intermediate_path); @@ -202,11 +202,11 @@ TEST(TargetTestSourceGroup, Target_Build_SourceRecompile) { buildcc::base::m::TargetExpect_SourceRemoved(1, &simple); // Added and compiled - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); buildcc::base::m::TargetExpect_SourceAdded(1, &simple); // Rebuild target - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); // Run the second Build to test Recompile simple.Build(); @@ -232,10 +232,10 @@ TEST(TargetTestSourceGroup, Target_Build_SourceRecompile) { simple.AddSource(NEW_SOURCE); // Run the second Build to test Recompile - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); buildcc::base::m::TargetExpect_SourceUpdated(1, &simple); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); buildcc::internal::FbsLoader loader(NAME, intermediate_path); diff --git a/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp b/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp index 4b69a39b..95420eae 100644 --- a/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp +++ b/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp @@ -41,8 +41,8 @@ TEST(TargetTestSourceOutOfRootGroup, Add_OutOfRootSource) { gcc, ""); simple.AddSource("../dummy_main.cpp"); - buildcc::internal::m::Expect_command(1, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); } @@ -61,8 +61,8 @@ TEST(TargetTestSourceOutOfRootGroup, Glob_OutOfRootSource) { CHECK_EQUAL(12, simple.GetCurrentSourceFiles().size()); - buildcc::internal::m::Expect_command(12, true); - buildcc::internal::m::Expect_command(1, true); + buildcc::internal::m::CommandExpect_Execute(12, true); + buildcc::internal::m::CommandExpect_Execute(1, true); simple.Build(); mock().checkExpectations(); diff --git a/buildcc/targets/target_gcc.h b/buildcc/targets/target_gcc.h index 543f632b..5f3a96a9 100644 --- a/buildcc/targets/target_gcc.h +++ b/buildcc/targets/target_gcc.h @@ -38,7 +38,7 @@ class StaticTarget_gcc : public base::Target { target_path_relative_to_root) {} private: - virtual std::string_view Link() const { + std::string_view Link() const override { return "{archiver} rcs {output} {compiled_sources}"; } }; @@ -51,11 +51,11 @@ class DynamicTarget_gcc : public base::Target { target_path_relative_to_root) {} private: - virtual std::string_view CompileCommand() const { + std::string_view CompileCommand() const override { return "{compiler} {preprocessor_flags} {include_dirs} {compile_flags} " "-fpic -o {output} -c {input}"; } - virtual std::string_view Link() const { + std::string_view Link() const override { return "{cpp_compiler} -shared {link_flags} {compiled_sources} -o {output}"; } }; diff --git a/buildcc/targets/target_msvc.h b/buildcc/targets/target_msvc.h index eef667b2..a2226419 100644 --- a/buildcc/targets/target_msvc.h +++ b/buildcc/targets/target_msvc.h @@ -40,10 +40,10 @@ class ExecutableTarget_msvc : public base::Target { } private: - virtual std::string_view CompileCommand() const { + std::string_view CompileCommand() const override { return kMsvcCompileCommand; } - virtual std::string_view Link() const { + std::string_view Link() const override { return "{linker} {link_flags} {lib_dirs} /OUT:{output} {lib_deps} " "{compiled_sources}"; } @@ -60,10 +60,10 @@ class StaticTarget_msvc : public base::Target { } private: - virtual std::string_view CompileCommand() const { + std::string_view CompileCommand() const override { return kMsvcCompileCommand; } - virtual std::string_view Link() const { + std::string_view Link() const override { return "{archiver} {link_flags} /OUT:{output} {compiled_sources}"; } }; @@ -79,10 +79,10 @@ class DynamicTarget_msvc : public base::Target { } private: - virtual std::string_view CompileCommand() const { + std::string_view CompileCommand() const override { return kMsvcCompileCommand; } - virtual std::string_view Link() const { + std::string_view Link() const override { return "{linker} /DLL {link_flags} /OUT:{output}.dll /IMPLIB:{output} " "{compiled_sources}"; } diff --git a/doc/custom_target/commands.md b/doc/custom_target/commands.md new file mode 100644 index 00000000..8ad16140 --- /dev/null +++ b/doc/custom_target/commands.md @@ -0,0 +1,52 @@ +# Target commands for Compile and Link + +When constructing custom commands we need to supply our own pattern to the buildsystem + +This is done by overriding the 2 `virtual base::Target` functions + +**IMPORTANT: Make sure they are string literals** +```cpp +std::string_view CompileCommand() const override { + return "{compiler} {preprocessor_flags} {include_dirs} {compile_flags} -o {output} -c {input}"; +} + +std::string_view Link() const override { + return "{cpp_compiler} {link_flags} {compiled_sources} -o {output} {lib_dirs} {lib_deps}"; +} +``` + +- See [GCC specific overrides](../../buildcc/targets/target_gcc.h) +- See [MSVC specific overrides](../../buildcc/targets/target_msvc.h) + +# General + +The following `{}` commands are available to both `CompileCommand` and `Link` functions + +See [build.cpp Target::Build API](../../buildcc/lib/target/src/target/build.cpp) + +- `include_dirs`: Aggregated include directories for header files +- `lib_dirs`: Aggregated lib directories for external libraries +- `lib_deps`: External libraries and full path libraries +- `preprocessor_flags`: Preprocessor definitions +- `link_flags`: Flags supplied during linking +- `asm_compiler`: Assembly compiler +- `c_compiler`: C compiler +- `cpp_compiler`: C++ compiler +- `archiver`: Archiver for Static Libraries +- `linker`: Linker usually used during the Linking phase / Library creation + +# Compile Specific + +See [source.cpp Target::CompileCommand API](../../buildcc/lib/target/src/target/source.cpp) + +- `compiler`: Automatically chosen amongst ASM, C and C++ toolchain compiler +- `compile_flags`: Automatically chosen amongst `{c/cpp}_flags` +- `output`: Object file +- `input`: Input source file + +# Links Specific + +See [build.cpp Target::Target API](../../buildcc/lib/target/src/target/build.cpp) + +- `output`: Generated target as `Target::GetName()` +- `compiled_sources`: Aggregated object files