summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2025-12-28 21:48:09 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2026-02-03 08:42:10 +0100
commitf2eb782080a74a7d789dea154e17e18cf5121af4 (patch)
tree64a3205616d496f335fd8fad3f0aaeb2aae67f42 /test
parentf66ab53b9380a5367e24727df620d6620ab031f7 (diff)
Diffstat (limited to 'test')
-rw-r--r--test/ctor.cc2
-rw-r--r--test/cycle_test.cc23
-rw-r--r--test/execute_test.cc5
-rw-r--r--test/generated_sources_test.cc40
-rw-r--r--test/suite/test.bat13
-rw-r--r--test/suite/test.cc18
-rwxr-xr-xtest/suite/test.sh2
-rw-r--r--test/testprog.cc38
-rw-r--r--test/tmpfile.h5
-rw-r--r--test/tools_test.cc3
10 files changed, 134 insertions, 15 deletions
diff --git a/test/ctor.cc b/test/ctor.cc
index 440ddfe..1201929 100644
--- a/test/ctor.cc
+++ b/test/ctor.cc
@@ -95,6 +95,7 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings)
ctor::cxx_flags{
"-std=c++20", "-O3", "-Wall",
"-I../src", "-Iuunit",
+ "-I../json/include",
"-DOUTPUT=\"deps\"",
"-fexceptions",
},
@@ -240,6 +241,7 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings)
ctor::cxx_flags{
"-std=c++20", "-O3", "-Wall",
"-I../src",
+ "-I../json/include",
"-fexceptions",
},
ctor::ld_flags{ "-pthread" },
diff --git a/test/cycle_test.cc b/test/cycle_test.cc
index 8f4c296..5b93e94 100644
--- a/test/cycle_test.cc
+++ b/test/cycle_test.cc
@@ -51,10 +51,25 @@ public:
const auto& tasks = getTasks(settings);
uASSERT_EQUAL(4u, tasks.size());
- uASSERT_EQUAL("target0"s, tasks[0]->target());
- uASSERT_EQUAL("target1"s, tasks[1]->target());
- uASSERT_EQUAL("target2"s, tasks[2]->target());
- uASSERT_EQUAL("target3"s, tasks[3]->target());
+ const auto& c = ctor::get_configuration();
+ std::string ext;
+ switch(c.build_arch)
+ {
+ case ctor::arch::unix:
+ case ctor::arch::apple:
+ ext = "";
+ break;
+ case ctor::arch::windows:
+ ext = ".exe";
+ break;
+ case ctor::arch::unknown:
+ break;
+ }
+
+ uASSERT_EQUAL("target0"s+ext, tasks[0]->target());
+ uASSERT_EQUAL("target1"s+ext, tasks[1]->target());
+ uASSERT_EQUAL("target2"s+ext, tasks[2]->target());
+ uASSERT_EQUAL("target3"s+ext, tasks[3]->target());
for(auto task : tasks)
{
diff --git a/test/execute_test.cc b/test/execute_test.cc
index f8f902f..3cdb309 100644
--- a/test/execute_test.cc
+++ b/test/execute_test.cc
@@ -23,8 +23,13 @@ public:
void return_value()
{
+#if defined(_WIN32)
+ constexpr int segfault_return_value = 3;
+ constexpr int exception_return_value = 0xC0000409;
+#else
constexpr int segfault_return_value = 11;
constexpr int exception_return_value = 6;
+#endif
ctor::settings s;
auto cur_path = std::filesystem::path(paths::argv_0).parent_path();
std::vector<std::string> paths{{cur_path.string()}};
diff --git a/test/generated_sources_test.cc b/test/generated_sources_test.cc
index 626a102..d4b8cdd 100644
--- a/test/generated_sources_test.cc
+++ b/test/generated_sources_test.cc
@@ -17,10 +17,26 @@ public:
uTEST(GeneratedSourcesTest::test_many_to_one_output);
}
+ std::string ext;
+
void setup()
{
// Make sure we start from a clean slate
getConfigFileList().clear();
+
+ const auto& c = ctor::get_configuration();
+ switch(c.build_arch)
+ {
+ case ctor::arch::unix:
+ case ctor::arch::apple:
+ ext = "";
+ break;
+ case ctor::arch::windows:
+ ext = ".exe";
+ break;
+ case ctor::arch::unknown:
+ break;
+ }
}
void test_custom_output()
@@ -44,9 +60,9 @@ public:
{"bar.y", ctor::output_file{"bar.cc"}},
},
ctor::GeneratorOneToOne([]([[maybe_unused]]const std::string& input,
- [[maybe_unused]]const std::string& output,
- [[maybe_unused]]const ctor::build_configuration& config,
- [[maybe_unused]]const ctor::settings& settings)
+ [[maybe_unused]]const std::string& output,
+ [[maybe_unused]]const ctor::build_configuration& config,
+ [[maybe_unused]]const ctor::settings& settings)
{
return 0;
}),
@@ -63,13 +79,14 @@ public:
bool found{false};
for(const auto& task : tasks)
{
- if(task->target() == "test1")
+ if(task->target() == "test1"+ext)
{
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());
+ uASSERT_EQUAL(std::filesystem::path("test/bar.x"),
+ std::filesystem::path(deps_foo_o[0]->source()));
found = true;
}
}
@@ -96,10 +113,10 @@ public:
{"bar.x"},
{"bar.y"},
},
- ctor::GeneratorManyToOne([](const std::vector<std::string>& input,
- const std::string& output,
- const ctor::build_configuration& config,
- const ctor::settings& settings)
+ ctor::GeneratorManyToOne([]([[maybe_unused]]const std::vector<std::string>& input,
+ [[maybe_unused]]const std::string& output,
+ [[maybe_unused]]const ctor::build_configuration& config,
+ [[maybe_unused]]const ctor::settings& settings)
{
return 0;
}),
@@ -116,13 +133,14 @@ public:
bool found{false};
for(const auto& task : tasks)
{
- if(task->target() == "test1")
+ if(task->target() == "test1"+ext)
{
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());
+ uASSERT_EQUAL(std::filesystem::path("test/bar.x"),
+ std::filesystem::path(deps_foo_o[0]->source()));
found = true;
}
}
diff --git a/test/suite/test.bat b/test/suite/test.bat
new file mode 100644
index 0000000..20f0846
--- /dev/null
+++ b/test/suite/test.bat
@@ -0,0 +1,13 @@
+@echo off
+
+set CXX=cl.exe
+set CC=cl.exe
+set AR=lib.exe
+set LD=link.exe
+set CTORDIR=..\..\build
+
+%CXX% /nologo /MT /std:c++20 /D_X86_ /EHsc test.cc /link /out:test.exe
+@if %errorlevel% neq 0 exit /b %errorlevel%
+
+test.exe
+@if %errorlevel% neq 0 exit /b %errorlevel%
diff --git a/test/suite/test.cc b/test/suite/test.cc
index b096a8b..3c7ce4a 100644
--- a/test/suite/test.cc
+++ b/test/suite/test.cc
@@ -21,8 +21,13 @@ int fail(int value = 1,
exit(value);
}
+#if _MSC_VER && !__INTEL_COMPILER
+const std::string ctor_exe{"ctor.exe"};
+const std::string obj_ext{".obj"};
+#else
const std::string ctor_exe{"./ctor"};
const std::string obj_ext{".o"};
+#endif
void run_ctor(const std::vector<std::string>& args,
const std::source_location location = std::source_location::current())
@@ -128,18 +133,28 @@ int main()
// Wipe the board
std::filesystem::remove_all(BUILDDIR);
+#if _MSC_VER && !__INTEL_COMPILER
+ std::filesystem::create_directory(BUILDDIR);
+#endif
std::filesystem::remove("configuration.cc");
std::filesystem::remove("config.h");
std::filesystem::remove(ctor_exe);
//////////////////////////////////////////////////////////////////////////////
// bootstrap
+ // TODO: add support for quoted strings with spaces
{
auto cxx_prog = locate(CXX, paths);
std::vector<std::string> args =
+#if _MSC_VER && !__INTEL_COMPILER
+ {"/nologo", "/MT", "/std:c++20", "/D_X86_", "/EHsc", "/I..\\..\\src",
+ "ctor.cc", "/link", "/LIBPATH:"+CTORDIR, "libctor.lib",
+ "/subsystem:console", "/out:" + ctor_exe};
+#else
{"-pthread", "-std=c++20", "-L", CTORDIR, "-lctor", "-I", "../../src",
"ctor.cc", "-o", ctor_exe};
+#endif
if(!CXXFLAGS.empty())
{
auto tokens = argsplit(CXXFLAGS);
@@ -168,8 +183,11 @@ int main()
//////////////////////////////////////////////////////////////////////////////
// check if source file changes are tracked
{
+#if _MSC_VER && !__INTEL_COMPILER
+#else
// No build files should have been created yet
assert_not_exists(BUILDDIR);
+#endif
// capture ctor binary before configure is called
Tracker ctor_bin(ctor_exe);
diff --git a/test/suite/test.sh b/test/suite/test.sh
index 4638c0d..8272247 100755
--- a/test/suite/test.sh
+++ b/test/suite/test.sh
@@ -1,4 +1,6 @@
#!/bin/bash
+#set -x
+
: ${CXX:=g++}
$CXX $LDFLAGS $CXXFLAGS -std=c++20 -Wall test.cc -o test && ./test
diff --git a/test/testprog.cc b/test/testprog.cc
index 93edc3f..18c2c74 100644
--- a/test/testprog.cc
+++ b/test/testprog.cc
@@ -5,6 +5,14 @@
extern char **environ;
+#if defined(_WIN32)
+#define WINDOWS_LEAN_AND_MEAN
+#include <windows.h>
+#undef max
+#else
+extern char **environ; // see 'man environ'
+#endif
+
int main(int argc, const char* argv[])
{
if(argc < 2)
@@ -20,11 +28,41 @@ int main(int argc, const char* argv[])
{
return 0;
}
+
std::ofstream ostrm(argv[2], std::ios::binary);
+ if(ostrm.bad())
+ {
+ std::cout << "Error: Could not write to " << argv[2] << "\n";
+ }
+#if defined(_WIN32)
+ auto env_strings = GetEnvironmentStrings();
+ const char* ptr = env_strings;
+ std::string env;
+ while(true)
+ {
+ if(*ptr == '\0')
+ {
+ if(env.empty())
+ {
+ // no more
+ break;
+ }
+ ostrm << env << "\n";
+ env.clear();
+ ++ptr;
+ continue;
+ }
+
+ env += *ptr;
+ ++ptr;
+ }
+ FreeEnvironmentStrings(env_strings);
+#else
for(auto current = environ; *current; ++current)
{
ostrm << (*current) << "\n";
}
+#endif
}
if(cmd == "retval")
diff --git a/test/tmpfile.h b/test/tmpfile.h
index 0f83a20..5887e36 100644
--- a/test/tmpfile.h
+++ b/test/tmpfile.h
@@ -17,7 +17,12 @@ public:
while(!fp)
{
filename = tmp_file_template.string() + std::to_string(counter++);
+ // TODO: Use std::fstream.open() with openmode noreplace when using c++23
+#if defined(_WIN32)
+ fopen_s(&fp, filename.data(), "wx");
+#else
fp = std::fopen(filename.data(), "wx");
+#endif
}
std::fwrite(data.data(), data.size(), 1, fp);
std::fclose(fp);
diff --git a/test/tools_test.cc b/test/tools_test.cc
index 5ae04c3..15270b3 100644
--- a/test/tools_test.cc
+++ b/test/tools_test.cc
@@ -22,6 +22,9 @@ std::ostream& operator<<(std::ostream& stream, const ctor::toolchain& toolchain)
case ctor::toolchain::clang:
stream << "ctor::toolchain::clang";
break;
+ case ctor::toolchain::msvc:
+ stream << "ctor::toolchain::msvc";
+ break;
}
return stream;
}