summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ctor.h19
-rw-r--r--src/task.cc2
-rw-r--r--src/task.h2
-rw-r--r--src/task_fn.cc187
-rw-r--r--src/task_fn.h5
-rw-r--r--src/task_ld.cc5
-rw-r--r--src/task_ld.h1
-rw-r--r--src/tasks.cc16
8 files changed, 195 insertions, 42 deletions
diff --git a/src/ctor.h b/src/ctor.h
index f145eef..dddc5ef 100644
--- a/src/ctor.h
+++ b/src/ctor.h
@@ -282,10 +282,17 @@ struct settings
};
struct build_configuration;
-using GeneratorCb = std::function<int(const std::string& input,
- const std::string& output,
- const build_configuration& config,
- const ctor::settings& settings)>;
+using GeneratorOneToOne =
+ std::function<int(const std::string& input,
+ const std::string& output,
+ const build_configuration& config,
+ const ctor::settings& settings)>;
+
+using GeneratorManyToOne =
+ std::function<int(const std::vector<std::string>& input,
+ const std::string& output,
+ const ctor::build_configuration& config,
+ const ctor::settings& settings)>;
struct build_configuration
{
@@ -297,7 +304,9 @@ struct build_configuration
std::vector<std::string> depends; // internal target dependencies
ctor::flags flags;
std::vector<std::string> externals; // externals used by this configuration
- GeneratorCb function;
+ std::variant<std::monostate,
+ GeneratorOneToOne,
+ GeneratorManyToOne> function;
};
using build_configurations = std::vector<build_configuration>;
diff --git a/src/task.cc b/src/task.cc
index 5484c23..17559bf 100644
--- a/src/task.cc
+++ b/src/task.cc
@@ -12,7 +12,7 @@ Task::Task(const ctor::build_configuration& config_, const ctor::settings& setti
: config(config_)
, output_system(config.system)
, settings(settings_)
- , sourceDir(std::move(sourceDir_))
+ , sourceDir(sourceDir_)
{
}
diff --git a/src/task.h b/src/task.h
index 32d0de3..c884186 100644
--- a/src/task.h
+++ b/src/task.h
@@ -79,5 +79,5 @@ protected:
ctor::language source_language{ctor::language::automatic};
ctor::output_system output_system{ctor::output_system::host};
const ctor::settings& settings;
- std::string sourceDir;
+ std::filesystem::path sourceDir;
};
diff --git a/src/task_fn.cc b/src/task_fn.cc
index ebfdac6..69e36ac 100644
--- a/src/task_fn.cc
+++ b/src/task_fn.cc
@@ -11,46 +11,129 @@
#include "execute.h"
#include "util.h"
-TaskFn::TaskFn(const ctor::build_configuration& config_, const ctor::settings& settings_,
- const std::string& sourceDir_, const ctor::source& source)
+TaskFn::TaskFn(const ctor::build_configuration& config_,
+ const ctor::settings& settings_,
+ const std::string& sourceDir_,
+ const ctor::source& source)
: Task(config_, settings_, sourceDir_)
- , sourceFile(sourceDir_)
, config(config_)
, settings(settings_)
{
- sourceFile /= source.file;
-
- std::filesystem::create_directories(std::filesystem::path(settings.builddir) / sourceFile.parent_path());
-
+ std::filesystem::create_directories(std::filesystem::path(settings.builddir) /
+ sourceDir.parent_path());
target_type = config.type;
source_language = source.language;
- std::filesystem::path base = sourceFile.parent_path();
- if(source.output.empty())
+ if(std::holds_alternative<ctor::GeneratorOneToOne>(config.function))
{
- std::cerr << "Missing output file for functional target\n";
- exit(1);
+ if(source.source_type == ctor::source_type::generated)
+ {
+ sourceFile = std::filesystem::path(settings.builddir);
+ }
+ sourceFile /= sourceDir / source.file;
+
+ std::filesystem::path base = sourceFile.parent_path();
+
+ if(source.output.empty())
+ {
+ std::cerr << "Missing target/output file for functional target.\n";
+ exit(1);
+ }
+ _targetFile = base / source.output;
}
+ else if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function))
+ {
+ for(const auto& src : config.sources)
+ {
+ std::filesystem::path _src;
+ if(src.source_type == ctor::source_type::generated)
+ {
+ _src = std::filesystem::path(settings.builddir);
+ }
+ _src /= sourceDir / src.file;
+ sources.push_back(_src.string());
+ }
- _targetFile = base / source.output;
+ std::filesystem::path base = sourceDir;
+ if(config.target.empty())
+ {
+ std::cerr << "Missing target file for functional target\n";
+ exit(1);
+ }
+ _targetFile = base / config.target;
+ sourceListFile = targetFile().parent_path() / targetFile().filename();
+ sourceListFile += ".sources";
+ }
}
bool TaskFn::dirtyInner()
{
- if(!std::filesystem::exists(sourceFile))
+ if(!std::filesystem::exists(targetFile()))
{
- //std::cout << "Missing source file: " << std::string(sourceFile) << "\n";
+ //std::cout << "Missing targetFile\n";
return true;
}
- if(!std::filesystem::exists(targetFile()))
+ if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function))
+ {
+ if(!std::filesystem::exists(sourceListFile))
+ {
+ //std::cout << "Missing sourceListFile\n";
+ return true;
+ }
+
+ {
+ auto lastSourceList = readFile(sourceListFile.string());
+ if(sourceListString() != lastSourceList)
+ {
+ //std::cout << "The compiler sourceList changed\n";
+ return true;
+ }
+ }
+ }
+
+ std::filesystem::file_time_type last_changed{};
+ bool missing{false};
+ if(std::holds_alternative<ctor::GeneratorOneToOne>(config.function))
+ {
+ if(!std::filesystem::exists(sourceFile))
+ {
+ missing = true;
+ }
+ last_changed = std::filesystem::last_write_time(sourceFile);
+ }
+ else if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function))
+ {
+ bool first{true};
+ for(const auto& source : sources)
+ {
+ if(!std::filesystem::exists(source))
+ {
+ missing |= true;
+ }
+ else
+ {
+ if(first)
+ {
+ last_changed = std::filesystem::last_write_time(source);
+ }
+ else
+ {
+ last_changed =
+ std::max(last_changed,
+ std::filesystem::last_write_time(source));
+ }
+ }
+ first = false;
+ }
+ }
+
+ if(missing)
{
- //std::cout << "Missing targetFile\n";
return true;
}
- if(std::filesystem::last_write_time(sourceFile) >
- std::filesystem::last_write_time(targetFile()))
+ if(last_changed > std::filesystem::last_write_time(targetFile()))
{
//std::cout << "The targetFile older than sourceFile\n";
return true;
@@ -61,10 +144,11 @@ bool TaskFn::dirtyInner()
int TaskFn::runInner()
{
- if(!std::filesystem::exists(sourceFile))
+ if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function))
{
- std::cout << "Missing source file: " << sourceFile.string() << "\n";
- return 1;
+ // Write sourceList to file.
+ std::ofstream sourceListStream(sourceListFile.string());
+ sourceListStream << sourceListString();
}
if(settings.verbose >= 0)
@@ -75,10 +159,27 @@ int TaskFn::runInner()
std::cout << output << std::flush;
}
- auto res = config.function(sourceFile.string(),
- targetFile().string(),
- config,
- settings);
+ int res{};
+ if(std::holds_alternative<std::monostate>(config.function))
+ {
+ }
+ else if(std::holds_alternative<ctor::GeneratorOneToOne>(config.function))
+ {
+ auto func = std::get<ctor::GeneratorOneToOne>(config.function);
+ res = func(sourceFile.string(),
+ targetFile().string(),
+ config,
+ settings);
+ }
+ else if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function))
+ {
+ auto func = std::get<ctor::GeneratorManyToOne>(config.function);
+ res = func(sources,
+ targetFile().string(),
+ config,
+ settings);
+ }
+
if(res != 0)
{
std::filesystem::remove(targetFile());
@@ -95,12 +196,34 @@ int TaskFn::clean()
std::filesystem::remove(targetFile());
}
+ if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function))
+ {
+ if(std::filesystem::exists(sourceListFile))
+ {
+ std::cout << "Removing " << sourceListFile.string() << "\n";
+ std::filesystem::remove(sourceListFile);
+ }
+ }
+
return 0;
}
std::vector<std::string> TaskFn::depends() const
{
- return {};
+ std::vector<std::string> deps;
+ if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function))
+ {
+ for(const auto& src : config.sources)
+ {
+ if(src.source_type == ctor::source_type::generated)
+ {
+ std::filesystem::path _src = std::filesystem::path(settings.builddir);
+ _src /= src.file;
+ deps.push_back(_src.string());
+ }
+ }
+ }
+ return deps;
}
std::string TaskFn::target() const
@@ -110,7 +233,17 @@ std::string TaskFn::target() const
std::filesystem::path TaskFn::targetFile() const
{
- return std::filesystem::path(settings.builddir) / sourceDir / _targetFile;
+ return std::filesystem::path(settings.builddir) / _targetFile;
+}
+
+std::string TaskFn::sourceListString() const
+{
+ std::string sourceListStr;
+ for(const auto& source : config.sources)
+ {
+ sourceListStr += " " + source.file;
+ }
+ return sourceListStr;
}
bool TaskFn::derived() const
diff --git a/src/task_fn.h b/src/task_fn.h
index 1bad32c..84b4c2a 100644
--- a/src/task_fn.h
+++ b/src/task_fn.h
@@ -28,6 +28,7 @@ public:
std::string target() const override;
std::filesystem::path targetFile() const override;
+ std::string sourceListString() const;
bool derived() const override;
std::string toJSON() const override;
@@ -37,8 +38,10 @@ public:
protected:
std::filesystem::path sourceFile;
std::filesystem::path _targetFile;
+ std::filesystem::path sourceListFile;
const ctor::build_configuration& config;
const ctor::settings& settings;
- std::filesystem::path sourceDir;
+
+ std::vector<std::string> sources;
};
diff --git a/src/task_ld.cc b/src/task_ld.cc
index a3f02d1..a1cff34 100644
--- a/src/task_ld.cc
+++ b/src/task_ld.cc
@@ -20,7 +20,6 @@ TaskLD::TaskLD(const ctor::build_configuration& config_,
: Task(config_, settings_, sourceDir_)
, config(config_)
, settings(settings_)
- , sourceDir(sourceDir_)
, is_self(is_self_)
{
target_type = config.type;
@@ -40,8 +39,8 @@ TaskLD::TaskLD(const ctor::build_configuration& config_,
objectFiles.push_back(objectFile);
dependsStr.push_back(objectFile.string());
}
-
- flagsFile = std::filesystem::path(settings.builddir) / cleanUp(sourceDir) / targetFile().stem();
+ auto cleaned_source_dir = cleanUp(sourceDir.string());
+ flagsFile = std::filesystem::path(settings.builddir) / cleaned_source_dir / targetFile().stem();
flagsFile += ".flags";
source_language = ctor::language::c;
diff --git a/src/task_ld.h b/src/task_ld.h
index 85f680a..9dce4b4 100644
--- a/src/task_ld.h
+++ b/src/task_ld.h
@@ -43,6 +43,5 @@ private:
const ctor::build_configuration& config;
const ctor::settings& settings;
- std::string sourceDir;
bool is_self;
};
diff --git a/src/tasks.cc b/src/tasks.cc
index 7de8af9..fb7d72b 100644
--- a/src/tasks.cc
+++ b/src/tasks.cc
@@ -85,7 +85,7 @@ std::vector<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration&
ctor::target_type target_type{config.type};
if(target_type == ctor::target_type::automatic)
{
- if(config.function != nullptr)
+ if(!std::holds_alternative<std::monostate>(config.function))
{
target_type = ctor::target_type::function;
}
@@ -114,12 +114,22 @@ std::vector<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration&
#ifndef BOOTSTRAP
else
{
- for(const auto& source : config.sources)
+ bool multi{std::holds_alternative<ctor::GeneratorManyToOne>(config.function)};
+ if(multi)
{
- auto task = std::make_shared<TaskFn>(config, settings, sourceDir, source);
+ auto task = std::make_shared<TaskFn>(config, settings, sourceDir, "");
tasks.push_back(task);
objects.push_back(task->target());
}
+ else
+ {
+ for(const auto& source : config.sources)
+ {
+ auto task = std::make_shared<TaskFn>(config, settings, sourceDir, source);
+ tasks.push_back(task);
+ objects.push_back(task->target());
+ }
+ }
}
#endif