From 3f77058f8f9bb5a94020b622434d351ede3ad0f6 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 13 Oct 2021 00:22:54 -0700 Subject: [PATCH 01/16] Updated target.fbs for pch - Updated target_loader.cpp - Updated target_storer.cpp --- buildcc/lib/target/include/target/target_loader.h | 2 ++ buildcc/lib/target/src/target/target_loader.cpp | 1 + buildcc/lib/target/src/target/target_storer.cpp | 4 +++- buildcc/schema/target.fbs | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/buildcc/lib/target/include/target/target_loader.h b/buildcc/lib/target/include/target/target_loader.h index 968efbc2..ec56379b 100644 --- a/buildcc/lib/target/include/target/target_loader.h +++ b/buildcc/lib/target/include/target/target_loader.h @@ -47,6 +47,7 @@ class TargetLoader : public LoaderInterface { const path_unordered_set &GetLoadedSources() const { return loaded_sources_; } const path_unordered_set &GetLoadedHeaders() const { return loaded_headers_; } + const path_unordered_set &GetLoadedPchs() const { return loaded_pchs_; } const path_unordered_set &GetLoadedLibDeps() const { return loaded_lib_deps_; } @@ -93,6 +94,7 @@ class TargetLoader : public LoaderInterface { path_unordered_set loaded_sources_; path_unordered_set loaded_headers_; + path_unordered_set loaded_pchs_; path_unordered_set loaded_lib_deps_; std::unordered_set loaded_external_lib_dirs_; diff --git a/buildcc/lib/target/src/target/target_loader.cpp b/buildcc/lib/target/src/target/target_loader.cpp index 9fc53758..c8a0a105 100644 --- a/buildcc/lib/target/src/target/target_loader.cpp +++ b/buildcc/lib/target/src/target/target_loader.cpp @@ -49,6 +49,7 @@ bool TargetLoader::Load() { ExtractPath(target->source_files(), loaded_sources_); ExtractPath(target->header_files(), loaded_headers_); + ExtractPath(target->pch_files(), loaded_pchs_); ExtractPath(target->lib_deps(), loaded_lib_deps_); Extract(target->external_lib_deps(), loaded_external_lib_dirs_); diff --git a/buildcc/lib/target/src/target/target_storer.cpp b/buildcc/lib/target/src/target/target_storer.cpp index 1f4a8091..c8c18559 100644 --- a/buildcc/lib/target/src/target/target_storer.cpp +++ b/buildcc/lib/target/src/target/target_storer.cpp @@ -48,6 +48,8 @@ bool Target::Store() { internal::CreateFbsVectorPath(builder, current_source_files_.internal); auto fbs_header_files = internal::CreateFbsVectorPath(builder, current_header_files_.internal); + auto fbs_pch_files = + internal::CreateFbsVectorPath(builder, current_pch_files_.internal); auto fbs_lib_deps = internal::CreateFbsVectorPath(builder, current_lib_deps_.internal); @@ -79,7 +81,7 @@ bool Target::Store() { auto fbs_target = fbs::CreateTargetDirect( builder, name_.c_str(), fbs_target_type, &fbs_source_files, - &fbs_header_files, &fbs_lib_deps, &fbs_external_lib_deps, + &fbs_header_files, &fbs_pch_files, &fbs_lib_deps, &fbs_external_lib_deps, &fbs_include_dirs, &fbs_lib_dirs, &fbs_preprocessor_flags, &fbs_common_compile_flags, &fbs_asm_compile_flags, &fbs_c_compile_flags, &fbs_cpp_compile_flags, &fbs_link_flags, &fbs_compile_dependencies, diff --git a/buildcc/schema/target.fbs b/buildcc/schema/target.fbs index 98ec9393..77b78d91 100644 --- a/buildcc/schema/target.fbs +++ b/buildcc/schema/target.fbs @@ -30,6 +30,7 @@ table Target { // Files source_files:[Path]; header_files:[Path]; + pch_files:[Path]; lib_deps:[Path]; // Links From 4d4fea2a2e29120f3eda3684dd2dfe246bcdcae5 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 13 Oct 2021 00:28:45 -0700 Subject: [PATCH 02/16] Added pch.cpp and compile_pch.cpp --- buildcc/lib/target/cmake/mock_target.cmake | 3 +- buildcc/lib/target/cmake/target.cmake | 2 + buildcc/lib/target/src/target/compile_pch.cpp | 94 +++++++++++++++++++ buildcc/lib/target/src/target/pch.cpp | 43 +++++++++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 buildcc/lib/target/src/target/compile_pch.cpp create mode 100644 buildcc/lib/target/src/target/pch.cpp diff --git a/buildcc/lib/target/cmake/mock_target.cmake b/buildcc/lib/target/cmake/mock_target.cmake index 1e7faa26..53780c5d 100644 --- a/buildcc/lib/target/cmake/mock_target.cmake +++ b/buildcc/lib/target/cmake/mock_target.cmake @@ -13,7 +13,6 @@ add_library(mock_target STATIC # Target friend src/target/friend/file_extension.cpp - include/target/friend/file_extension.h # Target src/target/target.cpp @@ -22,10 +21,12 @@ add_library(mock_target STATIC src/target/source.cpp src/target/include_dir.cpp + src/target/pch.cpp src/target/lib.cpp src/target/flags.cpp src/target/additional_deps.cpp + src/target/compile_pch.cpp src/target/compile_source.cpp src/target/link_target.cpp src/target/build.cpp diff --git a/buildcc/lib/target/cmake/target.cmake b/buildcc/lib/target/cmake/target.cmake index 188924ae..b27dac2e 100644 --- a/buildcc/lib/target/cmake/target.cmake +++ b/buildcc/lib/target/cmake/target.cmake @@ -30,12 +30,14 @@ set(TARGET_SRCS src/target/source.cpp src/target/include_dir.cpp + src/target/pch.cpp src/target/lib.cpp src/target/flags.cpp src/target/additional_deps.cpp src/target/recheck_states.cpp + src/target/compile_pch.cpp src/target/compile_source.cpp src/target/link_target.cpp src/target/build.cpp diff --git a/buildcc/lib/target/src/target/compile_pch.cpp b/buildcc/lib/target/src/target/compile_pch.cpp new file mode 100644 index 00000000..849deb46 --- /dev/null +++ b/buildcc/lib/target/src/target/compile_pch.cpp @@ -0,0 +1,94 @@ +/* + * 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 "target/target.h" + +#include "env/assert_fatal.h" +#include "env/util.h" + +namespace { + +constexpr const char *const kFormat = R"(// Generated by BuildCC +#pragma once + +// clang-format off +{aggregated_includes} +)"; + +void AggregateToFile(const fs::path &filename, + const buildcc::internal::fs_unordered_set &header_files) { + std::string aggregated_includes; + for (const auto &hf : header_files) { + std::string temp = fmt::format("#include \"{}\"\r\n", hf.string()); + aggregated_includes.append(temp); + } + + buildcc::Command command; + std::string constructed_output = command.Construct( + kFormat, { + {"aggregated_includes", aggregated_includes}, + }); + bool success = buildcc::env::SaveFile(filename.string().c_str(), + constructed_output, false); + buildcc::env::assert_fatal(success, "Could not save pch file"); +} + +} // namespace + +namespace buildcc::base { + +std::string Target::ConstructPchCompileCommand() const { + const std::string compiler = GetState().contains_cpp_src + ? GetToolchain().GetCppCompiler() + : GetToolchain().GetCCompiler(); + const FileExt::Type file_ext_type = + GetState().contains_cpp_src ? FileExt::Type::Cpp : FileExt::Type::C; + const std::string compile_flags = + ext_.GetCompileFlags(file_ext_type).value_or(""); + return command_.Construct( + config_.pch_command, + { + {"compiler", compiler}, + {"pch_flags", ""}, // TODO, Add PCH specific flags + {"compile_flags", compile_flags}, + {"output", GetPchCompilePath().string()}, + {"input", GetPchHeaderPath().string()}, + }); +} + +void Target::PrePchCompile() { + for (const auto &user_pf : current_pch_files_.user) { + current_pch_files_.internal.emplace( + buildcc::internal::Path::CreateExistingPath(user_pf)); + } +} + +void Target::BuildPch() { + PrePchCompile(); + if (!loader_.IsLoaded()) { + dirty_ = true; + } else { + RecheckPaths(loader_.GetLoadedPchs(), current_pch_files_.internal); + } + + if (dirty_) { + AggregateToFile(GetPchHeaderPath(), current_pch_files_.user); + bool success = Command::Execute(pch_file_.command); + env::assert_fatal(success, "Failed to compile pch"); + } +} + +} // namespace buildcc::base diff --git a/buildcc/lib/target/src/target/pch.cpp b/buildcc/lib/target/src/target/pch.cpp new file mode 100644 index 00000000..64776c43 --- /dev/null +++ b/buildcc/lib/target/src/target/pch.cpp @@ -0,0 +1,43 @@ +/* + * 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 "target/target.h" + +namespace buildcc::base { + +void Target::AddPchAbsolute(const fs::path &absolute_filepath) { + LockedAfterBuild(); + const auto file_ext_type = ext_.GetType(absolute_filepath); + env::assert_fatal(FileExt::IsValidHeader(file_ext_type), + fmt::format("{} does not have a valid header extension", + absolute_filepath.string())); + + const fs::path absolute_pch = fs::path(absolute_filepath).make_preferred(); + current_pch_files_.user.insert(absolute_pch); +} + +void Target::AddPch(const fs::path &relative_filename, + const fs::path &relative_to_target_path) { + env::log_trace(name_, __FUNCTION__); + + // Compute the absolute source path + fs::path absolute_pch = + target_root_source_dir_ / relative_to_target_path / relative_filename; + + AddPchAbsolute(absolute_pch); +} + +} // namespace buildcc::base From 396bcc0581879015aef2ae25ba9c1731bffae708 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 13 Oct 2021 00:29:41 -0700 Subject: [PATCH 03/16] Updated tasks.cpp --- buildcc/lib/target/mock/target/tasks.cpp | 2 ++ buildcc/lib/target/src/target/tasks.cpp | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/buildcc/lib/target/mock/target/tasks.cpp b/buildcc/lib/target/mock/target/tasks.cpp index c35557bd..e01ae4b5 100644 --- a/buildcc/lib/target/mock/target/tasks.cpp +++ b/buildcc/lib/target/mock/target/tasks.cpp @@ -2,6 +2,8 @@ namespace buildcc::base { +void Target::PchTask() { BuildPch(); } + void Target::CompileTask() { std::vector source_files; std::vector dummy_source_files; diff --git a/buildcc/lib/target/src/target/tasks.cpp b/buildcc/lib/target/src/target/tasks.cpp index 956596e0..f20eedc9 100644 --- a/buildcc/lib/target/src/target/tasks.cpp +++ b/buildcc/lib/target/src/target/tasks.cpp @@ -27,6 +27,7 @@ namespace { +constexpr const char *const kPchTaskName = "Pch"; constexpr const char *const kCompileTaskName = "Objects"; constexpr const char *const kLinkTaskName = "Target"; @@ -34,6 +35,13 @@ constexpr const char *const kLinkTaskName = "Target"; namespace buildcc::base { +void Target::PchTask() { + env::log_trace(name_, __FUNCTION__); + + pch_task_ = tf_.emplace([&]() { BuildPch(); }); + pch_task_.name(kPchTaskName); +} + void Target::CompileTask() { env::log_trace(name_, __FUNCTION__); @@ -70,8 +78,13 @@ void Target::LinkTask() { env::log_trace(name_, __FUNCTION__); link_task_ = tf_.emplace([&]() { BuildLink(); }); - link_task_.name(kLinkTaskName); + + // Only add if not empty + // PCH may not be used + if (!pch_task_.empty()) { + compile_task_.succeed(pch_task_); + } link_task_.succeed(compile_task_); } From 76642d6a2f436bd69f2e73bac3979183b7a5cfb1 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 13 Oct 2021 00:31:24 -0700 Subject: [PATCH 04/16] Update target.h --- buildcc/lib/target/include/target/target.h | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index 4714316f..593d1068 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -61,10 +61,15 @@ class Target : public BuilderInterface { std::string target_ext{""}; std::string obj_ext{".o"}; + std::string pch_header_ext{".hpp"}; + std::string pch_compile_ext{".gch"}; std::string prefix_include_dir{"-I"}; std::string prefix_lib_dir{"-L"}; + std::string pch_command{"{compiler} {preprocessor_flags} {include_dirs} " + "{common_compile_flags} {pch_flags} " + "{compile_flags} -o {output} -c {input}"}; std::string compile_command{ "{compiler} {preprocessor_flags} {include_dirs} {common_compile_flags} " "{compile_flags} -o {output} -c {input}"}; @@ -129,6 +134,11 @@ class Target : public BuilderInterface { void GlobHeaders(const fs::path &relative_to_target_path); void GlobHeadersAbsolute(const fs::path &absolute_path); + // PCH + void AddPch(const fs::path &relative_filename, + const fs::path &relative_to_target_path = ""); + void AddPchAbsolute(const fs::path &absolute_filepath); + // * Include and Lib directory void AddIncludeDir(const fs::path &relative_include_dir, bool glob_headers = false); @@ -177,6 +187,17 @@ class Target : public BuilderInterface { // we can cache these variables during Target construction fs::path GetTargetPath() const { return ConstructTargetPath(); } + // TODO, Make these construct APIs + fs::path GetPchHeaderPath() const { + return target_intermediate_dir_ / + fmt::format("buildcc_pch{}", config_.pch_header_ext); + } + // Each target only has only 1 PCH file + fs::path GetPchCompilePath() const { + return GetPchHeaderPath().replace_extension( + fmt::format("{}{}", config_.pch_header_ext, config_.pch_compile_ext)); + } + // Const references // TODO, Shift getters to source file as well @@ -273,11 +294,15 @@ class Target : public BuilderInterface { void UnlockedAfterBuild() const; // Build + void BuildPch(); + // TODO, Rename to BuildObject void BuildCompile(std::vector &source_files, std::vector &dummy_source_files); void BuildLink(); // + void PrePchCompile(); + // TODO, Rename to PreObjectCompile void PreCompile(); void PreLink(); @@ -298,6 +323,8 @@ class Target : public BuilderInterface { const std::unordered_set ¤t_external_libs); // Tasks + void PchTask(); + // TODO, Rename to ObjectTask and TargetTask void CompileTask(); void LinkTask(); @@ -319,6 +346,7 @@ class Target : public BuilderInterface { // Construct fs::path ConstructObjectPath(const fs::path &absolute_source_file) const; fs::path ConstructTargetPath() const; + std::string ConstructPchCompileCommand() const; std::string ConstructCompileCommand(const fs::path &absolute_current_source) const; std::string ConstructLinkCommand() const; @@ -344,6 +372,7 @@ class Target : public BuilderInterface { // TODO, Use an internal::Storer class / struct for this to reduce clutter internal::default_files current_source_files_; internal::default_files current_header_files_; + internal::default_files current_pch_files_; internal::default_files current_lib_deps_; internal::fs_unordered_set current_include_dirs_; internal::fs_unordered_set current_lib_dirs_; @@ -360,6 +389,8 @@ class Target : public BuilderInterface { // Not used for serialization // NOTE, Always store the absolute source path -> absolute compiled source // path here + OutputInfo pch_file_; + // TODO, Remove current from these std::unordered_map current_object_files_; OutputInfo current_target_file_; @@ -369,6 +400,7 @@ class Target : public BuilderInterface { FileExt ext_{*this}; tf::Taskflow tf_; + tf::Task pch_task_; tf::Task compile_task_; tf::Task link_task_; }; From 7671aaee42799ba069b4544f4ae0f7ccc45e6585 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 13 Oct 2021 00:34:53 -0700 Subject: [PATCH 05/16] Update build.cpp --- buildcc/lib/target/src/target/build.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/buildcc/lib/target/src/target/build.cpp b/buildcc/lib/target/src/target/build.cpp index 13ba78fe..124250f0 100644 --- a/buildcc/lib/target/src/target/build.cpp +++ b/buildcc/lib/target/src/target/build.cpp @@ -58,19 +58,25 @@ void Target::Build() { {"linker", toolchain_.GetLinker()}, }); + // Load the serialized file + (void)loader_.Load(); + + // PCH Compile + if (!current_pch_files_.user.empty()) { + // TODO, Update .output at Constructor + pch_file_.command = ConstructPchCompileCommand(); + PchTask(); + } + // Compile Command + // Link Command for (auto &object_rel : current_object_files_) { object_rel.second.command = ConstructCompileCommand(object_rel.first); } + CompileTask(); - // Link Command + // TODO, Update .output at Constructor current_target_file_.command = ConstructLinkCommand(); - - // Load the serialized file - (void)loader_.Load(); - - // Register the tasks - CompileTask(); LinkTask(); } From fc3e43aef2b0e887978ddf10f874ce53c61c82ac Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 13 Oct 2021 00:35:14 -0700 Subject: [PATCH 06/16] Update test_base_target.cpp --- buildcc/lib/target/test/target/test_base_target.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/buildcc/lib/target/test/target/test_base_target.cpp b/buildcc/lib/target/test/target/test_base_target.cpp index b261db44..5f9e041b 100644 --- a/buildcc/lib/target/test/target/test_base_target.cpp +++ b/buildcc/lib/target/test/target/test_base_target.cpp @@ -1,5 +1,7 @@ #include "constants.h" +#include "expect_command.h" + #include "target/target.h" #include "env/env.h" @@ -9,10 +11,14 @@ #include "CppUTest/MemoryLeakDetectorNewMacros.h" #include "CppUTest/TestHarness.h" #include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" // clang-format off TEST_GROUP(TargetBaseTestGroup) { + void teardown() { + mock().clear(); + } }; // clang-format on static const buildcc::base::Toolchain gcc(buildcc::base::Toolchain::Id::Gcc, @@ -81,10 +87,13 @@ TEST(TargetBaseTestGroup, TargetConfig_BadLinkCommand) { buildcc::base::Target simple(NAME, buildcc::base::Target::Type::Executable, gcc, "data", config); simple.AddSource("dummy_main.c"); + + buildcc::m::CommandExpect_Execute(1, true); CHECK_THROWS(std::exception, simple.Build()); } buildcc::env::deinit(); + mock().checkExpectations(); } // TODO, Check toolchain change From b17a4901c9d03033ce7bf4903fc6fa76627644f6 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 13 Oct 2021 18:23:23 -0700 Subject: [PATCH 07/16] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d614f6f2..92ed69eb 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ _deps .vscode/ .vs/ .idea/ +.cache/ # Files *.gcov From 81c4d3a5d0f3bf64b0c1a910efe7168c79fa1e4b Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 13 Oct 2021 18:24:08 -0700 Subject: [PATCH 08/16] Update target.h --- buildcc/lib/target/include/target/target.h | 1 - 1 file changed, 1 deletion(-) diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index 593d1068..2ba96102 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -106,7 +106,6 @@ class Target : public BuilderInterface { } virtual ~Target() {} - Target(Target &&target) = default; Target(const Target &target) = delete; // Builders From f691d018eb31cbb1ac61028622ad1bc9b32a7c90 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 13 Oct 2021 18:25:24 -0700 Subject: [PATCH 09/16] Updated target_pch unit test --- buildcc/lib/target/test/target/CMakeLists.txt | 7 + buildcc/lib/target/test/target/constants.h.in | 2 + .../test/target/data/pch/pch_header_1.h | 0 .../test/target/data/pch/pch_header_2.h | 0 .../target/test/target/test_target_pch.cpp | 240 ++++++++++++++++++ 5 files changed, 249 insertions(+) create mode 100644 buildcc/lib/target/test/target/data/pch/pch_header_1.h create mode 100644 buildcc/lib/target/test/target/data/pch/pch_header_2.h create mode 100644 buildcc/lib/target/test/target/test_target_pch.cpp diff --git a/buildcc/lib/target/test/target/CMakeLists.txt b/buildcc/lib/target/test/target/CMakeLists.txt index 0c4e4b9c..5bc7931c 100644 --- a/buildcc/lib/target/test/target/CMakeLists.txt +++ b/buildcc/lib/target/test/target/CMakeLists.txt @@ -45,6 +45,12 @@ add_executable(test_base_target ) target_link_libraries(test_base_target PRIVATE target_interface) +# Test target pch +add_executable(test_target_pch + test_target_pch.cpp +) +target_link_libraries(test_target_pch PRIVATE target_interface) + # Test target sources add_executable(test_target_source test_target_source.cpp @@ -96,6 +102,7 @@ target_link_libraries(test_target_lock PRIVATE target_interface) # Tests add_test(NAME test_base_target COMMAND test_base_target) +add_test(NAME test_target_pch COMMAND test_target_pch) add_test(NAME test_target_source COMMAND test_target_source) add_test(NAME test_target_source_out_of_root COMMAND test_target_source_out_of_root) add_test(NAME test_target_include_dir COMMAND test_target_include_dir) diff --git a/buildcc/lib/target/test/target/constants.h.in b/buildcc/lib/target/test/target/constants.h.in index 58d4e75b..a79785d9 100644 --- a/buildcc/lib/target/test/target/constants.h.in +++ b/buildcc/lib/target/test/target/constants.h.in @@ -4,6 +4,8 @@ inline constexpr char const *BUILD_SCRIPT_SOURCE = "@CMAKE_CURRENT_SOURCE_DIR@"; inline constexpr char const *BUILD_TARGET_BASE_INTERMEDIATE_DIR = "@CMAKE_CURRENT_SOURCE_DIR@/intermediate"; + +inline constexpr char const *BUILD_TARGET_PCH_INTERMEDIATE_DIR = "@CMAKE_CURRENT_SOURCE_DIR@/intermediate/target_pch"; inline constexpr char const * BUILD_TARGET_SOURCE_INTERMEDIATE_DIR = "@CMAKE_CURRENT_SOURCE_DIR@/intermediate/target_source"; inline constexpr char const * BUILD_TARGET_SOURCE_OUT_OF_ROOT_INTERMEDIATE_DIR = "@CMAKE_CURRENT_SOURCE_DIR@/intermediate/target_source_out_of_root"; diff --git a/buildcc/lib/target/test/target/data/pch/pch_header_1.h b/buildcc/lib/target/test/target/data/pch/pch_header_1.h new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/target/test/target/data/pch/pch_header_2.h b/buildcc/lib/target/test/target/data/pch/pch_header_2.h new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/target/test/target/test_target_pch.cpp b/buildcc/lib/target/test/target/test_target_pch.cpp new file mode 100644 index 00000000..b2ecc7de --- /dev/null +++ b/buildcc/lib/target/test/target/test_target_pch.cpp @@ -0,0 +1,240 @@ +#include + +#include + +#include "constants.h" + +#include "expect_command.h" +#include "expect_target.h" + +#include "target/target.h" + +#include "env/env.h" +#include "env/util.h" + +// Third Party + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTest/UtestMacros.h" +#include "CppUTestExt/MockSupport.h" + +// clang-format off +TEST_GROUP(TargetPchTestGroup) +{ + void teardown() { + mock().clear(); + } +}; +// clang-format on + +static const buildcc::base::Toolchain gcc(buildcc::base::Toolchain::Id::Gcc, + "gcc", "as", "gcc", "g++", "ar", + "ld"); + +TEST(TargetPchTestGroup, Target_AddPch) { + constexpr const char *const NAME = "AddPch.exe"; + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); +} + +TEST(TargetPchTestGroup, Target_AddPch_Build) { + constexpr const char *const NAME = "AddPch_Build.exe"; + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); + + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + + mock().checkExpectations(); +} + +TEST(TargetPchTestGroup, Target_AddPch_Rebuild) { + constexpr const char *const NAME = "AddPch_Rebuild.exe"; + + { + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); + + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Rebuild: No change + { + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); + + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Rebuild: Removed + { + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + + buildcc::base::m::TargetExpect_PathRemoved(1, &target); + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Rebuild: Added + { + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); + + buildcc::base::m::TargetExpect_PathAdded(1, &target); + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Rebuild: Updated + { + sleep(1); + fs::path filename = + fs::path(BUILD_SCRIPT_SOURCE) / "data" / "pch/pch_header_1.h"; + bool save = buildcc::env::SaveFile(filename.string().c_str(), "", false); + CHECK_TRUE(save); + + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); + + buildcc::base::m::TargetExpect_PathUpdated(1, &target); + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + mock().checkExpectations(); +} + +TEST(TargetPchTestGroup, Target_AddPch_CppRebuild) { + constexpr const char *const NAME = "AddPch_CppRebuild.exe"; + + { + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); + target.AddSource("dummy_main.cpp"); + + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Rebuild: No change + { + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); + target.AddSource("dummy_main.cpp"); + + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Rebuild: Removed + { + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddSource("dummy_main.cpp"); + + buildcc::base::m::TargetExpect_PathRemoved(1, &target); + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Rebuild: Added + { + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); + target.AddSource("dummy_main.cpp"); + + buildcc::base::m::TargetExpect_PathAdded(1, &target); + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Rebuild: Updated + { + sleep(1); + fs::path filename = + fs::path(BUILD_SCRIPT_SOURCE) / "data" / "pch/pch_header_1.h"; + bool save = buildcc::env::SaveFile(filename.string().c_str(), "", false); + CHECK_TRUE(save); + + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); + target.AddSource("dummy_main.cpp"); + + buildcc::base::m::TargetExpect_PathUpdated(1, &target); + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + mock().checkExpectations(); +} + +int main(int ac, char **av) { + const fs::path target_source_intermediate_path = + fs::path(BUILD_TARGET_PCH_INTERMEDIATE_DIR) / gcc.GetName(); + fs::remove_all(target_source_intermediate_path); + + buildcc::env::init(BUILD_SCRIPT_SOURCE, BUILD_TARGET_PCH_INTERMEDIATE_DIR); + return CommandLineTestRunner::RunAllTests(ac, av); +} From dd3c6363e7b519af85479cf782cacda31d4e5115 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 13 Oct 2021 18:26:28 -0700 Subject: [PATCH 10/16] Updated compile_source and link_target --- buildcc/lib/target/src/target/compile_source.cpp | 11 +++++------ buildcc/lib/target/src/target/link_target.cpp | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/buildcc/lib/target/src/target/compile_source.cpp b/buildcc/lib/target/src/target/compile_source.cpp index e1f85555..ebc6d67a 100644 --- a/buildcc/lib/target/src/target/compile_source.cpp +++ b/buildcc/lib/target/src/target/compile_source.cpp @@ -168,7 +168,6 @@ void Target::BuildCompile(std::vector &source_files, PreCompile(); if (!loader_.IsLoaded()) { - CompileSources(source_files); dirty_ = true; } else { RecheckFlags(loader_.GetLoadedPreprocessorFlags(), @@ -184,12 +183,12 @@ void Target::BuildCompile(std::vector &source_files, RecheckPaths(loader_.GetLoadedHeaders(), current_header_files_.internal); RecheckPaths(loader_.GetLoadedCompileDependencies(), current_compile_dependencies_.internal); + } - if (dirty_) { - CompileSources(source_files); - } else { - RecompileSources(source_files, dummy_source_files); - } + if (dirty_) { + CompileSources(source_files); + } else { + RecompileSources(source_files, dummy_source_files); } } diff --git a/buildcc/lib/target/src/target/link_target.cpp b/buildcc/lib/target/src/target/link_target.cpp index c5ce037c..3d5be9a4 100644 --- a/buildcc/lib/target/src/target/link_target.cpp +++ b/buildcc/lib/target/src/target/link_target.cpp @@ -63,7 +63,7 @@ void Target::BuildLink() { RecheckPaths(loader_.GetLoadedLibDeps(), current_lib_deps_.internal); if (dirty_) { - bool success = Command::Execute(current_target_file_.command); + bool success = Command::Execute(GetLinkCommand()); env::assert_fatal(success, "Failed to link target"); Store(); state_.build = true; From 32fb2dd4175d580a793178e8a0710a45f15e9781 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 13 Oct 2021 18:27:09 -0700 Subject: [PATCH 11/16] Update README.md --- buildcc/lib/target/src/target/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/buildcc/lib/target/src/target/README.md b/buildcc/lib/target/src/target/README.md index f91b3321..f2429812 100644 --- a/buildcc/lib/target/src/target/README.md +++ b/buildcc/lib/target/src/target/README.md @@ -17,6 +17,8 @@ - [x] `include_dir.cpp` - Include Dir - Header File +- [x] `pch.cpp` + - Precompile Header files - [x] `lib.cpp` - Lib Dir - Lib File (full path Target supplied) @@ -55,7 +57,7 @@ ## Action on Target -- [ ] `compile_header.cpp` (pch) +- [x] `compile_header.cpp` (pch) - [x] `compile_source.cpp` (object) - [x] `link_target.cpp` (executable, library, C++20 module) - [x] `build.cpp` From 23d6dd60c0ecb98cfd535b36da2f1841d4ed4380 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 14 Oct 2021 00:14:34 -0700 Subject: [PATCH 12/16] Updated target.fbs with pch_flags --- buildcc/lib/target/include/target/target.h | 1 + buildcc/lib/target/include/target/target_loader.h | 4 ++++ buildcc/lib/target/src/target/target_loader.cpp | 1 + buildcc/lib/target/src/target/target_storer.cpp | 8 +++++--- buildcc/schema/target.fbs | 1 + 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index 2ba96102..e9543b96 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -378,6 +378,7 @@ class Target : public BuilderInterface { std::unordered_set current_external_lib_deps_; std::unordered_set current_preprocessor_flags_; std::unordered_set current_common_compile_flags_; + std::unordered_set current_pch_flags_; std::unordered_set current_asm_compile_flags_; std::unordered_set current_c_compile_flags_; std::unordered_set current_cpp_compile_flags_; diff --git a/buildcc/lib/target/include/target/target_loader.h b/buildcc/lib/target/include/target/target_loader.h index ec56379b..e5a7f30b 100644 --- a/buildcc/lib/target/include/target/target_loader.h +++ b/buildcc/lib/target/include/target/target_loader.h @@ -65,6 +65,9 @@ class TargetLoader : public LoaderInterface { const std::unordered_set &GetLoadedCommonCompileFlags() const { return loaded_common_compile_flags_; } + const std::unordered_set &GetLoadedPchFlags() const { + return loaded_pch_flags_; + } const std::unordered_set &GetLoadedAsmCompileFlags() const { return loaded_asm_compile_flags_; } @@ -104,6 +107,7 @@ class TargetLoader : public LoaderInterface { std::unordered_set loaded_preprocessor_flags_; std::unordered_set loaded_common_compile_flags_; + std::unordered_set loaded_pch_flags_; std::unordered_set loaded_asm_compile_flags_; std::unordered_set loaded_c_compile_flags_; std::unordered_set loaded_cpp_compile_flags_; diff --git a/buildcc/lib/target/src/target/target_loader.cpp b/buildcc/lib/target/src/target/target_loader.cpp index c8a0a105..5643c7c7 100644 --- a/buildcc/lib/target/src/target/target_loader.cpp +++ b/buildcc/lib/target/src/target/target_loader.cpp @@ -59,6 +59,7 @@ bool TargetLoader::Load() { Extract(target->preprocessor_flags(), loaded_preprocessor_flags_); Extract(target->common_compile_flags(), loaded_common_compile_flags_); + Extract(target->pch_flags(), loaded_pch_flags_); Extract(target->asm_compile_flags(), loaded_asm_compile_flags_); Extract(target->c_compile_flags(), loaded_c_compile_flags_); Extract(target->cpp_compile_flags(), loaded_cpp_compile_flags_); diff --git a/buildcc/lib/target/src/target/target_storer.cpp b/buildcc/lib/target/src/target/target_storer.cpp index c8c18559..64affcd3 100644 --- a/buildcc/lib/target/src/target/target_storer.cpp +++ b/buildcc/lib/target/src/target/target_storer.cpp @@ -65,6 +65,8 @@ bool Target::Store() { internal::CreateFbsVectorString(builder, current_preprocessor_flags_); auto fbs_common_compile_flags = internal::CreateFbsVectorString(builder, current_common_compile_flags_); + auto fbs_pch_flags = + internal::CreateFbsVectorString(builder, current_pch_flags_); auto fbs_asm_compile_flags = internal::CreateFbsVectorString(builder, current_asm_compile_flags_); auto fbs_c_compile_flags = @@ -83,9 +85,9 @@ bool Target::Store() { builder, name_.c_str(), fbs_target_type, &fbs_source_files, &fbs_header_files, &fbs_pch_files, &fbs_lib_deps, &fbs_external_lib_deps, &fbs_include_dirs, &fbs_lib_dirs, &fbs_preprocessor_flags, - &fbs_common_compile_flags, &fbs_asm_compile_flags, &fbs_c_compile_flags, - &fbs_cpp_compile_flags, &fbs_link_flags, &fbs_compile_dependencies, - &fbs_link_dependencies); + &fbs_common_compile_flags, &fbs_pch_flags, &fbs_asm_compile_flags, + &fbs_c_compile_flags, &fbs_cpp_compile_flags, &fbs_link_flags, + &fbs_compile_dependencies, &fbs_link_dependencies); fbs::FinishTargetBuffer(builder, fbs_target); auto file_path = GetBinaryPath(); diff --git a/buildcc/schema/target.fbs b/buildcc/schema/target.fbs index 77b78d91..fd320a33 100644 --- a/buildcc/schema/target.fbs +++ b/buildcc/schema/target.fbs @@ -43,6 +43,7 @@ table Target { // Flags preprocessor_flags:[string]; common_compile_flags:[string]; + pch_flags:[string]; asm_compile_flags:[string]; c_compile_flags:[string]; cpp_compile_flags:[string]; From 5639c2d8fc5a8f0baf6b51393cbabb736442ac6e Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 17 Oct 2021 18:16:12 -0700 Subject: [PATCH 13/16] Added AddPchFlag API --- buildcc/lib/target/include/target/target.h | 1 + buildcc/lib/target/src/target/flags.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index e9543b96..640d6c41 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -154,6 +154,7 @@ class Target : public BuilderInterface { // * Flags void AddPreprocessorFlag(const std::string &flag); void AddCommonCompileFlag(const std::string &flag); + void AddPchFlag(const std::string &flag); void AddAsmCompileFlag(const std::string &flag); void AddCCompileFlag(const std::string &flag); void AddCppCompileFlag(const std::string &flag); diff --git a/buildcc/lib/target/src/target/flags.cpp b/buildcc/lib/target/src/target/flags.cpp index b06bbe97..e563f7a1 100644 --- a/buildcc/lib/target/src/target/flags.cpp +++ b/buildcc/lib/target/src/target/flags.cpp @@ -26,6 +26,10 @@ void Target::AddCommonCompileFlag(const std::string &flag) { LockedAfterBuild(); current_common_compile_flags_.insert(flag); } +void Target::AddPchFlag(const std::string &flag) { + LockedAfterBuild(); + current_pch_flags_.insert(flag); +} void Target::AddAsmCompileFlag(const std::string &flag) { LockedAfterBuild(); current_asm_compile_flags_.insert(flag); From b0e36be94f2b0eba5ebde57a30f12a686c9363ba Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 17 Oct 2021 18:17:12 -0700 Subject: [PATCH 14/16] Updated compile_pch.cpp - Aggregated current_pch_flags for pch_flags custom command - Updated Rechecks during rebuild for pch --- buildcc/lib/target/src/target/compile_pch.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/buildcc/lib/target/src/target/compile_pch.cpp b/buildcc/lib/target/src/target/compile_pch.cpp index 849deb46..0c0970de 100644 --- a/buildcc/lib/target/src/target/compile_pch.cpp +++ b/buildcc/lib/target/src/target/compile_pch.cpp @@ -18,6 +18,7 @@ #include "env/assert_fatal.h" #include "env/util.h" +#include "target/util.h" namespace { @@ -62,7 +63,7 @@ std::string Target::ConstructPchCompileCommand() const { config_.pch_command, { {"compiler", compiler}, - {"pch_flags", ""}, // TODO, Add PCH specific flags + {"pch_flags", internal::aggregate(current_pch_flags_)}, {"compile_flags", compile_flags}, {"output", GetPchCompilePath().string()}, {"input", GetPchHeaderPath().string()}, @@ -81,6 +82,16 @@ void Target::BuildPch() { if (!loader_.IsLoaded()) { dirty_ = true; } else { + RecheckFlags(loader_.GetLoadedPreprocessorFlags(), + current_preprocessor_flags_); + RecheckFlags(loader_.GetLoadedCommonCompileFlags(), + current_common_compile_flags_); + RecheckFlags(loader_.GetLoadedPchFlags(), current_pch_flags_); + RecheckFlags(loader_.GetLoadedCCompileFlags(), current_c_compile_flags_); + RecheckFlags(loader_.GetLoadedCppCompileFlags(), + current_cpp_compile_flags_); + RecheckDirs(loader_.GetLoadedIncludeDirs(), current_include_dirs_); + RecheckPaths(loader_.GetLoadedHeaders(), current_header_files_.internal); RecheckPaths(loader_.GetLoadedPchs(), current_pch_files_.internal); } From 560d552ddd9f9f662f53346cbdcb00bfd1be3eac Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 17 Oct 2021 18:29:55 -0700 Subject: [PATCH 15/16] Updated custom_target command.md document --- doc/custom_target/commands.md | 36 ++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/doc/custom_target/commands.md b/doc/custom_target/commands.md index d839a22c..40dddaa2 100644 --- a/doc/custom_target/commands.md +++ b/doc/custom_target/commands.md @@ -2,31 +2,31 @@ 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 +This is done by overriding the 3 `base::Target::Config` strings -**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}"; -} +base::Target::Config config; -std::string_view Link() const override { - return "{cpp_compiler} {link_flags} {compiled_sources} -o {output} {lib_dirs} {lib_deps}"; -} +config.pch_command = "{compiler} {preprocessor_flags} {include_dirs} {common_compile_flags} {pch_flags} {compile_flags} -o {output} -c {input}"; + +config.compile_command = "{compiler} {preprocessor_flags} {include_dirs} {common_compile_flags} {compile_flags} -o {output} -c {input}"; + +config.link_command = "{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) +- See [GCC specific overrides](../../buildcc/targets/include/targets/target_gcc.h) +- See [MSVC specific overrides](../../buildcc/targets/include/targets/target_msvc.h) # General -The following `{}` commands are available to both `CompileCommand` and `Link` functions +The following `{}` commands are available to both `pch_command`, `compile_command` and `link_command` 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 - `preprocessor_flags`: Preprocessor definitions +- `common_compile_flags`: Common compile flags for `PCH`, `ASM`, `C` and `CPP` files - `link_flags`: Flags supplied during linking - `asm_compiler`: Assembly compiler - `c_compiler`: C compiler @@ -34,9 +34,19 @@ See [build.cpp Target::Build API](../../buildcc/lib/target/src/target/build.cpp) - `archiver`: Archiver for Static Libraries - `linker`: Linker usually used during the Linking phase / Library creation +# PCH Specific + +See [compile_pch.cpp Target::ConstructPchCompileCommand API](../../buildcc/lib/target/src/target/compile_pch.cpp) + +- `compiler`: Selects CPP compiler if project contains CPP source else C compiler +- `pch_flags`: Aggregated pch specific flags +- `compile_flags`: Selects CPP flags if project contains CPP source else C flags +- `output`: PCH output path +- `input`: PCH input generated path (Headers are aggregated into a .h file) + # Compile Specific -See [source.cpp Target::CompileCommand API](../../buildcc/lib/target/src/target/source.cpp) +See [compile_source.cpp Target::ConstructCompileCommand API](../../buildcc/lib/target/src/target/compile_source.cpp) - `compiler`: Automatically chosen amongst ASM, C and C++ toolchain compiler - `compile_flags`: Automatically chosen amongst `{c/cpp}_flags` @@ -45,7 +55,7 @@ See [source.cpp Target::CompileCommand API](../../buildcc/lib/target/src/target/ # Links Specific -See [build.cpp Target::Target API](../../buildcc/lib/target/src/target/build.cpp) +See [link_target.cpp Target::ConstructLinkCommand API](../../buildcc/lib/target/src/target/link_target.cpp) - `output`: Generated target as `Target::GetName()` - `compiled_sources`: Aggregated object files From cd6fa14a2843250de8853ad08297fb34cb1f5bc0 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 17 Oct 2021 19:27:53 -0700 Subject: [PATCH 16/16] Updated test_target_pch --- buildcc/lib/target/include/target/target.h | 3 +++ .../target/test/target/test_target_pch.cpp | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index 640d6c41..f586559f 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -228,6 +228,9 @@ class Target : public BuilderInterface { const std::unordered_set &GetCurrentCommonCompileFlags() const { return current_common_compile_flags_; } + const std::unordered_set &GetCurrentPchFlags() const { + return current_pch_flags_; + } const std::unordered_set &GetCurrentAsmCompileFlags() const { return current_asm_compile_flags_; } diff --git a/buildcc/lib/target/test/target/test_target_pch.cpp b/buildcc/lib/target/test/target/test_target_pch.cpp index b2ecc7de..be18791b 100644 --- a/buildcc/lib/target/test/target/test_target_pch.cpp +++ b/buildcc/lib/target/test/target/test_target_pch.cpp @@ -230,6 +230,25 @@ TEST(TargetPchTestGroup, Target_AddPch_CppRebuild) { mock().checkExpectations(); } +TEST(TargetPchTestGroup, Target_AddPchFlag_Build) { + constexpr const char *const NAME = "AddPchFlag_Build.exe"; + + buildcc::base::Target target(NAME, buildcc::base::Target::Type::Executable, + gcc, "data"); + target.AddPchFlag("-H"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); + + buildcc::m::CommandExpect_Execute(1, true); + buildcc::m::CommandExpect_Execute(1, true); + target.Build(); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + CHECK_EQUAL(target.GetCurrentPchFlags().size(), 1); + + mock().checkExpectations(); +} + int main(int ac, char **av) { const fs::path target_source_intermediate_path = fs::path(BUILD_TARGET_PCH_INTERMEDIATE_DIR) / gcc.GetName();