diff options
| -rw-r--r-- | src/ctor.h | 12 | ||||
| -rw-r--r-- | src/task_cc.cc | 8 | ||||
| -rw-r--r-- | src/task_fn.cc | 3 | ||||
| -rw-r--r-- | src/tasks.cc | 4 | ||||
| -rw-r--r-- | test/ctor.cc | 17 | ||||
| -rw-r--r-- | test/generated_sources_test.cc | 80 |
6 files changed, 121 insertions, 3 deletions
@@ -67,6 +67,12 @@ struct output_file std::string file; }; +enum class source_type +{ + regular, + generated, +}; + struct source { template <class ... Args> @@ -74,6 +80,7 @@ struct source std::is_convertible_v<Args, std::string_view> || std::is_same_v<Args, ctor::toolchain> || std::is_same_v<Args, ctor::language> || + std::is_same_v<Args, ctor::source_type> || std::is_same_v<Args, ctor::output_file> ) && ...) constexpr source(Args && ... arg) @@ -96,6 +103,10 @@ struct source { output = arg.file; } + else if constexpr(std::is_same_v<Args, ctor::source_type>) + { + source_type = arg; + } }(), ...); } @@ -103,6 +114,7 @@ struct source ctor::toolchain toolchain{ctor::toolchain::any}; ctor::language language{ctor::language::automatic}; std::string output{}; + ctor::source_type source_type{ctor::source_type::regular}; }; enum class cxx_opt diff --git a/src/task_cc.cc b/src/task_cc.cc index 9628455..f81023f 100644 --- a/src/task_cc.cc +++ b/src/task_cc.cc @@ -23,6 +23,10 @@ TaskCC::TaskCC(const ctor::build_configuration& config_, const ctor::settings& s , sourceDir(sourceDir_) , _source(source) { + if(source.source_type == ctor::source_type::generated) + { + sourceFile = std::filesystem::path(settings.builddir) / sourceFile; + } sourceFile /= source.file; std::filesystem::path base = sourceFile.parent_path(); @@ -252,6 +256,10 @@ int TaskCC::clean() std::vector<std::string> TaskCC::depends() const { + if(_source.source_type == ctor::source_type::generated) + { + return {sourceFile.string()}; + } return {}; } diff --git a/src/task_fn.cc b/src/task_fn.cc index b6b50ea..ebfdac6 100644 --- a/src/task_fn.cc +++ b/src/task_fn.cc @@ -24,6 +24,7 @@ TaskFn::TaskFn(const ctor::build_configuration& config_, const ctor::settings& s target_type = config.type; source_language = source.language; + std::filesystem::path base = sourceFile.parent_path(); if(source.output.empty()) { @@ -31,7 +32,7 @@ TaskFn::TaskFn(const ctor::build_configuration& config_, const ctor::settings& s exit(1); } - _targetFile = source.output; + _targetFile = base / source.output; } bool TaskFn::dirtyInner() diff --git a/src/tasks.cc b/src/tasks.cc index 94fe269..7de8af9 100644 --- a/src/tasks.cc +++ b/src/tasks.cc @@ -114,9 +114,9 @@ std::vector<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration& #ifndef BOOTSTRAP else { - for(const auto& file : config.sources) + for(const auto& source : config.sources) { - auto task = std::make_shared<TaskFn>(config, settings, sourceDir, file); + auto task = std::make_shared<TaskFn>(config, settings, sourceDir, source); tasks.push_back(task); objects.push_back(task->target()); } diff --git a/test/ctor.cc b/test/ctor.cc index e33dc77..8b89f6d 100644 --- a/test/ctor.cc +++ b/test/ctor.cc @@ -28,6 +28,23 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) { .type = ctor::target_type::unit_test, .system = ctor::output_system::build, + .target = "generated_sources_test", + .sources = { + "generated_sources_test.cc", + "testmain.cc", + }, + .depends = { "libctor_nomain.a" }, + .flags = { + .cxxflags = { + "-std=c++20", "-O3", "-Wall", + "-I../src", "-Iuunit", + "-DOUTPUT=\"generated_sources\"", + }, + }, + }, + { + .type = ctor::target_type::unit_test, + .system = ctor::output_system::build, .target = "argsplit_test", .sources = { "argsplit_test.cc", diff --git a/test/generated_sources_test.cc b/test/generated_sources_test.cc new file mode 100644 index 0000000..53bde62 --- /dev/null +++ b/test/generated_sources_test.cc @@ -0,0 +1,80 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#include <uunit.h> + +#include <ctor.h> +#include <tasks.h> +#include <rebuild.h> + +class GeneratedSourcesTest + : public uUnit +{ +public: + GeneratedSourcesTest() + { + uTEST(GeneratedSourcesTest::test_custom_output); + } + + void setup() + { + // Make sure we start from a clean slate + getConfigFileList().clear(); + } + + void test_custom_output() + { + using namespace std::string_literals; + + ctor::reg( + [](const ctor::settings&) + { + return ctor::build_configurations{ + { + .target = "test1", + .sources = { + {"foo.cc", ctor::source_type::generated} + } + }, + { + .target = "this_is_unused", + .sources = { + {"bar.x", ctor::output_file{"foo.cc"}}, + {"bar.y", ctor::output_file{"bar.cc"}}, + }, + .function = [](const std::string& input, + const std::string& output, + const ctor::build_configuration& config, + const ctor::settings& settings) + { + return 0; + } + }, + }; + }); + ctor::settings settings{}; + auto tasks = getTasks(settings); + for(auto task : tasks) + { + uASSERT(task->registerDepTasks(tasks) == 0); + } + uASSERT_EQUAL(4u, tasks.size()); + bool found{false}; + for(const auto& task : tasks) + { + if(task->target() == "test1") + { + auto deps_test1 = task->getDependsTasks(); + uASSERT_EQUAL(1u, deps_test1.size()); + auto deps_foo_o = deps_test1[0]->getDependsTasks(); + uASSERT_EQUAL(1u, deps_foo_o.size()); + uASSERT_EQUAL("test/bar.x"s, deps_foo_o[0]->source()); + found = true; + } + } + uASSERT(found); + } +}; + +// Registers the fixture into the 'registry' +static GeneratedSourcesTest test; |
