Skip to content
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ _deps
.vscode/
.vs/
.idea/
.cache/

# Files
*.gcov
Expand Down
3 changes: 2 additions & 1 deletion buildcc/lib/target/cmake/mock_target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions buildcc/lib/target/cmake/target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 37 additions & 1 deletion buildcc/lib/target/include/target/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -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}"};
Expand Down Expand Up @@ -101,7 +106,6 @@ class Target : public BuilderInterface {
}
virtual ~Target() {}

Target(Target &&target) = default;
Target(const Target &target) = delete;

// Builders
Expand Down Expand Up @@ -129,6 +133,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);
Expand All @@ -145,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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -207,6 +228,9 @@ class Target : public BuilderInterface {
const std::unordered_set<std::string> &GetCurrentCommonCompileFlags() const {
return current_common_compile_flags_;
}
const std::unordered_set<std::string> &GetCurrentPchFlags() const {
return current_pch_flags_;
}
const std::unordered_set<std::string> &GetCurrentAsmCompileFlags() const {
return current_asm_compile_flags_;
}
Expand Down Expand Up @@ -273,11 +297,15 @@ class Target : public BuilderInterface {
void UnlockedAfterBuild() const;

// Build
void BuildPch();
// TODO, Rename to BuildObject
void BuildCompile(std::vector<fs::path> &source_files,
std::vector<fs::path> &dummy_source_files);
void BuildLink();

//
void PrePchCompile();
// TODO, Rename to PreObjectCompile
void PreCompile();
void PreLink();

Expand All @@ -298,6 +326,8 @@ class Target : public BuilderInterface {
const std::unordered_set<std::string> &current_external_libs);

// Tasks
void PchTask();
// TODO, Rename to ObjectTask and TargetTask
void CompileTask();
void LinkTask();

Expand All @@ -319,6 +349,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;
Expand All @@ -344,12 +375,14 @@ 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_;
std::unordered_set<std::string> current_external_lib_deps_;
std::unordered_set<std::string> current_preprocessor_flags_;
std::unordered_set<std::string> current_common_compile_flags_;
std::unordered_set<std::string> current_pch_flags_;
std::unordered_set<std::string> current_asm_compile_flags_;
std::unordered_set<std::string> current_c_compile_flags_;
std::unordered_set<std::string> current_cpp_compile_flags_;
Expand All @@ -360,6 +393,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<fs::path, OutputInfo, internal::PathHash>
current_object_files_;
OutputInfo current_target_file_;
Expand All @@ -369,6 +404,7 @@ class Target : public BuilderInterface {
FileExt ext_{*this};

tf::Taskflow tf_;
tf::Task pch_task_;
tf::Task compile_task_;
tf::Task link_task_;
};
Expand Down
6 changes: 6 additions & 0 deletions buildcc/lib/target/include/target/target_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
}
Expand All @@ -64,6 +65,9 @@ class TargetLoader : public LoaderInterface {
const std::unordered_set<std::string> &GetLoadedCommonCompileFlags() const {
return loaded_common_compile_flags_;
}
const std::unordered_set<std::string> &GetLoadedPchFlags() const {
return loaded_pch_flags_;
}
const std::unordered_set<std::string> &GetLoadedAsmCompileFlags() const {
return loaded_asm_compile_flags_;
}
Expand Down Expand Up @@ -93,6 +97,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<std::string> loaded_external_lib_dirs_;
Expand All @@ -102,6 +107,7 @@ class TargetLoader : public LoaderInterface {

std::unordered_set<std::string> loaded_preprocessor_flags_;
std::unordered_set<std::string> loaded_common_compile_flags_;
std::unordered_set<std::string> loaded_pch_flags_;
std::unordered_set<std::string> loaded_asm_compile_flags_;
std::unordered_set<std::string> loaded_c_compile_flags_;
std::unordered_set<std::string> loaded_cpp_compile_flags_;
Expand Down
2 changes: 2 additions & 0 deletions buildcc/lib/target/mock/target/tasks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace buildcc::base {

void Target::PchTask() { BuildPch(); }

void Target::CompileTask() {
std::vector<fs::path> source_files;
std::vector<fs::path> dummy_source_files;
Expand Down
4 changes: 3 additions & 1 deletion buildcc/lib/target/src/target/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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`
Expand Down
20 changes: 13 additions & 7 deletions buildcc/lib/target/src/target/build.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
105 changes: 105 additions & 0 deletions buildcc/lib/target/src/target/compile_pch.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* 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"
#include "target/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", internal::aggregate(current_pch_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 {
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);
}

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
Loading