summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/ctor.cc64
-rw-r--r--test/source_type_test.cc42
-rw-r--r--test/suite/ctor_files/ctor.cc.bar18
-rw-r--r--test/suite/ctor_files/ctor.cc.base19
-rw-r--r--test/suite/ctor_files/ctor.cc.multi18
-rwxr-xr-xtest/suite/test.sh32
-rw-r--r--test/tasks_test.cc111
-rw-r--r--test/tools_test.cc930
8 files changed, 1116 insertions, 118 deletions
diff --git a/test/ctor.cc b/test/ctor.cc
index 6515c72..a2ad64d 100644
--- a/test/ctor.cc
+++ b/test/ctor.cc
@@ -1,16 +1,16 @@
// -*- c++ -*-
// Distributed under the BSD 2-Clause License.
// See accompanying file LICENSE for details.
-#include <libctor.h>
+#include <ctor.h>
namespace
{
-BuildConfigurations ctorTestConfigs()
+ctor::build_configurations ctorTestConfigs(const ctor::settings& settings)
{
return
{
{
- .type = TargetType::UnitTest,
+ .type = ctor::target_type::unit_test,
.target = "execute_test",
.sources = {
"execute_test.cc",
@@ -19,7 +19,7 @@ BuildConfigurations ctorTestConfigs()
},
.flags = {
.cxxflags = {
- "-std=c++20", "-O3", "-s", "-Wall", "-Werror",
+ "-std=c++20", "-O3", "-Wall", "-Werror",
"-I../src", "-Iuunit",
"-DOUTPUT=\"execute\"",
},
@@ -27,16 +27,16 @@ BuildConfigurations ctorTestConfigs()
},
},
{
- .type = TargetType::UnitTest,
+ .type = ctor::target_type::unit_test,
.target = "tasks_test",
.sources = {
"tasks_test.cc",
"testmain.cc",
},
- .depends = {"libctor.a"},
+ .depends = { "libctor_nomain.a" },
.flags = {
.cxxflags = {
- "-std=c++20", "-O3", "-s", "-Wall", "-Werror",
+ "-std=c++20", "-O3", "-Wall", "-Werror",
"-I../src", "-Iuunit",
"-DOUTPUT=\"tasks\"",
},
@@ -44,22 +44,66 @@ BuildConfigurations ctorTestConfigs()
},
},
{
- .type = TargetType::UnitTest,
+ .type = ctor::target_type::unit_test,
.target = "source_type_test",
.sources = {
"source_type_test.cc",
"testmain.cc",
},
- .depends = {"libctor.a"},
+ .depends = { "libctor_nomain.a" },
.flags = {
.cxxflags = {
- "-std=c++20", "-O3", "-s", "-Wall", "-Werror",
+ "-std=c++20", "-O3", "-Wall", "-Werror",
"-I../src", "-Iuunit",
"-DOUTPUT=\"source_type\"",
},
.ldflags = { "-pthread" },
},
},
+ {
+ .type = ctor::target_type::unit_test,
+ .target = "tools_test",
+ .sources = {
+ "tools_test.cc",
+ "testmain.cc",
+ "../src/tools.cc",
+ },
+ //.depends = { "libctor_nomain.a" },
+ .flags = {
+ .cxxflags = {
+ "-std=c++20", "-O3", "-Wall", "-Werror",
+ "-I../src", "-Iuunit",
+ "-DOUTPUT=\"tools\"",
+ },
+ },
+ },
+ {
+ .type = ctor::target_type::unit_test_library,
+ .target = "libctor_nomain.a",
+ .sources = {
+ "../src/build.cc",
+ "../src/configure.cc",
+ "../src/execute.cc",
+ "../src/rebuild.cc",
+ "../src/tasks.cc",
+ "../src/task.cc",
+ "../src/task_ar.cc",
+ "../src/task_cc.cc",
+ "../src/task_fn.cc",
+ "../src/task_ld.cc",
+ "../src/task_so.cc",
+ "../src/tools.cc",
+ "../src/util.cc",
+ "../src/externals_manual.cc",
+ },
+ .flags = {
+ .cxxflags = {
+ "-std=c++20", "-O3", "-Wall", "-Werror",
+ "-I../src",
+ },
+ .ldflags = { "-pthread" },
+ },
+ },
};
}
}
diff --git a/test/source_type_test.cc b/test/source_type_test.cc
index 47d820d..288f1e5 100644
--- a/test/source_type_test.cc
+++ b/test/source_type_test.cc
@@ -1,38 +1,40 @@
-#include <uunit.h>
-
-#include <libctor.h>
+#include <ctor.h>
#include <task_cc.h>
-#include <settings.h>
-std::ostream& operator<<(std::ostream& stream, const Language& lang)
+std::ostream& operator<<(std::ostream& stream, const ctor::language& lang);
+
+#include <uunit.h>
+
+std::ostream& operator<<(std::ostream& stream, const ctor::language& lang)
{
switch(lang)
{
- case Language::Auto:
- stream << "Language::Auto";
+ case ctor::language::automatic:
+ stream << "ctor::language::automatic";
break;
- case Language::C:
- stream << "Language::C";
+ case ctor::language::c:
+ stream << "ctor::language::c";
break;
- case Language::Cpp:
- stream << "Language::Cpp";
+ case ctor::language::cpp:
+ stream << "ctor::language::cpp";
break;
- case Language::Asm:
- stream << "Language::Asm";
+ case ctor::language::assembler:
+ stream << "ctor::language::assembler";
break;
}
return stream;
}
+
class TestableTaskCC
: public TaskCC
{
public:
- TestableTaskCC(const Source& source)
+ TestableTaskCC(const ctor::source& source)
: TaskCC({}, {}, "build", source)
{}
- Language language() const
+ ctor::language language() const
{
return source_language;
}
@@ -51,22 +53,22 @@ public:
{
{ // c++
TestableTaskCC task("hello.cc");
- uASSERT_EQUAL(Language::Cpp, task.language());
+ uASSERT_EQUAL(ctor::language::cpp, task.language());
}
{ // c
TestableTaskCC task("hello.c");
- uASSERT_EQUAL(Language::C, task.language());
+ uASSERT_EQUAL(ctor::language::c, task.language());
}
{ // asm
TestableTaskCC task("hello.s");
- uASSERT_EQUAL(Language::Asm, task.language());
+ uASSERT_EQUAL(ctor::language::assembler, task.language());
}
{ // custom/explicit language
- TestableTaskCC task( {"hello.foo", Language::Asm} );
- uASSERT_EQUAL(Language::Asm, task.language());
+ TestableTaskCC task( {"hello.foo", ctor::language::assembler} );
+ uASSERT_EQUAL(ctor::language::assembler, task.language());
}
// Note: Failure state will result in exit(1) so cannot be tested
diff --git a/test/suite/ctor_files/ctor.cc.bar b/test/suite/ctor_files/ctor.cc.bar
index 92456cb..218f9cc 100644
--- a/test/suite/ctor_files/ctor.cc.bar
+++ b/test/suite/ctor_files/ctor.cc.bar
@@ -1,12 +1,12 @@
// -*- c++ -*-
// Distributed under the BSD 2-Clause License.
// See accompanying file LICENSE for details.
-#include <libctor.h>
+#include <ctor.h>
//#include "config.h"
namespace
{
-BuildConfigurations ctorConfigs()
+ctor::build_configurations ctorConfigs(const ctor::settings& settings)
{
return
{
@@ -30,17 +30,19 @@ BuildConfigurations ctorConfigs()
};
}
-ExternalConfigurations ctorExtConfigs()
+ctor::external_configurations ctorExtConfigs(const ctor::settings& settings)
{
return
{
{
.name = "bar",
- .flags = {
- .cxxflags = { "-D_A_", "-DBAR"},
- .cflags = { "-D_B_" },
- .ldflags = { "-D_C_" },
- .asmflags = { "-D_D_" },
+ .external = ctor::external_manual{
+ .flags = {
+ .cflags = { "-D_B_" },
+ .cxxflags = { "-D_A_", "-DBAR"},
+ .ldflags = { "-D_C_" },
+ .asmflags = { "-D_D_" },
+ },
},
// Creates --with-foo-prefix arg to configure which will be used for
// -L and -I flags.
diff --git a/test/suite/ctor_files/ctor.cc.base b/test/suite/ctor_files/ctor.cc.base
index 6c60513..eab39c4 100644
--- a/test/suite/ctor_files/ctor.cc.base
+++ b/test/suite/ctor_files/ctor.cc.base
@@ -1,12 +1,12 @@
// -*- c++ -*-
// Distributed under the BSD 2-Clause License.
// See accompanying file LICENSE for details.
-#include <libctor.h>
+#include <ctor.h>
//#include "config.h"
namespace
{
-BuildConfigurations ctorConfigs()
+ctor::build_configurations ctorConfigs(const ctor::settings& settings)
{
return
{
@@ -30,17 +30,20 @@ BuildConfigurations ctorConfigs()
};
}
-ExternalConfigurations ctorExtConfigs()
+ctor::external_configurations ctorExtConfigs(const ctor::settings& settings)
{
return
{
{
.name = "bar",
- .flags = {
- .cxxflags = { "-D_A_", "-DFOO"},
- .cflags = { "-D_B_" },
- .ldflags = { "-D_C_" },
- .asmflags = { "-D_D_" },
+ .external = ctor::external_manual
+ {
+ .flags = {
+ .cflags = { "-D_B_" },
+ .cxxflags = { "-D_A_", "-DFOO"},
+ .ldflags = { "-D_C_" },
+ .asmflags = { "-D_D_" },
+ },
},
// Creates --with-foo-prefix arg to configure which will be used for
// -L and -I flags.
diff --git a/test/suite/ctor_files/ctor.cc.multi b/test/suite/ctor_files/ctor.cc.multi
index 9db2517..2b88afe 100644
--- a/test/suite/ctor_files/ctor.cc.multi
+++ b/test/suite/ctor_files/ctor.cc.multi
@@ -1,14 +1,14 @@
// -*- c++ -*-
// Distributed under the BSD 2-Clause License.
// See accompanying file LICENSE for details.
-#include <libctor.h>
+#include <ctor.h>
//#include "config.h"
#include "foobar.h"
namespace
{
-BuildConfigurations ctorConfigs()
+ctor::build_configurations ctorConfigs(const ctor::settings& settings)
{
return
{
@@ -32,17 +32,19 @@ BuildConfigurations ctorConfigs()
};
}
-ExternalConfigurations ctorExtConfigs()
+ctor::external_configurations ctorExtConfigs(const ctor::settings& settings)
{
return
{
{
.name = "bar",
- .flags = {
- .cxxflags = { "-D_A_", "-DFOO"},
- .cflags = { "-D_B_" },
- .ldflags = { "-D_C_" },
- .asmflags = { "-D_D_" },
+ .external = ctor::external_manual{
+ .flags = {
+ .cflags = { "-D_B_" },
+ .cxxflags = { "-D_A_", "-DFOO"},
+ .ldflags = { "-D_C_" },
+ .asmflags = { "-D_D_" },
+ },
},
// Creates --with-foo-prefix arg to configure which will be used for
// -L and -I flags.
diff --git a/test/suite/test.sh b/test/suite/test.sh
index c980154..c112351 100755
--- a/test/suite/test.sh
+++ b/test/suite/test.sh
@@ -1,4 +1,9 @@
#!/bin/bash
+: ${CXX:=g++}
+: ${CTORDIR:=../../build}
+: ${BUILDDIR:=build}
+
+CXX=$(which $CXX)
function fail
{
@@ -13,21 +18,22 @@ function ctor
}
# Wipe the board
-rm -Rf build
+rm -Rf ${BUILDDIR}
rm -f configuration.cc
rm -f ctor
+echo "** ctor_files/ctor.cc.base"
cp ctor_files/ctor.cc.base ctor.cc
# Compile bootstrap binary
-g++ -pthread -std=c++20 -L../../build -lctor -I../../src ctor.cc -o ctor || fail ${LINENO}
+$CXX -pthread -std=c++20 -L${CTORDIR} -lctor -I../../src ctor.cc -o ctor || fail ${LINENO}
# No build files should have been created yet
-[ -d build ] && fail ${LINENO}
+[ -d ${BUILDDIR} ] && fail ${LINENO}
# capture md5 sum of ctor binary before configure is called
MD5=`md5sum ctor`
-ctor configure --ctor-includedir ../../src --ctor-libdir ../../build
+ctor configure --ctor-includedir ../../src --ctor-libdir=${CTORDIR} --build-dir=${BUILDDIR}
# ctor should be rebuilt at this point, so md5 sum should have changed
(echo $MD5 | md5sum --status -c) && fail ${LINENO}
@@ -36,7 +42,7 @@ ctor configure --ctor-includedir ../../src --ctor-libdir ../../build
[ ! -f configuration.cc ] && fail ${LINENO}
# Shouldn't compile anything yet - only configure
-[ -f build/hello-hello_cc.o ] && fail ${LINENO}
+[ -f ${BUILDDIR}/hello-hello_cc.o ] && fail ${LINENO}
MD5=`md5sum ctor`
@@ -44,12 +50,12 @@ MD5=`md5sum ctor`
ctor -v
# Compiled object should now exist
-[ ! -f build/hello-hello_cc.o ] && fail ${LINENO}
+[ ! -f ${BUILDDIR}/hello-hello_cc.o ] && fail ${LINENO}
# ctor should not have been rebuilt, so md5 sum should be the same
(echo $MD5 | md5sum --status -c) || fail ${LINENO}
-MOD1=`stat -c %Y build/hello-hello_cc.o`
+MOD1=`stat -c %Y ${BUILDDIR}/hello-hello_cc.o`
touch hello.cc
sleep 1.1
@@ -57,10 +63,11 @@ sleep 1.1
ctor -v
# Object file should have been recompiled
-MOD2=`stat -c %Y build/hello-hello_cc.o`
+MOD2=`stat -c %Y ${BUILDDIR}/hello-hello_cc.o`
[[ $MOD1 == $MOD2 ]] && fail ${LINENO}
# Replacve -DFOO with -DBAR in foo external.cxxflags
+echo "** ctor_files/ctor.cc.bar"
cp ctor_files/ctor.cc.bar ctor.cc
MD5C=`md5sum configuration.cc`
@@ -71,22 +78,23 @@ sleep 1.1
# Run normally to reconfigure, rebuild ctor and rebuild hello.cc
ctor -v
-MOD2=`stat -c %Y build/hello-hello_cc.o`
+MOD2=`stat -c %Y ${BUILDDIR}/hello-hello_cc.o`
[[ $MOD1 == $MOD2 ]] && fail ${LINENO}
(echo $MD5C | md5sum --status -c) && fail ${LINENO}
(echo $MD5 | md5sum --status -c) && fail ${LINENO}
+echo "** ctor_files/ctor.cc.multi"
cp ctor_files/ctor.cc.multi ctor.cc
MD5C=`md5sum configuration.cc`
MD5=`md5sum ctor`
-MOD1=`stat -c %Y build/hello-hello_cc.o`
+MOD1=`stat -c %Y ${BUILDDIR}/hello-hello_cc.o`
sleep 1.1
# Run normally to reconfigure, rebuild ctor and rebuild hello.cc
ctor -v
-MOD2=`stat -c %Y build/hello-hello_cc.o`
+MOD2=`stat -c %Y ${BUILDDIR}/hello-hello_cc.o`
[[ $MOD1 == $MOD2 ]] && fail ${LINENO}
(echo $MD5C | md5sum --status -c) && fail ${LINENO}
(echo $MD5 | md5sum --status -c) && fail ${LINENO}
@@ -102,3 +110,5 @@ ctor -v
MOD2=`stat -c %Y ctor`
[[ $MOD1 == $MOD2 ]] && fail ${LINENO}
+
+exit 0
diff --git a/test/tasks_test.cc b/test/tasks_test.cc
index 8a15fcd..5f1db26 100644
--- a/test/tasks_test.cc
+++ b/test/tasks_test.cc
@@ -1,12 +1,11 @@
#include <uunit.h>
-#include <libctor.h>
+#include <ctor.h>
#include <tasks.h>
-#include <settings.h>
namespace
{
-BuildConfigurations ctorTestConfigs1()
+ctor::build_configurations ctorTestConfigs1(const ctor::settings&)
{
return
{
@@ -20,7 +19,7 @@ BuildConfigurations ctorTestConfigs1()
};
}
-BuildConfigurations ctorTestConfigs2()
+ctor::build_configurations ctorTestConfigs2(const ctor::settings&)
{
return
{
@@ -37,6 +36,19 @@ BuildConfigurations ctorTestConfigs2()
REG(ctorTestConfigs1);
REG(ctorTestConfigs2);
+std::size_t count(const std::set<std::shared_ptr<Task>>& tasks,
+ const std::string& name)
+{
+ auto cnt{0u};
+ for(const auto& task : tasks)
+ {
+ if(task->target() == name)
+ {
+ cnt++;
+ }
+ }
+ return cnt;
+}
class TestTask
: public Task
@@ -44,7 +56,7 @@ class TestTask
public:
TestTask(const std::string& name, bool dirty,
const std::vector<std::string>& deps = {})
- : Task({})
+ : Task({}, {}, {})
, task_name(name)
, task_dirty(dirty)
, task_deps(deps)
@@ -55,6 +67,7 @@ public:
int clean() override { return 0; }
std::vector<std::string> depends() const override { return task_deps; }
std::string target() const override { return task_name; }
+ std::filesystem::path targetFile() const override { return {}; }
bool derived() const override { return false; }
bool dirtyInner() override { return task_dirty; }
@@ -78,7 +91,7 @@ public:
void getTargets_test()
{
using namespace std::string_literals;
- Settings settings{};
+ ctor::settings settings{};
const auto& targets = getTargets(settings);
uASSERT_EQUAL(4u, targets.size());
@@ -96,34 +109,26 @@ public:
void getTasks_test()
{
using namespace std::string_literals;
- Settings settings{ .builddir = "foo" };
+ ctor::settings settings{ .builddir = "foo" };
{
auto tasks = getTasks(settings);
uASSERT_EQUAL(6u, tasks.size());
- auto task = tasks.begin();
- uASSERT_EQUAL("foo/test/target1-foo_cc.o"s, (*task)->target());
- task++;
- uASSERT_EQUAL("foo/test/target1-bar_c.o"s, (*task)->target());
- task++;
- uASSERT_EQUAL("foo/test/target1"s, (*task)->target());
- task++;
- uASSERT_EQUAL("foo/test/target2"s, (*task)->target());
- task++;
- uASSERT_EQUAL("foo/test/target3"s, (*task)->target());
- task++;
- uASSERT_EQUAL("foo/test/target4"s, (*task)->target());
+ // Note: count() is used here because the order of
+ // std::set<std::shared_ptr<T>> is not deterministic.
+ uASSERT_EQUAL(1u, count(tasks, "target1"s));
+ uASSERT_EQUAL(1u, count(tasks, "target2"s));
+ uASSERT_EQUAL(1u, count(tasks, "target3"s));
+ uASSERT_EQUAL(1u, count(tasks, "target4"s));
+ uASSERT_EQUAL(1u, count(tasks, "test/target1-foo_cc.o"s));
+ uASSERT_EQUAL(1u, count(tasks, "test/target1-bar_c.o"s));
}
{
auto tasks = getTasks(settings, {"target1", "target3"});
uASSERT_EQUAL(4u, tasks.size());
- auto task = tasks.begin();
- uASSERT_EQUAL("foo/test/target1-foo_cc.o"s, (*task)->target());
- task++;
- uASSERT_EQUAL("foo/test/target1-bar_c.o"s, (*task)->target());
- task++;
- uASSERT_EQUAL("foo/test/target1"s, (*task)->target());
- task++;
- uASSERT_EQUAL("foo/test/target3"s, (*task)->target());
+ uASSERT_EQUAL(1u, count(tasks, "target1"s));
+ uASSERT_EQUAL(1u, count(tasks, "target3"s));
+ uASSERT_EQUAL(1u, count(tasks, "test/target1-foo_cc.o"s));
+ uASSERT_EQUAL(1u, count(tasks, "test/target1-bar_c.o"s));
}
{
auto tasks = getTasks(settings, {"no-such-target"});
@@ -134,11 +139,11 @@ public:
void getNextTask_test()
{
using namespace std::string_literals;
- Settings settings{};
+ ctor::settings settings{};
{ // Zero (Empty)
- std::list<std::shared_ptr<Task>> allTasks;
- std::list<std::shared_ptr<Task>> dirtyTasks;
+ std::set<std::shared_ptr<Task>> allTasks;
+ std::set<std::shared_ptr<Task>> dirtyTasks;
for(auto& task : dirtyTasks)
{
@@ -151,10 +156,10 @@ public:
{ // Zero (One task, no dirty)
auto task1 = std::make_shared<TestTask>("task1", false);
- std::list<std::shared_ptr<Task>> allTasks;
- allTasks.push_back(task1);
+ std::set<std::shared_ptr<Task>> allTasks;
+ allTasks.insert(task1);
- std::list<std::shared_ptr<Task>> dirtyTasks;
+ std::set<std::shared_ptr<Task>> dirtyTasks;
for(auto& task : dirtyTasks)
{
@@ -167,11 +172,11 @@ public:
{ // One (One task, one dirty)
auto task1 = std::make_shared<TestTask>("task1", true);
- std::list<std::shared_ptr<Task>> allTasks;
- allTasks.push_back(task1);
+ std::set<std::shared_ptr<Task>> allTasks;
+ allTasks.insert(task1);
- std::list<std::shared_ptr<Task>> dirtyTasks;
- dirtyTasks.push_back(task1);
+ std::set<std::shared_ptr<Task>> dirtyTasks;
+ dirtyTasks.insert(task1);
for(auto& task : dirtyTasks)
{
@@ -186,12 +191,12 @@ public:
auto task1 = std::make_shared<TestTask>("task1", false);
auto task2 = std::make_shared<TestTask>("task2", true);
- std::list<std::shared_ptr<Task>> allTasks;
- allTasks.push_back(task1);
- allTasks.push_back(task2);
+ std::set<std::shared_ptr<Task>> allTasks;
+ allTasks.insert(task1);
+ allTasks.insert(task2);
- std::list<std::shared_ptr<Task>> dirtyTasks;
- dirtyTasks.push_back(task2);
+ std::set<std::shared_ptr<Task>> dirtyTasks;
+ dirtyTasks.insert(task2);
for(auto& task : dirtyTasks)
{
@@ -208,12 +213,12 @@ public:
std::vector<std::string> deps = {"task1"};
auto task2 = std::make_shared<TestTask>("task2", true, deps);
- std::list<std::shared_ptr<Task>> allTasks;
- allTasks.push_back(task1);
- allTasks.push_back(task2);
+ std::set<std::shared_ptr<Task>> allTasks;
+ allTasks.insert(task1);
+ allTasks.insert(task2);
- std::list<std::shared_ptr<Task>> dirtyTasks;
- dirtyTasks.push_back(task2);
+ std::set<std::shared_ptr<Task>> dirtyTasks;
+ dirtyTasks.insert(task2);
for(auto& task : dirtyTasks)
{
@@ -230,13 +235,13 @@ public:
std::vector<std::string> deps = {"task1"};
auto task2 = std::make_shared<TestTask>("task2", true, deps);
- std::list<std::shared_ptr<Task>> allTasks;
- allTasks.push_back(task2);
- allTasks.push_back(task1);
+ std::set<std::shared_ptr<Task>> allTasks;
+ allTasks.insert(task2);
+ allTasks.insert(task1);
- std::list<std::shared_ptr<Task>> dirtyTasks;
- dirtyTasks.push_back(task2);
- dirtyTasks.push_back(task1);
+ std::set<std::shared_ptr<Task>> dirtyTasks;
+ dirtyTasks.insert(task2);
+ dirtyTasks.insert(task1);
for(auto& task : dirtyTasks)
{
diff --git a/test/tools_test.cc b/test/tools_test.cc
new file mode 100644
index 0000000..7127b8d
--- /dev/null
+++ b/test/tools_test.cc
@@ -0,0 +1,930 @@
+#include <vector>
+#include <string>
+#include <ostream>
+#include <initializer_list>
+#include <cassert>
+
+#include <tools.h>
+
+std::ostream& operator<<(std::ostream& stream, const ctor::toolchain& toolchain)
+{
+ switch(toolchain)
+ {
+ case ctor::toolchain::none:
+ stream << "ctor::toolchain::none";
+ break;
+ case ctor::toolchain::any:
+ stream << "ctor::toolchain::any";
+ break;
+ case ctor::toolchain::gcc:
+ stream << "ctor::toolchain::gcc";
+ break;
+ case ctor::toolchain::clang:
+ stream << "ctor::toolchain::clang";
+ break;
+ }
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const std::vector<std::string>& vs)
+{
+ bool first{true};
+ stream << "{ ";
+ for(const auto& v : vs)
+ {
+ if(!first)
+ {
+ stream << ", ";
+ }
+ stream << "'" << v << "'";
+ first = false;
+ }
+ stream << " }";
+
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const ctor::c_flag& flag)
+{
+ stream << "{" << flag.opt << ", \"" << flag.arg << "\", " << flag.toolchain << "}";
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const ctor::cxx_flag& flag)
+{
+ stream << "{" << flag.opt << ", \"" << flag.arg << "\", " << flag.toolchain << "}";
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const ctor::ld_flag& flag)
+{
+ stream << "{" << flag.opt << ", \"" << flag.arg << "\", " << flag.toolchain << "}";
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const ctor::ar_flag& flag)
+{
+ stream << "{" << flag.opt << ", \"" << flag.arg << "\", " << flag.toolchain << "}";
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const ctor::asm_flag& flag)
+{
+ stream << "{" << flag.opt << ", \"" << flag.arg << "\", " << flag.toolchain << "}";
+ return stream;
+}
+
+bool operator!=(const ctor::c_flag& a, const ctor::c_flag& b)
+{
+ return
+ a.opt != b.opt ||
+ a.arg != b.arg ||
+ a.toolchain != b.toolchain;
+}
+
+bool operator!=(const ctor::cxx_flag& a, const ctor::cxx_flag& b)
+{
+ return
+ a.opt != b.opt ||
+ a.arg != b.arg ||
+ a.toolchain != b.toolchain;
+}
+bool operator!=(const ctor::ld_flag& a, const ctor::ld_flag& b)
+{
+ return
+ a.opt != b.opt ||
+ a.arg != b.arg ||
+ a.toolchain != b.toolchain;
+}
+
+bool operator!=(const ctor::ar_flag& a, const ctor::ar_flag& b)
+{
+ return
+ a.opt != b.opt ||
+ a.arg != b.arg ||
+ a.toolchain != b.toolchain;
+}
+bool operator!=(const ctor::asm_flag& a, const ctor::asm_flag& b)
+{
+ return
+ a.opt != b.opt ||
+ a.arg != b.arg ||
+ a.toolchain != b.toolchain;
+}
+
+#include <uunit.h>
+
+namespace {
+std::string conf_host_cxx{};
+std::string conf_build_cxx{};
+}
+
+const ctor::configuration& ctor::get_configuration()
+{
+ static ctor::configuration cfg;
+ return cfg;
+}
+
+const std::string& ctor::configuration::get(const std::string& key, const std::string& defval) const
+{
+ if(key == ctor::cfg::host_cxx)
+ {
+ return conf_host_cxx;
+ }
+
+ if(key == ctor::cfg::build_cxx)
+ {
+ return conf_build_cxx;
+ }
+
+ assert(false); // bad key
+
+ static std::string res{};
+ return res;
+}
+
+class ToolsTest
+ : public uUnit
+{
+public:
+ ToolsTest()
+ {
+ uTEST(ToolsTest::getToolChain_test);
+
+ uTEST(ToolsTest::getOption_toolchain_c_test);
+ uTEST(ToolsTest::getOption_toolchain_cxx_test);
+ uTEST(ToolsTest::getOption_toolchain_ld_test);
+ uTEST(ToolsTest::getOption_toolchain_ar_test);
+ uTEST(ToolsTest::getOption_toolchain_asm_test);
+
+ uTEST(ToolsTest::getOption_str_c_test);
+ uTEST(ToolsTest::getOption_str_cxx_test);
+ uTEST(ToolsTest::getOption_str_ld_test);
+ uTEST(ToolsTest::getOption_str_ar_test);
+ uTEST(ToolsTest::getOption_str_asm_test);
+
+ uTEST(ToolsTest::to_strings_c_test);
+ uTEST(ToolsTest::to_strings_cxx_test);
+ uTEST(ToolsTest::to_strings_ld_test);
+ uTEST(ToolsTest::to_strings_ar_test);
+ uTEST(ToolsTest::to_strings_asm_test);
+ }
+
+ void getToolChain_test()
+ {
+ uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/g++"));
+ uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/g++-10"));
+ uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/x86_64-pc-linux-gnu-g++-9.3.0"));
+ uASSERT_EQUAL(ctor::toolchain::clang, getToolChain("/usr/bin/clang++"));
+ uASSERT_EQUAL(ctor::toolchain::clang, getToolChain("/usr/bin/clang++-16"));
+ uASSERT_EQUAL(ctor::toolchain::clang, getToolChain("/usr/lib/llvm/16/bin/i686-pc-linux-gnu-clang++-16"));
+ }
+
+
+ void getOption_toolchain_c_test()
+ {
+ std::vector<std::string> exp;
+ std::vector<std::string> act;
+
+ //
+ // gcc
+ //
+ exp = { "-o", "foo" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::output, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-g" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::debug);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Wall" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::warn_all);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Werror" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::warnings_as_errors);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-MMD" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::generate_dep_tree);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-c" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::no_link);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Ifoo" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::include_path, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-std=foo" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::c_std, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Ofoo" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::optimization, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIC" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::position_independent_code);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIE" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::position_independent_executable);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-foo" };
+ act = c_option(ctor::toolchain::gcc, ctor::c_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // clang
+ //
+ exp = { "-o", "foo" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::output, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-g" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::debug);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Wall" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::warn_all);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Werror" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::warnings_as_errors);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-MMD" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::generate_dep_tree);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-c" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::no_link);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Ifoo" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::include_path, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-std=foo" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::c_std, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Ofoo" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::optimization, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIC" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::position_independent_code);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIE" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::position_independent_executable);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-foo" };
+ act = c_option(ctor::toolchain::clang, ctor::c_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // any
+ //
+ exp = { "{ctor::c_opt::output, \"foo\"}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::output, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::c_opt::debug}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::debug);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::c_opt::warn_all}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::warn_all);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::c_opt::warnings_as_errors}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::warnings_as_errors);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::c_opt::generate_dep_tree}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::generate_dep_tree);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::c_opt::no_link}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::no_link);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::c_opt::include_path, \"foo\"}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::include_path, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::c_opt::c_std, \"foo\"}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::c_std, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::c_opt::optimization, \"foo\"}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::optimization, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::c_opt::position_independent_code}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::position_independent_code);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::c_opt::position_independent_executable}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::position_independent_executable);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::c_opt::custom, \"-foo\"}" };
+ act = c_option(ctor::toolchain::any, ctor::c_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+ }
+
+ void getOption_toolchain_cxx_test()
+ {
+ std::vector<std::string> exp;
+ std::vector<std::string> act;
+
+ //
+ // gcc
+ //
+ exp = { "-o", "foo" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::output, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-g" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::debug);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Wall" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::warn_all);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Werror" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::warnings_as_errors);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-MMD" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::generate_dep_tree);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-c" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::no_link);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Ifoo" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::include_path, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-std=foo" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::cpp_std, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Ofoo" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::optimization, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIC" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::position_independent_code);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIE" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::position_independent_executable);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-foo" };
+ act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // clang
+ //
+ exp = { "-o", "foo" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::output, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-g" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::debug);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Wall" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::warn_all);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Werror" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::warnings_as_errors);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-MMD" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::generate_dep_tree);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-c" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::no_link);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Ifoo" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::include_path, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-std=foo" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::cpp_std, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Ofoo" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::optimization, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIC" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::position_independent_code);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIE" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::position_independent_executable);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-foo" };
+ act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // any
+ //
+ exp = { "{ctor::cxx_opt::output, \"foo\"}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::output, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::cxx_opt::debug}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::debug);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::cxx_opt::warn_all}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::warn_all);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::cxx_opt::warnings_as_errors}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::warnings_as_errors);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::cxx_opt::generate_dep_tree}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::generate_dep_tree);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::cxx_opt::no_link}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::no_link);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::cxx_opt::include_path, \"foo\"}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::include_path, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::cxx_opt::cpp_std, \"foo\"}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::cpp_std, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::cxx_opt::optimization, \"foo\"}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::optimization, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::cxx_opt::position_independent_code}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::position_independent_code);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::cxx_opt::position_independent_executable}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::position_independent_executable);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::cxx_opt::custom, \"-foo\"}" };
+ act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+ }
+
+ void getOption_toolchain_ld_test()
+ {
+ std::vector<std::string> exp;
+ std::vector<std::string> act;
+
+ //
+ // gcc
+ //
+ exp = { "-o", "foo" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::output, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-s" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::strip);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Wall" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::warn_all);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Werror" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::warnings_as_errors);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Lfoo" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::library_path, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-lfoo" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::link, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-std=foo" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::cpp_std, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-shared" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::build_shared);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-pthread" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::threads);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIC" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::position_independent_code);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIE" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::position_independent_executable);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-foo" };
+ act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // clang
+ //
+ exp = { "-o", "foo" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::output, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-s" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::strip);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Wall" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::warn_all);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Werror" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::warnings_as_errors);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-Lfoo" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::library_path, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-lfoo" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::link, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-std=foo" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::cpp_std, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-shared" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::build_shared);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-pthread" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::threads);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIC" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::position_independent_code);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-fPIE" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::position_independent_executable);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-foo" };
+ act = ld_option(ctor::toolchain::clang, ctor::ld_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // any
+ //
+ exp = { "{ctor::ld_opt::output, \"foo\"}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::output, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::ld_opt::strip}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::strip);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::ld_opt::warn_all}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::warn_all);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::ld_opt::warnings_as_errors}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::warnings_as_errors);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::ld_opt::library_path, \"foo\"}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::library_path, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::ld_opt::link, \"foo\"}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::link, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::ld_opt::cpp_std, \"foo\"}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::cpp_std, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::ld_opt::build_shared}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::build_shared);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::ld_opt::threads}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::threads);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::ld_opt::position_independent_code}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::position_independent_code);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::ld_opt::position_independent_executable}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::position_independent_executable);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "{ctor::ld_opt::custom, \"-foo\"}" };
+ act = ld_option(ctor::toolchain::any, ctor::ld_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+ }
+
+ void getOption_toolchain_ar_test()
+ {
+ std::vector<std::string> exp;
+ std::vector<std::string> act;
+
+ //
+ // gcc
+ //
+ exp = { "-r" };
+ act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::replace);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-s" };
+ act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::add_index);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-c" };
+ act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::create);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "foo" };
+ act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::output, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-foo" };
+ act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // clang
+ //
+ exp = { "-r" };
+ act = ar_option(ctor::toolchain::clang, ctor::ar_opt::replace);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-s" };
+ act = ar_option(ctor::toolchain::clang, ctor::ar_opt::add_index);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-c" };
+ act = ar_option(ctor::toolchain::clang, ctor::ar_opt::create);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "foo" };
+ act = ar_option(ctor::toolchain::clang, ctor::ar_opt::output, "foo");
+ uASSERT_EQUAL(exp, act);
+
+ exp = { "-foo" };
+ act = ar_option(ctor::toolchain::clang, ctor::ar_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // any
+ //
+ exp = { "{ctor::ar_opt::custom, \"-foo\"}" };
+ act = ar_option(ctor::toolchain::any, ctor::ar_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+}
+
+ void getOption_toolchain_asm_test()
+ {
+ std::vector<std::string> exp;
+ std::vector<std::string> act;
+
+ //
+ // gcc
+ //
+ exp = { "-foo" };
+ act = asm_option(ctor::toolchain::gcc, ctor::asm_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // clang
+ //
+ exp = { "-foo" };
+ act = asm_option(ctor::toolchain::clang, ctor::asm_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // any
+ //
+ exp = { "{ctor::asm_opt::custom, \"-foo\"}" };
+ act = asm_option(ctor::toolchain::any, ctor::asm_opt::custom, "-foo");
+ uASSERT_EQUAL(exp, act);
+ }
+
+
+ void getOption_str_c_test()
+ {
+ ctor::c_flag exp("");
+ ctor::c_flag act("");
+
+ //
+ // gcc
+ //
+ exp = { ctor::c_opt::include_path, "foo" };
+ act = c_option("-Ifoo", ctor::toolchain::gcc);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { ctor::c_opt::custom, "foo" };
+ act = c_option("foo", ctor::toolchain::gcc);
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // clang
+ //
+ exp = { ctor::c_opt::include_path, "foo" };
+ act = c_option("-Ifoo", ctor::toolchain::clang);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { ctor::c_opt::custom, "foo" };
+ act = c_option("foo", ctor::toolchain::clang);
+ uASSERT_EQUAL(exp, act);
+ }
+
+ void getOption_str_cxx_test()
+ {
+ ctor::cxx_flag exp("");
+ ctor::cxx_flag act("");
+
+ //
+ // gcc
+ //
+ exp = { ctor::cxx_opt::include_path, "foo" };
+ act = cxx_option("-Ifoo", ctor::toolchain::gcc);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { ctor::cxx_opt::custom, "foo" };
+ act = cxx_option("foo", ctor::toolchain::gcc);
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // clang
+ //
+ exp = { ctor::cxx_opt::include_path, "foo" };
+ act = cxx_option("-Ifoo", ctor::toolchain::clang);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { ctor::cxx_opt::custom, "foo" };
+ act = cxx_option("foo", ctor::toolchain::clang);
+ uASSERT_EQUAL(exp, act);
+ }
+
+ void getOption_str_ld_test()
+ {
+ ctor::ld_flag exp("");
+ ctor::ld_flag act("");
+
+ //
+ // gcc
+ //
+ exp = { ctor::ld_opt::library_path, "foo" };
+ act = ld_option("-Lfoo", ctor::toolchain::gcc);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { ctor::ld_opt::custom, "foo" };
+ act = ld_option("foo", ctor::toolchain::gcc);
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // clang
+ //
+ exp = { ctor::ld_opt::library_path, "foo" };
+ act = ld_option("-Lfoo", ctor::toolchain::clang);
+ uASSERT_EQUAL(exp, act);
+
+ exp = { ctor::ld_opt::custom, "foo" };
+ act = ld_option("foo", ctor::toolchain::clang);
+ uASSERT_EQUAL(exp, act);
+ }
+
+ void getOption_str_ar_test()
+ {
+ ctor::ar_flag exp("");
+ ctor::ar_flag act("");
+
+ //
+ // gcc
+ //
+ exp = { ctor::ar_opt::custom, "foo" };
+ act = ar_option("foo", ctor::toolchain::gcc);
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // clang
+ //
+ exp = { ctor::ar_opt::custom, "foo" };
+ act = ar_option("foo", ctor::toolchain::clang);
+ uASSERT_EQUAL(exp, act);
+ }
+
+ void getOption_str_asm_test()
+ {
+ ctor::asm_flag exp("");
+ ctor::asm_flag act("");
+
+ //
+ // gcc
+ //
+ exp = { ctor::asm_opt::custom, "foo" };
+ act = asm_option("foo", ctor::toolchain::gcc);
+ uASSERT_EQUAL(exp, act);
+
+ //
+ // clang
+ //
+ exp = { ctor::asm_opt::custom, "foo" };
+ act = asm_option("foo", ctor::toolchain::clang);
+ uASSERT_EQUAL(exp, act);
+ }
+
+
+ void to_strings_c_test()
+ {
+ std::vector<std::string> exp;
+ std::vector<std::string> act;
+
+ // Mismatching toolchain (required vs actual) results in no output
+ // otherwise to_strings is just a proxy for c_option
+ act = to_strings(ctor::toolchain::gcc, {ctor::toolchain::clang, ctor::c_opt::no_link});
+ uASSERT_EQUAL(exp, act);
+ }
+
+ void to_strings_cxx_test()
+ {
+ std::vector<std::string> exp;
+ std::vector<std::string> act;
+
+ // Mismatching toolchain (required vs actual) results in no output
+ // otherwise to_strings is just a proxy for cxx_option
+ act = to_strings(ctor::toolchain::gcc, {ctor::toolchain::clang, ctor::cxx_opt::no_link});
+ uASSERT_EQUAL(exp, act);
+ }
+
+ void to_strings_ld_test()
+ {
+ std::vector<std::string> exp;
+ std::vector<std::string> act;
+
+ // Mismatching toolchain (required vs actual) results in no output
+ // otherwise to_strings is just a proxy for ld_option
+ act = to_strings(ctor::toolchain::gcc, {ctor::toolchain::clang, ctor::ld_opt::strip});
+ uASSERT_EQUAL(exp, act);
+ }
+
+ void to_strings_ar_test()
+ {
+ std::vector<std::string> exp;
+ std::vector<std::string> act;
+
+ // Mismatching toolchain (required vs actual) results in no output
+ // otherwise to_strings is just a proxy for ar_option
+ act = to_strings(ctor::toolchain::gcc, {ctor::toolchain::clang, ctor::ar_opt::custom, "foo"});
+ uASSERT_EQUAL(exp, act);
+ }
+
+ void to_strings_asm_test()
+ {
+ std::vector<std::string> exp;
+ std::vector<std::string> act;
+
+ // Mismatching toolchain (required vs actual) results in no output
+ // otherwise to_strings is just a proxy for asm_option
+ act = to_strings(ctor::toolchain::gcc, {ctor::toolchain::clang, ctor::asm_opt::custom, "foo"});
+ uASSERT_EQUAL(exp, act);
+ }
+};
+
+// Registers the fixture into the 'registry'
+static ToolsTest test;