Skip to content

Toolchain generic #209

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
Apr 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
372b03e
Updated storage.h
coder137 Apr 25, 2022
2f5ca64
Update ScopedStorage
coder137 Apr 25, 2022
af59133
Added Clear API for ScopedStorage
coder137 Apr 25, 2022
f5cd405
Updated static Storage API
coder137 Apr 25, 2022
f36083c
Updated specialized toolchains
coder137 Apr 25, 2022
d7768bb
Added toolchain_generic.h
coder137 Apr 25, 2022
9f0580c
Updated register.cpp with SystemInit
coder137 Apr 25, 2022
bfbf8d5
Updated toolchain verify
coder137 Apr 26, 2022
2f2b462
Updated test toolchain verify tests
coder137 Apr 26, 2022
fcdb7d4
Updated specialized_toolchains to static library
coder137 Apr 26, 2022
189279e
Minor update
coder137 Apr 26, 2022
7f95557
Updated toolchain with lock false
coder137 Apr 27, 2022
e507729
Updated specialized toolchains
coder137 Apr 27, 2022
4a70ed5
Updated toolchain_verify
coder137 Apr 27, 2022
86a129d
Updated toolchain_generic
coder137 Apr 27, 2022
c827f44
Updated specialized toolchains
coder137 Apr 27, 2022
fdb4640
Updated toolchain generic
coder137 Apr 27, 2022
8733c8d
Removed toolchain lock check
coder137 Apr 27, 2022
63027d1
Updated test toolchains
coder137 Apr 27, 2022
9164ff6
Updated buildcc.h with toolchain_generic and toolchain_custom
coder137 Apr 27, 2022
df4576f
Added toolchain_custom.h
coder137 Apr 27, 2022
cd200cc
Updated toolchain_generic with comments
coder137 Apr 27, 2022
c36b2fd
Updated toolchain_custom
coder137 Apr 27, 2022
e04d187
Updated toolchain.h
coder137 Apr 27, 2022
06f0a3e
Updated args.h (derived from Toolchain)
coder137 Apr 27, 2022
fe7c4f0
Added virtual destructor to specialized toolchains
coder137 Apr 27, 2022
4dc070d
Updated toolchain_verify
coder137 Apr 28, 2022
12883c2
Updated toolchain.cpp
coder137 Apr 28, 2022
7bc54e7
Updated toolchain_custom.h
coder137 Apr 28, 2022
2652244
Updated toolchain gcc and msvc
coder137 Apr 28, 2022
634a7a0
Added toolchain infos
coder137 Apr 28, 2022
3ccd9ed
Updated args
coder137 Apr 28, 2022
5320447
Updated buildcc.h
coder137 Apr 28, 2022
d3a9470
Updated examples, bootstrap and buildexe
coder137 Apr 28, 2022
1613628
Updated documentation
coder137 Apr 28, 2022
4bd0c9f
Updated toolchain_verify and tests
coder137 Apr 28, 2022
2da54f7
Updated bootstrap for buildcc
coder137 Apr 28, 2022
2a18e45
Updated toolchain msvc
coder137 Apr 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bootstrap/main.buildcc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ int main(int argc, char **argv) {
Reg::Init();
Reg::Call(Args::Clean()).Func(clean_cb);

BaseToolchain toolchain = custom_toolchain_arg.ConstructToolchain();
auto &toolchain = custom_toolchain_arg;
toolchain.SetToolchainInfoFunc(GlobalToolchainInfo::Get(toolchain.id));

BuildBuildCC buildcc(
toolchain, TargetEnv(Project::GetRootDir(), Project::GetBuildDir()));
Expand Down
1 change: 1 addition & 0 deletions bootstrap/src/build_buildcc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen,
target.GlobHeaders("lib/args/include/args");

// Specialized Toolchains
target.GlobSources("toolchains/src");
target.AddIncludeDir("toolchains/include");
target.GlobHeaders("toolchains/include/toolchains");

Expand Down
4 changes: 4 additions & 0 deletions buildcc/buildcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
#include "toolchains/toolchain_gcc.h"
#include "toolchains/toolchain_msvc.h"
#include "toolchains/toolchain_mingw.h"
#include "toolchains/toolchain_generic.h"
#include "toolchains/toolchain_custom.h"

#include "toolchains/toolchain_infos.h"

// TODO, Add more specialized toolchains here

Expand Down
46 changes: 21 additions & 25 deletions buildcc/lib/args/include/args/args.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,35 +47,31 @@ struct ArgToolchainState {
* command line
* Bundled with Toolchain State
*/
struct ArgToolchain {
ArgToolchain() = default;
class ArgToolchain : public Toolchain {
public:
ArgToolchain()
: Toolchain(ToolchainId::Undefined, "", ToolchainExecutables()){};
ArgToolchain(ToolchainId initial_id, const std::string &initial_name,
const ToolchainExecutables &initial_executables)
: id(initial_id), name(initial_name), executables(initial_executables) {}
ArgToolchain(ToolchainId initial_id, const std::string &initial_name,
const std::string &initial_assembler,
const std::string &initial_c_compiler,
const std::string &initial_cpp_compiler,
const std::string &initial_archiver,
const std::string &initial_linker)
: ArgToolchain(initial_id, initial_name,
ToolchainExecutables(initial_assembler, initial_c_compiler,
initial_cpp_compiler,
initial_archiver, initial_linker)) {}

/**
* @brief Construct a BaseToolchain from the arguments supplied through the
* command line information
*/
// TODO, Update this for lock and ToolchainConfig
BaseToolchain ConstructToolchain() const {
return BaseToolchain(id, name, executables);
}
: Toolchain(initial_id, initial_name, initial_executables) {}
[[deprecated]] ArgToolchain(ToolchainId initial_id,
const std::string &initial_name,
const std::string &initial_assembler,
const std::string &initial_c_compiler,
const std::string &initial_cpp_compiler,
const std::string &initial_archiver,
const std::string &initial_linker)
: Toolchain(initial_id, initial_name,
ToolchainExecutables(initial_assembler, initial_c_compiler,
initial_cpp_compiler, initial_archiver,
initial_linker)) {}

public:
ArgToolchainState state;
ToolchainId id{ToolchainId::Undefined};
std::string name{""};
ToolchainExecutables executables;
ToolchainId &id = RefId();
std::string &name = RefName();
ToolchainExecutables &executables = RefExecutables();
ToolchainConfig &config = RefConfig();
};

// NOTE, Incomplete without pch_compile_command
Expand Down
22 changes: 19 additions & 3 deletions buildcc/lib/args/src/register.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "env/assert_fatal.h"
#include "env/env.h"
#include "env/storage.h"

namespace fs = std::filesystem;

Expand Down Expand Up @@ -67,13 +68,28 @@ namespace buildcc {

std::unique_ptr<Reg::Instance> Reg::instance_;

void SystemInit() {
Project::Init(fs::current_path() / Args::GetProjectRootDir(),
fs::current_path() / Args::GetProjectBuildDir());
env::set_log_level(Args::GetLogLevel());

// Top down (what is init first gets deinit last)
std::atexit([]() {
Project::Deinit();
Reg::Deinit();
Args::Deinit();
Storage::Clear();
});
}

void Reg::Init() {
if (!instance_) {
instance_ = std::make_unique<Instance>();
env::assert_fatal(static_cast<bool>(instance_), "Reg::Init failed");
env::assert_fatal(Args::IsParsed(), "Setup your Args");
Project::Init(fs::current_path() / Args::GetProjectRootDir(),
fs::current_path() / Args::GetProjectBuildDir());
env::set_log_level(Args::GetLogLevel());

// Initialize everything else here
SystemInit();
}
}

Expand Down
54 changes: 39 additions & 15 deletions buildcc/lib/env/include/env/storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,7 @@ namespace buildcc {
class ScopedStorage {
public:
ScopedStorage() {}
~ScopedStorage() {
for (const auto &ptr_iter : ptrs_) {
ptr_iter.second.destructor();
}
ptrs_.clear();
env::assert_fatal(ptrs_.empty(), "Memory not deallocated");
}
~ScopedStorage() { Clear(); }

ScopedStorage(const ScopedStorage &) = delete;

Expand All @@ -58,10 +52,15 @@ class ScopedStorage {
return *ptr;
}

template <typename T> void Remove(T *ptr) { delete ptr; }
void Clear() {
for (const auto &ptr_iter : ptrs_) {
ptr_iter.second.destructor();
}
ptrs_.clear();
}

template <typename T> const T &ConstRef(const std::string &identifier) const {
env::assert_fatal(ptrs_.find(identifier) != ptrs_.end(),
env::assert_fatal(Contains(identifier),
fmt::format("Could not find '{}'", identifier));
const PtrMetadata &metadata = ptrs_.at(identifier);
env::assert_fatal(
Expand All @@ -77,12 +76,30 @@ class ScopedStorage {
static_cast<const ScopedStorage &>(*this).ConstRef<T>(identifier));
}

bool Contains(const std::string &identifier) const {
return (ptrs_.find(identifier) != ptrs_.end());
}

template <typename T> bool Valid(const std::string &identifier) const {
if (!Contains(identifier)) {
return false;
}
const PtrMetadata &metadata = ptrs_.at(identifier);
if (typeid(T).name() != metadata.typeid_name) {
return false;
}
return true;
}

protected:
template <typename T> void Remove(T *ptr) { delete ptr; }

private:
/**
* @brief
* @param ptr Can hold data of any type
* @param typeid_name We cannot store a template type so this is the next best
* thing
* @param typeid_name We cannot store a template type so this is the next
* best thing
* @param desstructor Destructor callback to delete ptr
*/
struct PtrMetadata {
Expand All @@ -101,14 +118,13 @@ class Storage {
Storage(const Storage &) = delete;
Storage(Storage &&) = delete;

static void Init() { internal_ = std::make_unique<ScopedStorage>(); }
static void Deinit() { internal_.reset(nullptr); }

template <typename T, typename... Params>
static T &Add(const std::string &identifier, Params &&...params) {
return Ref().Add<T, Params...>(identifier, std::forward<Params>(params)...);
}

static void Clear() { Ref().Clear(); }

template <typename T>
static const T &ConstRef(const std::string &identifier) {
return Ref().ConstRef<T>(identifier);
Expand All @@ -118,11 +134,19 @@ class Storage {
return Ref().Ref<T>(identifier);
}

static bool Contains(const std::string &identifier) {
return Ref().Contains(identifier);
}

template <typename T> static bool Valid(const std::string &identifier) {
return Ref().Valid<T>(identifier);
}

private:
static ScopedStorage &Ref();

private:
static std::unique_ptr<ScopedStorage> internal_;
static ScopedStorage internal_;
};

} // namespace buildcc
Expand Down
8 changes: 2 additions & 6 deletions buildcc/lib/env/src/storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,8 @@

namespace buildcc {

std::unique_ptr<ScopedStorage> Storage::internal_;
ScopedStorage Storage::internal_;

ScopedStorage &Storage::Ref() {
env::assert_fatal(internal_ != nullptr,
"Initialize Storage using the Storage::Init API");
return *internal_;
}
ScopedStorage &Storage::Ref() { return internal_; }

} // namespace buildcc
45 changes: 32 additions & 13 deletions buildcc/lib/env/test/test_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,23 @@ TEST_GROUP(ScopedStorageTestGroup)
TEST_GROUP(StorageTestGroup)
{
void setup() {
buildcc::Storage::Init();
MemoryLeakWarningPlugin::saveAndDisableNewDeleteOverloads();
}
void teardown() {
buildcc::Storage::Deinit();
buildcc::Storage::Clear();
MemoryLeakWarningPlugin::restoreNewDeleteOverloads();
}
};
// clang-format on

class MyScopedStorage : public buildcc::ScopedStorage {
public:
// We want to unit test this
template <typename T> void Remove(T *ptr) {
this->ScopedStorage::Remove<T>(ptr);
}
};

class BigObj {};

class BigObjWithParameters {
Expand All @@ -42,19 +51,29 @@ class BigObjWithParameters {
static BigObj obj;

TEST(ScopedStorageTestGroup, BasicUsage) {
buildcc::ScopedStorage storage;
MyScopedStorage storage;
storage.Add<BigObjWithParameters>("identifier", "name", 10, obj);
storage.Add<BigObjWithParameters>("identifier2", "name2", 12, obj);

// Usage
storage.ConstRef<BigObjWithParameters>("identifier").GetName();
storage.Ref<BigObjWithParameters>("identifier2").GetName();

CHECK_TRUE(storage.Contains("identifier"));
CHECK_FALSE(storage.Contains("identifier_does_not_exist"));

CHECK_TRUE(storage.Valid<BigObjWithParameters>("identifier"));
CHECK_FALSE(storage.Valid<BigObjWithParameters>("wrong_identifier"));
CHECK_FALSE(storage.Valid<int>("identifier"));

storage.Clear();
CHECK_FALSE(storage.Contains("identifier"));

// Automatic cleanup here
}

TEST(ScopedStorageTestGroup, IncorrectUsage) {
buildcc::ScopedStorage storage;
MyScopedStorage storage;
storage.Add<BigObjWithParameters>("identifier", "name", 10, obj);

// We try to cast to a different type!
Expand All @@ -65,13 +84,13 @@ TEST(ScopedStorageTestGroup, IncorrectUsage) {
storage.Ref<BigObjWithParameters>("identifier2"));
}

std::string &toReference(std::string *pointer) { return *pointer; }

TEST(ScopedStorageTestGroup, NullptrDelete) {
buildcc::ScopedStorage storage;
MyScopedStorage storage;
storage.Remove<std::string>(nullptr);
}

//

TEST(StorageTestGroup, BasicUsage) {
buildcc::Storage::Add<BigObjWithParameters>("identifier", "name", 10, obj);
buildcc::Storage::Add<BigObjWithParameters>("identifier2", "name2", 12, obj);
Expand All @@ -84,14 +103,14 @@ TEST(StorageTestGroup, BasicUsage) {

STRCMP_EQUAL(bigobj.c_str(), "name");
STRCMP_EQUAL(bigobj2.c_str(), "name2");
}

TEST(StorageTestGroup, UsageWithoutInit) {
buildcc::Storage::Deinit();
CHECK_TRUE(buildcc::Storage::Contains("identifier"));
CHECK_FALSE(buildcc::Storage::Contains("identifier_does_not_exist"));

CHECK_THROWS(std::exception, buildcc::Storage::Add<int>("integer"));
CHECK_THROWS(std::exception, buildcc::Storage::Ref<int>("integer"));
CHECK_THROWS(std::exception, buildcc::Storage::ConstRef<int>("integer"));
CHECK_TRUE(buildcc::Storage::Valid<BigObjWithParameters>("identifier"));
CHECK_FALSE(
buildcc::Storage::Valid<BigObjWithParameters>("wrong_identifier"));
CHECK_FALSE(buildcc::Storage::Valid<BigObj>("identifier"));
}

int main(int ac, char **av) {
Expand Down
5 changes: 3 additions & 2 deletions buildcc/lib/target/src/target_info/target_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ namespace buildcc {
// PRIVATE

void TargetInfo::Initialize() {
toolchain_.GetLockInfo().ExpectsLock(
"Toolchain should be locked before usage through `Toolchain::Lock`");
// TODO, Update this later
// toolchain_.GetLockInfo().ExpectsLock(
// "Toolchain should be locked before usage through `Toolchain::Lock`");

std::for_each(toolchain_.GetPreprocessorFlags().begin(),
toolchain_.GetPreprocessorFlags().end(),
Expand Down
9 changes: 6 additions & 3 deletions buildcc/lib/target/test/target/test_toolchain_flag_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ TEST_GROUP(ToolchainFlagApiTestGroup)
TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Lock) {
buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc",
"g++", "ar", "ld");
toolchain.Lock();
CHECK_THROWS(std::exception, toolchain.AddPreprocessorFlag("-preprocessor"));
CHECK_THROWS(std::exception, toolchain.AddAsmCompileFlag("-asm"));
CHECK_THROWS(std::exception, toolchain.AddPchCompileFlag("-pchcompile"));
Expand All @@ -29,7 +30,7 @@ TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Lock) {

TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Unlock) {
buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc",
"g++", "ar", "ld", false);
"g++", "ar", "ld");
toolchain.AddPreprocessorFlag("-preprocessor");
toolchain.AddAsmCompileFlag("-asm");
toolchain.AddPchCompileFlag("-pchcompile");
Expand All @@ -55,7 +56,7 @@ TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Unlock) {

TEST(ToolchainFlagApiTestGroup, BasicTargetTest) {
buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc",
"g++", "ar", "ld", false);
"g++", "ar", "ld");

toolchain.AddPreprocessorFlag("-preprocessor");
toolchain.AddAsmCompileFlag("-asm");
Expand All @@ -67,7 +68,9 @@ TEST(ToolchainFlagApiTestGroup, BasicTargetTest) {
toolchain.AddLinkFlag("-link");

CHECK_FALSE(toolchain.GetLockInfo().IsLocked());
{ CHECK_THROWS(std::exception, (buildcc::TargetInfo(toolchain, ""))); }
// TODO, Add this in later
// * We should lock our toolchain before using it
// { CHECK_THROWS(std::exception, (buildcc::TargetInfo(toolchain, ""))); }

toolchain.Lock();
CHECK_TRUE(toolchain.GetLockInfo().IsLocked());
Expand Down
Loading