From 4aa3c169b0a716d56254dbda2ab2b90d1876e7ad Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Mon, 23 Dec 2024 12:14:46 +0100 Subject: WIP --- .gitmodules | 3 + Jenkinsfile | 25 +++ bootstrap.bat | 20 ++ bootstrap.sh | 2 +- clbootstrap.sh | 48 +++++ clrun.sh | 31 +++ ctor.cc | 21 ++ getopt-for-windows | 1 + src/bootstrap.cc | 2 +- src/configure.cc | 108 +++++++++- src/ctor.h | 31 ++- src/execute.cc | 189 ++++++++++++++++- src/libctor.cc | 3 +- src/rebuild.cc | 20 +- src/task.cc | 12 +- src/task_ar.cc | 3 +- src/task_cc.cc | 7 +- src/task_fn.cc | 2 +- src/task_ld.cc | 23 ++- src/task_so.cc | 3 +- src/tools.cc | 520 ++++++++++++++++++++++++++++++++++++++++++++--- src/tools.h | 15 +- src/util.cc | 54 ++++- test/ctor.cc | 52 ++++- test/execute_test.cc | 8 +- test/source_type_test.cc | 8 +- test/suite/test.sh | 2 + test/tasks_test.cc | 76 +++---- test/testprog.cc | 33 ++- test/tmpfile.h | 16 +- test/tools_test.cc | 315 ++++++++++++++-------------- 31 files changed, 1356 insertions(+), 297 deletions(-) create mode 100644 bootstrap.bat create mode 100755 clbootstrap.sh create mode 100755 clrun.sh create mode 160000 getopt-for-windows diff --git a/.gitmodules b/.gitmodules index c765825..edd12b8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "test/uunit"] path = test/uunit url = git://git.drumgizmo.org/uunit.git +[submodule "getopt-for-windows"] + path = getopt-for-windows + url = https://github.com/Chunde/getopt-for-windows.git diff --git a/Jenkinsfile b/Jenkinsfile index 290f412..3812aca 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -44,5 +44,30 @@ pipeline { } } //////////////////////////////////////////////////// + stage('Windows msvc') { + agent { label 'win10 && msvc' } + environment + { + VSDEVCMD="C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\Common7\\Tools\\VsDevCmd.bat" + } + steps { + echo 'Cleaning workspace ...' + bat 'git clean -d -x -f' + dir ('build/test') { + writeFile file:'dummy', text:'' + } + bat '"%VSDEVCMD%" && bootstrap.bat && snot.exe' + echo 'Testing (msvc) ...' + bat 'snot.exe check' + } + post { + always { + xunit(thresholds: [ skipped(failureThreshold: '0'), + failed(failureThreshold: '0') ], + tools: [ CppUnit(pattern: 'build/test/*.xml') ]) + } + } + } + //////////////////////////////////////////////////// } } diff --git a/bootstrap.bat b/bootstrap.bat new file mode 100644 index 0000000..e6f031a --- /dev/null +++ b/bootstrap.bat @@ -0,0 +1,20 @@ +set CXX=cl.exe +set CC=cl.exe +set AR=lib.exe +set LD=link.exe + +cl /nologo /MT /std:c++20 /D_X86_ /EHsc /Isrc /Fo:build\ ctor.cc src\bootstrap.cc /link /out:snot.exe +if %errorlevel% neq 0 exit /b %errorlevel% + +snot.exe +if %errorlevel% neq 0 exit /b %errorlevel% + +cl /nologo /std:c++20 /D_X86_ /EHsc /Isrc /Fo:build\ ctor.cc /c +if %errorlevel% neq 0 exit /b %errorlevel% +cl /nologo /std:c++20 /D_X86_ /EHsc /Isrc /Fo:build\test\ test\ctor.cc /c +if %errorlevel% neq 0 exit /b %errorlevel% +link /nologo build\libctor.lib build\ctor.obj build\test\ctor.obj /subsystem:console /out:snot.exe +if %errorlevel% neq 0 exit /b %errorlevel% + +snot.exe configure --ctor-includedir=src --ctor-libdir=build +if %errorlevel% neq 0 exit /b %errorlevel% diff --git a/bootstrap.sh b/bootstrap.sh index 9e8cdca..052d8b7 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -6,7 +6,7 @@ set -e CXX=$(which $CXX) echo "Bootstrapping..." -$CXX -std=c++20 -Wall -O3 -Isrc -pthread src/bootstrap.cc ctor.cc test/ctor.cc -o ctor +$CXX -std=c++20 -Wall -O3 -Isrc -pthread src/bootstrap.cc ctor.cc -o ctor ./ctor $CXX -std=c++20 -Wall -O3 -Isrc -pthread ctor.cc test/ctor.cc -L$BUILDDIR -lctor -o ctor ./ctor configure --ctor-includedir=src --ctor-libdir=$BUILDDIR --build-dir=$BUILDDIR diff --git a/clbootstrap.sh b/clbootstrap.sh new file mode 100755 index 0000000..47664d1 --- /dev/null +++ b/clbootstrap.sh @@ -0,0 +1,48 @@ +#!/bin/bash +set -e +set -x +export WINEDEBUG=-all + +export BASE='C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133' +export ONECORELIB="$BASE\lib\onecore\x86" +export WINEPATH="$BASE\bin\Hostx86\x86" +export INCLUDE="$BASE\include" +export UCRT="C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt" +export UCRTLIB="C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x86" +export UM="C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um" +export UMLIB="C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x86" +export SHARED="C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared" +echo Bootstrapping... + +export CL="/I\"$BASE\include\" /I\"$UCRT\" /I\"$UM\" /I\"$SHARED\" /link /LIBPATH:\"$UMLIB\" /LIBPATH:\"$ONECORELIB\" /LIBPATH:\"$UCRTLIB\"" +export LINK="/LIBPATH:\"$UMLIB\" /LIBPATH:\"$ONECORELIB\" /LIBPATH:\"$UCRTLIB\"" +export LIB="/LIBPATH:\"$UMLIB\" /LIBPATH:\"$ONECORELIB\" /LIBPATH:\"$UCRTLIB\"" + +# https://docs.microsoft.com/en-us/cpp/build/reference/cl-environment-variables?view=msvc-170 + +# set INCLUDE="$BASE\include";$UCRT;$UM;$SHARED +# set LIB= +# set LIBPATH=$UMLIB;$ONECORELIB;$UCRTLIB + +rm -Rf ctor.exe build/ configuration.cc +mkdir build +export CXX="cl.exe" +export CC="cl.exe" +export AR="lib.exe" +export LD="link.exe" + +wine cl /nologo /std:c++20 /D_X86_ /EHsc /Isrc /Fo:build/ ctor.cc src/bootstrap.cc /link /out:ctor.exe +#sleep 1 +wine ctor.exe +#sleep 1 +wine cl /nologo /std:c++20 /D_X86_ /EHsc /Isrc /Fo:build/ ctor.cc build/libctor.lib /link /subsystem:console /out:ctor.exe +#sleep 1 +wine ctor.exe configure --ctor-includedir=src --ctor-libdir=build +#sleep 1 + +#exit 0 + +wine ctor.exe -a test/ctor.cc +#sleep 1 +wine ctor.exe -v check +#sleep 1 diff --git a/clrun.sh b/clrun.sh new file mode 100755 index 0000000..d2e57f3 --- /dev/null +++ b/clrun.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -e +set -x +export WINEDEBUG=-all + +rm -f ~/.wine/drive_c/number + +export BASE='C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133' +export ONECORELIB="$BASE\lib\onecore\x86" +export WINEPATH="$BASE\bin\Hostx86\x86" +export INCLUDE="$BASE\include" +export UCRT="C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt" +export UCRTLIB="C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x86" +export UM="C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um" +export UMLIB="C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x86" +export SHARED="C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared" + +export CL="/I\"$BASE\include\" /I\"$UCRT\" /I\"$UM\" /I\"$SHARED\" /link /LIBPATH:\"$UMLIB\" /LIBPATH:\"$ONECORELIB\" /LIBPATH:\"$UCRTLIB\"" +export LINK="/LIBPATH:\"$UMLIB\" /LIBPATH:\"$ONECORELIB\" /LIBPATH:\"$UCRTLIB\"" +export LIB="/LIBPATH:\"$UMLIB\" /LIBPATH:\"$ONECORELIB\" /LIBPATH:\"$UCRTLIB\"" + +export CXX="cl.exe" +export CC="cl.exe" +export AR="lib.exe" +export LD="link.exe" + + +#wine ctor.exe + +$* + diff --git a/ctor.cc b/ctor.cc index 92135c2..8f40a7a 100644 --- a/ctor.cc +++ b/ctor.cc @@ -29,8 +29,23 @@ ctor::build_configurations ctorConfigs(const ctor::settings& settings) "src/tools.cc", "src/util.cc", "src/unittest.cc", + {ctor::toolchain::msvc, "getopt-for-windows/getopt.c"}, }, .flags = { + .cflags = { + "-O3", +// "-g", +// "-Wall", +// "-Wconversion", +// "-Wextra", + //"-Werror", + "-Isrc", + {ctor::toolchain::msvc, ctor::c_opt::custom, "/Igetopt-for-windows"}, + {ctor::toolchain::msvc, ctor::c_opt::custom, "/D_X86_"}, + {ctor::toolchain::msvc, ctor::c_opt::custom, "/EHsc"}, + {ctor::toolchain::msvc, ctor::c_opt::custom, "/external:W0"}, + {ctor::toolchain::msvc, ctor::c_opt::custom, "/D_CRT_SECURE_NO_WARNINGS"}, + }, .cxxflags = { "-std=c++20", "-O3", @@ -42,6 +57,12 @@ ctor::build_configurations ctorConfigs(const ctor::settings& settings) "-Wconversion", // "-Wnrvo", "-Isrc", + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/Igetopt-for-windows"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/D_X86_"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/EHsc"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/external:W0"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/D_CRT_SECURE_NO_WARNINGS"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/Dstrdup=_strdup"}, }, }, } diff --git a/getopt-for-windows b/getopt-for-windows new file mode 160000 index 0000000..76fe2df --- /dev/null +++ b/getopt-for-windows @@ -0,0 +1 @@ +Subproject commit 76fe2df86f84771775fd2f1a641a09adbce28df7 diff --git a/src/bootstrap.cc b/src/bootstrap.cc index 471c844..0ed2b70 100644 --- a/src/bootstrap.cc +++ b/src/bootstrap.cc @@ -41,7 +41,7 @@ bool ctor::configuration::has(const std::string& key) const return false; } -const std::string& ctor::configuration::get(const std::string& key, const std::string& default_value) const +std::string ctor::configuration::get(const std::string& key, const std::string& default_value) const { auto cxx_env = std::getenv("CXX"); if(key == ctor::cfg::build_cxx && cxx_env) diff --git a/src/configure.cc b/src/configure.cc index 995e340..d2c1053 100644 --- a/src/configure.cc +++ b/src/configure.cc @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include @@ -25,17 +27,49 @@ const std::filesystem::path configHeaderFile("config.h"); std::map external_includedir; std::map external_libdir; +#if !defined(_WIN32) const ctor::configuration& __attribute__((weak)) ctor::get_configuration() +#else +const ctor::configuration& default_get_configuration() +#endif { static ctor::configuration cfg; static bool initialised{false}; if(!initialised) { - cfg.build_toolchain = getToolChain(cfg.get(ctor::cfg::build_cxx, "/usr/bin/g++")); + std::string cxx_prog{"g++"}; + auto cxx_env = getenv("CXX"); + if(cxx_env) + { + cxx_prog = cxx_env; + } + + cfg.build_toolchain = getToolChain(cfg.get(ctor::cfg::build_cxx, cxx_prog)); initialised = true; } return cfg; } +#if defined(_WIN32) +// Hack to make ctor::get_configuration "weak" linked +// See: +// https://stackoverflow.com/questions/2290587/gcc-style-weak-linking-in-visual-studio +// and +// https://stackoverflow.com/questions/11849853/how-to-list-functions-present-in-object-file +#pragma comment(linker, "/alternatename:?get_configuration@ctor@@YAABUconfiguration@1@XZ=?default_get_configuration@@YAABUconfiguration@ctor@@XZ") + +/* + +?get_configuration@ctor@@YAABUconfiguration@1@XZ +??__Fcfg@?1??get_configuration@ctor@@YAABUconfiguration@1@XZ@YAXXZ + += + +?default_get_configuration@@YAABUconfiguration@ctor@@XZ +??__Fcfg@?1??default_get_configuration@@YAABUconfiguration@ctor@@XZ@YAXXZ + +*/ +//#pragma comment(linker, "/alternatename:??__Fcfg@?1??get_configuration@ctor@@YAABUconfiguration@1@XZ@YAXXZ=??__Fcfg@?1??default_get_configuration@@YAABUconfiguration@ctor@@XZ@YAXXZ") +#endif namespace ctor { std::optional includedir; @@ -69,7 +103,7 @@ bool ctor::configuration::has(const std::string& key) const return tools.find(key) != tools.end(); } -const std::string& ctor::configuration::get(const std::string& key, const std::string& default_value) const +std::string ctor::configuration::get(const std::string& key, const std::string& default_value) const { if(key == ctor::cfg::ctor_includedir && ctor::includedir) { @@ -91,11 +125,47 @@ const std::string& ctor::configuration::get(const std::string& key, const std::s return ctor::conf_values[key]; } - if(has(key)) + if(tools.find(key) != tools.end()) { return tools.at(key); } + if(key == ctor::cfg::build_cxx) + { + auto e = std::getenv("CXX"); + if(e) + { + return e; + } + } + + if(key == ctor::cfg::build_cc) + { + auto e = std::getenv("CC"); + if(e) + { + return e; + } + } + + if(key == ctor::cfg::build_ld) + { + auto e = std::getenv("LD"); + if(e) + { + return e; + } + } + + if(key == ctor::cfg::build_ar) + { + auto e = std::getenv("AR"); + if(e) + { + return e; + } + } + return default_value; } @@ -136,6 +206,9 @@ std::ostream& operator<<(std::ostream& stream, const ctor::toolchain& toolchain) case ctor::toolchain::gcc: stream << "ctor::toolchain::gcc"; break; + case ctor::toolchain::msvc: + stream << "ctor::toolchain::msvc"; + break; case ctor::toolchain::clang: stream << "ctor::toolchain::clang"; break; @@ -358,13 +431,12 @@ int regenerateCache(ctor::settings& settings, opt.add("help", no_argument, 'h', "Print this help text.", - [&]() { + [&]() -> int { std::cout << "Configure how to build with " << name << "\n"; std::cout << "Usage: " << name << " configure [options]\n\n"; std::cout << "Options:\n"; opt.help(); exit(0); - return 0; }); opt.process(static_cast(vargs.size()), vargs.data()); @@ -651,6 +723,7 @@ int regenerateCache(ctor::settings& settings, { ctor::conf_values[ctor::cfg::builddir] = builddir; } + ctor::conf_values[ctor::cfg::host_cxx] = host_cxx; ctor::conf_values[ctor::cfg::build_cxx] = build_cxx; @@ -863,6 +936,31 @@ int configure(const ctor::settings& global_settings, int argc, char* argv[]) env["PATH"] = path_env; } + // Env vars for msvc + auto cl_env = getenv("CL"); + if(cl_env) + { + env["CL"] = cl_env; + } + + auto lib_env = getenv("LIB"); + if(lib_env) + { + env["LIB"] = lib_env; + } + + auto link_env = getenv("LINK"); + if(link_env) + { + env["LINK"] = link_env; + } + + auto include_env = getenv("INCLUDE"); + if(include_env) + { + env["INCLUDE"] = include_env; + } + auto ret = regenerateCache(settings, args_span[0], args, env); if(ret != 0) { diff --git a/src/ctor.h b/src/ctor.h index e0e2bef..3d963b3 100644 --- a/src/ctor.h +++ b/src/ctor.h @@ -59,6 +59,7 @@ enum class toolchain none, gcc, clang, + msvc, }; struct source @@ -90,6 +91,9 @@ enum class cxx_opt output, // -o debug, // -g warn_all, // -Wall + warn_conversion, // -Wconversion + warn_shadow, // -Wshadow + warn_extra, // -Wextra warnings_as_errors, // -Werror generate_dep_tree, // -MMD no_link, // -c @@ -98,6 +102,7 @@ enum class cxx_opt optimization, // -O position_independent_code, // -fPIC position_independent_executable, // -fPIE + define, // -D[=] custom, // entire option taken verbatim from }; @@ -107,6 +112,9 @@ enum class c_opt output, // -o debug, // -g warn_all, // -Wall + warn_conversion, // -Wconversion + warn_shadow, // -Wshadow + warn_extra, // -Wextra warnings_as_errors, // -Werror generate_dep_tree, // -MMD no_link, // -c @@ -115,6 +123,7 @@ enum class c_opt optimization, // -O position_independent_code, // -fPIC position_independent_executable, // -fPIE + define, // -D[=] custom, // entire option taken verbatim from }; @@ -159,15 +168,21 @@ public: flag(std::string_view str); flag(const char* str); flag(T opt_) : opt(opt_) {} - flag(T opt_, std::string_view arg_) : opt(opt_), arg(arg_) {} - flag(T opt_, const char* arg_) : opt(opt_), arg(arg_) {} - flag(ctor::toolchain toolchain_, T opt_) : toolchain(toolchain_), opt(opt_) {} - flag(ctor::toolchain toolchain_, T opt_, const char* arg_) : toolchain(toolchain_), opt(opt_), arg(arg_) {} - flag(ctor::toolchain toolchain_, T opt_, std::string_view arg_) : toolchain(toolchain_), opt(opt_), arg(arg_) {} + flag(T opt_, std::string_view arg_, std::string_view arg2_ = "") + : opt(opt_), arg(arg_), arg2(arg2_) {} + flag(T opt_, const char* arg_, const char* arg2_ = "") + : opt(opt_), arg(arg_), arg2(arg2_) {} + flag(ctor::toolchain toolchain_, T opt_) + : toolchain(toolchain_), opt(opt_) {} + flag(ctor::toolchain toolchain_, T opt_, const char* arg_, const char* arg2_ = "") + : toolchain(toolchain_), opt(opt_), arg(arg_), arg2(arg2_) {} + flag(ctor::toolchain toolchain_, T opt_, std::string_view arg_, std::string_view arg2_ = "") + : toolchain(toolchain_), opt(opt_), arg(arg_), arg2(arg2_) {} ctor::toolchain toolchain{ctor::toolchain::any}; T opt{}; std::string arg; + std::string arg2; }; using c_flag = ctor::flag; @@ -253,12 +268,12 @@ namespace cfg constexpr auto builddir = "builddir"; constexpr auto host_cc = "host-cc"; -constexpr auto host_cxx = "host-cpp"; +constexpr auto host_cxx = "host-cxx"; constexpr auto host_ar = "host-ar"; constexpr auto host_ld = "host-ld"; constexpr auto build_cc = "build-cc"; -constexpr auto build_cxx = "build-cpp"; +constexpr auto build_cxx = "build-cxx"; constexpr auto build_ar = "build-ar"; constexpr auto build_ld = "build-ld"; @@ -269,7 +284,7 @@ constexpr auto ctor_libdir = "ctor-libdir"; struct configuration { bool has(const std::string& key) const; - const std::string& get(const std::string& key, const std::string& default_value = {}) const; + std::string get(const std::string& key, const std::string& default_value = {}) const; ctor::toolchain host_toolchain{ctor::toolchain::none}; ctor::arch host_arch{ctor::arch::unknown}; diff --git a/src/execute.cc b/src/execute.cc index cbae899..49d202c 100644 --- a/src/execute.cc +++ b/src/execute.cc @@ -5,12 +5,22 @@ #include "ctor.h" -#include -#include -#include -#include -#include +#if !defined(_WIN32) + #include + #include + #include + #include +#else + #define WINDOWS_LEAN_AND_MEAN + #include + #undef max +#endif + #include +#include +#include +#include +#include /* https://blog.famzah.net/2009/11/20/a-much-faster-popen-and-system-implementation-for-linux/ @@ -30,7 +40,11 @@ public: { for(const auto& arg : args) { +#if !defined(_WIN32) push_back(strdup(arg.data())); +#else + push_back(_strdup(arg.data())); +#endif } push_back(nullptr); } @@ -44,6 +58,7 @@ public: } }; +#if !defined(_WIN32) int parent_waitpid(pid_t pid) { int status{}; @@ -55,6 +70,7 @@ int parent_waitpid(pid_t pid) return WEXITSTATUS(status); } +#endif //_WIN32 } // namespace :: extern char **environ; // see 'man environ' @@ -92,6 +108,8 @@ int execute(const ctor::settings& settings, std::cout << cmd << std::endl; } +#if !defined(_WIN32) + #if 1 auto pid = vfork(); if(pid == 0) @@ -133,5 +151,166 @@ int execute(const ctor::settings& settings, return system(cmd.data()); #endif +#else // _WIN32 + std::map new_env; + { + auto env_strings = GetEnvironmentStrings(); + const char* ptr = env_strings; + std::string key; + std::string value; + bool key_state{true}; + while(true) + { + if(key_state) // searching for key + { + if(*ptr == '\0') + { + break; + } + + if(*ptr != '=') + { + key += *ptr; + } + else + { + key_state = false; + } + } + else + { + if(*ptr != '\0') + { + value += *ptr; + } + else + { + new_env.insert({key, value}); + key = {}; + value = {}; + key_state = true; + } + } + ++ptr; + } + FreeEnvironmentStrings(env_strings); + } + + // add new env vars (if any) + for(const auto& [key, value] : env) + { + //if(key == "CL" || key == "LINK" || key == "LIB") + { + new_env[key] = value; + } + } + + std::string env_str; + for(const auto& [k,v] : new_env) + { + env_str += k + "=" + v; + env_str += '\0'; + } + env_str += '\0'; + + STARTUPINFO si{}; +// si.hStdInput = GetStdHandle(((DWORD)-10)/*STD_INPUT_HANDLE*/); +// si.hStdOutput = GetStdHandle(((DWORD)-11)/*STD_OUTPUT_HANDLE*/); +// si.hStdError = GetStdHandle(((DWORD)-12)/*STD_ERROR_HANDLE*/); +// si.dwFlags = /*STARTF_USESTDHANDLES*/0x00000100; + + PROCESS_INFORMATION pi{}; + + si.cb = sizeof(si); + + // TODO: Use SetDllDirectory(...) to set DLL search directory + + if(terminate) + { + char tmpdir[MAX_PATH+1]; + int cnt{0}; + + // The returned string ends with a backslash + if(GetTempPathA(sizeof(tmpdir), tmpdir) == 0) + { + std::cerr << "Could not read TMP folder\n"; + return GetLastError(); + } + + char source[MAX_PATH]; + HMODULE module = GetModuleHandle(0); + GetModuleFileNameA(module, source, MAX_PATH); + + while(true) + { + if(cnt > 10) // If we need to try more than 10 times something is wrong + { + return 1; + } + + std::filesystem::path tmp_file = settings.builddir; + tmp_file /= "tmp"; + std::string target = tmp_file.string() + "-" + std::to_string(cnt); + std::cout << "move " << source << " => " << target < int { std::cout << "Usage: " << args[0] << " [options] [target] ...\n"; std::cout << R"_( where target can be either: @@ -174,7 +174,6 @@ Options: )_"; opt.help(); exit(0); - return 0; }); opt.process(argc, argv); diff --git a/src/rebuild.cc b/src/rebuild.cc index 1db5e83..865a45b 100644 --- a/src/rebuild.cc +++ b/src/rebuild.cc @@ -38,7 +38,10 @@ int reg(ctor::build_configurations (*cb)(const ctor::settings&), { auto pwd = std::filesystem::current_path(); auto rel = std::filesystem::relative(loc, pwd); - configFiles[numConfigFiles].file = strdup(rel.string().data()); // NOTE: This intentionally leaks memory + auto str = rel.string(); + auto file = new char[str.size() + 1]; + strncpy(file, str.data(), str.size() + 1); + configFiles[numConfigFiles].file = file; // NOTE: This intentionally leaks memory } else { @@ -71,7 +74,7 @@ int reg(const char* location) int unreg(const char* location) { - std::size_t found{0}; + int found{0}; for(std::size_t i = 0; i < numConfigFiles;) { if(std::string(location) == configFiles[i].file) @@ -169,6 +172,8 @@ bool recompileCheck(const ctor::settings& global_settings, int argc, char* argv[ config.flags.cxxflags.emplace_back(ctor::cxx_opt::optimization, "3"); config.flags.cxxflags.emplace_back(ctor::cxx_opt::cpp_std, "c++20"); + config.flags.cxxflags.push_back({ctor::toolchain::msvc, ctor::cxx_opt::custom, "/EHsc"}); + const auto& c = ctor::get_configuration(); if(c.has(ctor::cfg::ctor_includedir)) { @@ -180,13 +185,20 @@ bool recompileCheck(const ctor::settings& global_settings, int argc, char* argv[ config.flags.ldflags.emplace_back(ctor::ld_opt::library_path, c.get(ctor::cfg::ctor_libdir)); } - config.flags.ldflags.emplace_back(ctor::ld_opt::link, "ctor"); + config.flags.ldflags.emplace_back(ctor::toolchain::msvc, ctor::ld_opt::link, "libctor.lib"); + config.flags.ldflags.emplace_back(ctor::toolchain::gcc, ctor::ld_opt::link, "ctor"); + config.flags.ldflags.emplace_back(ctor::toolchain::clang, ctor::ld_opt::link, "ctor"); config.flags.ldflags.emplace_back(ctor::ld_opt::strip); config.flags.ldflags.emplace_back(ctor::ld_opt::threads); + config.flags.ldflags.push_back({ctor::toolchain::msvc, ctor::ld_opt::custom, "/subsystem:console"}); + ctor::settings settings{global_settings}; settings.verbose = -1; // Make check completely silent. - settings.builddir += "/ctor"; // override builddir to use ctor subdir + + // override builddir to use ctor subdir + auto ctor_builddir = std::filesystem::path(settings.builddir) / "ctor"; + settings.builddir = ctor_builddir.string(); { std::filesystem::path buildfile = settings.builddir; diff --git a/src/task.cc b/src/task.cc index a9c0fee..ef7731b 100644 --- a/src/task.cc +++ b/src/task.cc @@ -3,7 +3,6 @@ // See accompanying file LICENSE for details. #include "task.h" -#include #include #include #include @@ -46,11 +45,14 @@ int Task::registerDepTasks(const std::vector>& tasks) bool Task::operator==(const std::string& depStr) { + std::filesystem::path generated_output = sourceDir; + generated_output /= target(); return - name() == depStr || - target() == depStr || - sourceDir + "/" + target() == depStr || - targetFile().string() == depStr + (!derived() && name() == depStr) || // compare to name + (!derived() && config.target == depStr) || // compare to stated target (ex. foo.a) + target() == depStr || // compare to derived (derived to foo.lib on msvc) + generated_output == depStr || // not sure what this is for?! + targetFile().string() == depStr // compare to target output file ; } diff --git a/src/task_ar.cc b/src/task_ar.cc index b16a2f9..406dbdb 100644 --- a/src/task_ar.cc +++ b/src/task_ar.cc @@ -93,6 +93,8 @@ int TaskAR::runInner() append(args, ar_option(toolchain, ctor::ar_opt::add_index)); append(args, ar_option(toolchain, ctor::ar_opt::create)); append(args, ar_option(toolchain, ctor::ar_opt::output, targetFile().string())); + append(args, to_strings(toolchain, {ctor::toolchain::msvc, ctor::ar_opt::custom, "/nologo"})); + for(const auto& task : getDependsTasks()) { args.push_back(task->targetFile().string()); @@ -188,7 +190,6 @@ std::string TaskAR::flagsString() const flagsStr += str; } } - flagsStr += "\n"; for(const auto& dep : config.depends) { diff --git a/src/task_cc.cc b/src/task_cc.cc index e1f3023..ad62763 100644 --- a/src/task_cc.cc +++ b/src/task_cc.cc @@ -275,18 +275,21 @@ std::vector TaskCC::flags() const { append(flags, to_strings(toolchain, flag)); } + append(flags, to_strings(toolchain, {ctor::toolchain::msvc, ctor::c_opt::custom, "/nologo"})); return flags; case ctor::language::cpp: for(const auto& flag : config.flags.cxxflags) { append(flags, to_strings(toolchain, flag)); } + append(flags, to_strings(toolchain, {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/nologo"})); return flags; default: std::cerr << "Unknown CC target type\n"; exit(1); break; } + } std::string TaskCC::flagsString() const @@ -310,7 +313,7 @@ std::vector TaskCC::getCompilerArgs() const { case ctor::language::c: { - append(args, c_option(toolchain, ctor::c_opt::generate_dep_tree)); + append(args, c_option(toolchain, ctor::c_opt::generate_dep_tree, depsFile.string())); if(std::filesystem::path(config.target).extension() == ".so") { @@ -352,7 +355,7 @@ std::vector TaskCC::getCompilerArgs() const case ctor::language::cpp: { - append(args, cxx_option(toolchain, ctor::cxx_opt::generate_dep_tree)); + append(args, cxx_option(toolchain, ctor::cxx_opt::generate_dep_tree, depsFile.string())); if(std::filesystem::path(config.target).extension() == ".so") { diff --git a/src/task_fn.cc b/src/task_fn.cc index 2fa0ad6..258897c 100644 --- a/src/task_fn.cc +++ b/src/task_fn.cc @@ -97,7 +97,7 @@ std::vector TaskFn::depends() const std::string TaskFn::target() const { - return _targetFile; + return _targetFile.string(); } std::filesystem::path TaskFn::targetFile() const diff --git a/src/task_ld.cc b/src/task_ld.cc index c8cd1ea..dbe17c5 100644 --- a/src/task_ld.cc +++ b/src/task_ld.cc @@ -115,6 +115,7 @@ int TaskLD::runInner() } append(args, ld_option(toolchain, ctor::ld_opt::output, targetFile().string())); + append(args, to_strings(toolchain, {ctor::toolchain::msvc, ctor::ld_opt::custom, "/nologo"})); { // Write flags to file. std::ofstream flagsStream(flagsFile); @@ -126,8 +127,27 @@ int TaskLD::runInner() std::cout << "LD => " << targetFile().string() << std::endl; } - auto tool = compiler(); + std::string tool; const auto& c = ctor::get_configuration(); + + if(toolchain == ctor::toolchain::gcc || + toolchain == ctor::toolchain::clang) + { + tool = compiler(); + } + else // msvc + { + switch(outputSystem()) + { + case ctor::output_system::host: + tool = c.get(ctor::cfg::host_ld, "/usr/bin/ld"); + break; + case ctor::output_system::build: + tool = c.get(ctor::cfg::build_ld, "/usr/bin/ld"); + break; + } + } + return execute(settings, tool, args, c.env, is_self); } @@ -196,7 +216,6 @@ std::string TaskLD::flagsString() const flagsStr += str; } } - flagsStr += "\n"; for(const auto& dep : config.depends) { diff --git a/src/task_so.cc b/src/task_so.cc index 75b5f3c..d818d94 100644 --- a/src/task_so.cc +++ b/src/task_so.cc @@ -93,6 +93,8 @@ int TaskSO::runInner() append(args, ld_option(toolchain, ctor::ld_opt::output, targetFile().string())); + append(args, to_strings(toolchain, {ctor::toolchain::msvc, ctor::ld_opt::custom, "/nologo"})); + for(const auto& task : getDependsTasks()) { args.push_back(task->targetFile().string()); @@ -183,7 +185,6 @@ std::string TaskSO::flagsString() const flagsStr += str; } } - flagsStr += "\n"; for(const auto& dep : config.depends) { diff --git a/src/tools.cc b/src/tools.cc index 394a91c..7f16a0e 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,9 @@ std::ostream& operator<<(std::ostream& stream, const ctor::c_opt& opt) case ctor::c_opt::output: stream << "ctor::c_opt::output"; break; case ctor::c_opt::debug: stream << "ctor::c_opt::debug"; break; case ctor::c_opt::warn_all: stream << "ctor::c_opt::warn_all"; break; + case ctor::c_opt::warn_conversion: stream << "ctor::c_opt::warn_conversion"; break; + case ctor::c_opt::warn_shadow: stream << "ctor::c_opt::warn_shadow"; break; + case ctor::c_opt::warn_extra: stream << "ctor::c_opt::warn_extra"; break; case ctor::c_opt::warnings_as_errors: stream << "ctor::c_opt::warnings_as_errors"; break; case ctor::c_opt::generate_dep_tree: stream << "ctor::c_opt::generate_dep_tree"; break; case ctor::c_opt::no_link: stream << "ctor::c_opt::no_link"; break; @@ -28,6 +32,7 @@ std::ostream& operator<<(std::ostream& stream, const ctor::c_opt& opt) case ctor::c_opt::optimization: stream << "ctor::c_opt::optimization"; break; case ctor::c_opt::position_independent_code: stream << "ctor::c_opt::position_independent_code"; break; case ctor::c_opt::position_independent_executable: stream << "ctor::c_opt::position_independent_executable"; break; + case ctor::c_opt::define: stream << "ctor::c_opt::define"; break; case ctor::c_opt::custom: stream << "ctor::c_opt::custom"; break; } @@ -42,6 +47,9 @@ std::ostream& operator<<(std::ostream& stream, const ctor::cxx_opt& opt) case ctor::cxx_opt::output: stream << "ctor::cxx_opt::output"; break; case ctor::cxx_opt::debug: stream << "ctor::cxx_opt::debug"; break; case ctor::cxx_opt::warn_all: stream << "ctor::cxx_opt::warn_all"; break; + case ctor::cxx_opt::warn_conversion: stream << "ctor::cxx_opt::warn_conversion"; break; + case ctor::cxx_opt::warn_shadow: stream << "ctor::cxx_opt::warn_shadow"; break; + case ctor::cxx_opt::warn_extra: stream << "ctor::cxx_opt::warn_extra"; break; case ctor::cxx_opt::warnings_as_errors: stream << "ctor::cxx_opt::warnings_as_errors"; break; case ctor::cxx_opt::generate_dep_tree: stream << "ctor::cxx_opt::generate_dep_tree"; break; case ctor::cxx_opt::no_link: stream << "ctor::cxx_opt::no_link"; break; @@ -50,6 +58,7 @@ std::ostream& operator<<(std::ostream& stream, const ctor::cxx_opt& opt) case ctor::cxx_opt::optimization: stream << "ctor::cxx_opt::optimization"; break; case ctor::cxx_opt::position_independent_code: stream << "ctor::cxx_opt::position_independent_code"; break; case ctor::cxx_opt::position_independent_executable: stream << "ctor::cxx_opt::position_independent_executable"; break; + case ctor::cxx_opt::define: stream << "ctor::cxx_opt::define"; break; case ctor::cxx_opt::custom: stream << "ctor::cxx_opt::custom"; break; } @@ -109,18 +118,27 @@ ctor::toolchain getToolChain(const std::string& compiler) std::filesystem::path cc(compiler); auto cc_cmd = cc.stem().string(); + std::cout << "getToolChain: [" << cc_cmd << "] => "; + // Note: "g++" is a substring of "clang++" so "clang++" must be tested first. if(cc_cmd.find("clang++") != std::string::npos || cc_cmd.find("clang") != std::string::npos) { + std::cout << "clang" << std::endl; return ctor::toolchain::clang; } else if(cc_cmd.find("g++") != std::string::npos || cc_cmd.find("gcc") != std::string::npos || cc_cmd.find("mingw") != std::string::npos) { + std::cout << "gcc" << std::endl; return ctor::toolchain::gcc; } + else if(to_lower(cc_cmd).find("cl") != std::string::npos) + { + std::cout << "msvc" << std::endl; + return ctor::toolchain::msvc; + } std::cerr << "Unsupported output system.\n"; return ctor::toolchain::gcc; @@ -146,12 +164,262 @@ ctor::toolchain getToolChain(ctor::output_system system) return getToolChain(cfg.get(ctor::cfg::build_cxx, "g++")); } } +namespace msvc { +std::string get_arch([[maybe_unused]] ctor::output_system system) +{ + std::string arch; + // TODO + return arch; +} + +ctor::arch get_arch([[maybe_unused]] const std::string& str) +{ + return ctor::arch::windows; +} + +ctor::c_flag c_option(const std::string& flag) +{ + if(flag.starts_with("/I")) + { + std::string path = flag.substr(2); + path.erase(0, path.find_first_not_of(' ')); + return { ctor::c_opt::include_path, path }; + } + + return { ctor::c_opt::custom, flag }; +} + +ctor::cxx_flag cxx_option(const std::string& flag) +{ + if(flag.starts_with("/I")) + { + std::string path = flag.substr(2); + path.erase(0, path.find_first_not_of(' ')); + return { ctor::cxx_opt::include_path, path }; + } + + return { ctor::cxx_opt::custom, flag }; +} + +ctor::ld_flag ld_option(const std::string& flag) +{ + if(flag.starts_with("/L")) + { + std::string path = flag.substr(2); + path.erase(0, path.find_first_not_of(' ')); + return { ctor::ld_opt::library_path, path }; + } + + return { ctor::ld_opt::custom, flag }; +} + +ctor::ar_flag ar_option(const std::string& flag) +{ + return { ctor::ar_opt::custom, flag }; +} + +std::vector cxx_option(ctor::cxx_opt opt, const std::string& arg, + const std::string& arg2) +{ + switch(opt) + { + case ctor::cxx_opt::output: + return {"/Fo\"" + arg + "\""}; + case ctor::cxx_opt::debug: + return {"/DEBUG"}; + case ctor::cxx_opt::warn_all: + return {"/W4"}; + case ctor::cxx_opt::warn_conversion: + return {"/W4"}; // TODO: This is incorrect + case ctor::cxx_opt::warn_shadow: + return {"/W4"}; // TODO: This is incorrect + case ctor::cxx_opt::warn_extra: + return {"/W4"}; // TODO: This is incorrect + case ctor::cxx_opt::warnings_as_errors: + return {"/WX"}; + case ctor::cxx_opt::generate_dep_tree: + return {"/sourceDependencies", arg}; + case ctor::cxx_opt::no_link: + return {"/c"}; + case ctor::cxx_opt::include_path: + return {"/I" + arg}; + case ctor::cxx_opt::cpp_std: + return {"/std:" + arg}; + case ctor::cxx_opt::optimization: + { + int o{0}; + try + { + o = std::stoi(arg); + o = std::clamp(o, 0, 2); + } + catch(...) + { + // bad number? + } + return {"/O" + std::to_string(o)}; + } + case ctor::cxx_opt::position_independent_code: + return {}; // TODO? + case ctor::cxx_opt::position_independent_executable: + return {}; // TODO? + case ctor::cxx_opt::define: + if(!arg2.empty()) + { + return {"/D" + arg + "=" + esc(arg2)}; + } + else + { + return {"/D" + arg}; + } + case ctor::cxx_opt::custom: + return {arg}; + } + + std::cerr << "Unsupported compiler option.\n"; + return {}; +} + +std::vector c_option(ctor::c_opt opt, const std::string& arg, + const std::string& arg2) +{ + switch(opt) + { + case ctor::c_opt::output: + return {"/Fo\"" + arg + "\""}; + case ctor::c_opt::debug: + return {"/DEBUG"}; + case ctor::c_opt::warn_all: + return {"/W4"}; + case ctor::c_opt::warn_conversion: + return {"/W4"}; // TODO: This is incorrect + case ctor::c_opt::warn_shadow: + return {"/W4"}; // TODO: This is incorrect + case ctor::c_opt::warn_extra: + return {"/W4"}; // TODO: This is incorrect + case ctor::c_opt::warnings_as_errors: + return {"/WX"}; + case ctor::c_opt::generate_dep_tree: + return {"/sourceDependencies", arg}; + case ctor::c_opt::no_link: + return {"/c"}; + case ctor::c_opt::include_path: + return {"/I" + arg}; + case ctor::c_opt::c_std: + return {"/std:" + arg}; + case ctor::c_opt::optimization: + { + int o{0}; + try + { + o = std::stoi(arg); + o = std::clamp(o, 0, 2); + } + catch(...) + { + // bad number? + } + return {"/O" + std::to_string(o)}; + } + case ctor::c_opt::position_independent_code: + return {}; // TODO? + case ctor::c_opt::position_independent_executable: + return {}; // TODO? + case ctor::c_opt::define: + if(!arg2.empty()) + { + return {"/D" + arg + "=" + esc(arg2)}; + } + else + { + return {"/D" + arg}; + } + case ctor::c_opt::custom: + return {arg}; + } + + std::cerr << "Unsupported compiler option.\n"; + return {}; +} + +std::vector ld_option(ctor::ld_opt opt, const std::string& arg, + [[maybe_unused]]const std::string& arg2) +{ + switch(opt) + { + case ctor::ld_opt::output: + return {"/out:" + arg + ""}; + case ctor::ld_opt::strip: + return {}; // TODO? + case ctor::ld_opt::warn_all: + return {"/Wall"}; + case ctor::ld_opt::warnings_as_errors: + return {"/WX"}; + case ctor::ld_opt::library_path: + return {"/LIBPATH:\""+arg+"\""}; + case ctor::ld_opt::link: + return {arg}; // TODO? + case ctor::ld_opt::cpp_std: + return {"/std:" + arg}; + case ctor::ld_opt::build_shared: + return {}; // TODO? + case ctor::ld_opt::threads: + return {}; // TODO? + case ctor::ld_opt::position_independent_code: + return {}; // TODO? + case ctor::ld_opt::position_independent_executable: + return {}; // TODO? + case ctor::ld_opt::custom: + return {arg}; + } + + std::cerr << "Unsupported compiler option.\n"; + return {}; +} + +std::vector ar_option(ctor::ar_opt opt, const std::string& arg, + [[maybe_unused]]const std::string& arg2) +{ + switch(opt) + { + case ctor::ar_opt::replace: + return {}; + case ctor::ar_opt::add_index: + return {}; + case ctor::ar_opt::create: + return {}; + case ctor::ar_opt::output: + return {"/out:" + arg}; + case ctor::ar_opt::custom: + return {arg}; + } + + std::cerr << "Unsupported compiler option.\n"; + return {}; +} + +std::vector asm_option(ctor::asm_opt opt, const std::string& arg, + [[maybe_unused]]const std::string& arg2) +{ + switch(opt) + { + case ctor::asm_opt::custom: + return {arg}; + } + + std::cerr << "Unsupported compiler option.\n"; + return {}; +} +} // msvc:: + namespace gcc { -std::string get_arch(ctor::output_system system) +std::string get_arch([[maybe_unused]] ctor::output_system system) { + std::string arch; + // TODO popen on windows +#if !defined(_WIN32) std::string cmd; - const auto& c = ctor::get_configuration(); switch(system) { @@ -172,7 +440,6 @@ std::string get_arch(ctor::output_system system) return {};//ctor::arch::unknown; } - std::string arch; while(!feof(pipe)) { constexpr auto buffer_size{1024}; @@ -198,6 +465,7 @@ std::string get_arch(ctor::output_system system) // Remove 'Target: ' prefix constexpr auto prefix_length{8}; arch = arch.substr(prefix_length); +#endif // _WIN32 return arch; } @@ -245,6 +513,61 @@ ctor::c_flag c_option(const std::string& flag) return { ctor::c_opt::include_path, path }; } + if(flag.starts_with("-std=")) + { + std::string std = flag.substr(5); + return { ctor::c_opt::c_std, std }; + } + + if(flag.starts_with("-O")) + { + std::string opt = flag.substr(2, 1); + return { ctor::c_opt::optimization, opt }; + } + + if(flag.starts_with("-Wall")) + { + return { ctor::c_opt::warn_all }; + } + + if(flag.starts_with("-Wconversion")) + { + return { ctor::c_opt::warn_conversion}; + } + + if(flag.starts_with("-Wshadow")) + { + return { ctor::c_opt::warn_shadow}; + } + + if(flag.starts_with("-Wextra")) + { + return { ctor::c_opt::warn_extra}; + } + + if(flag.starts_with("-Werror")) + { + return { ctor::c_opt::warnings_as_errors }; + } + + if(flag.starts_with("-g")) + { + return { ctor::c_opt::debug }; + } + + if(flag.starts_with("-D")) + { + std::string def = flag.substr(2); + auto pos = def.find('='); + if(pos != def.npos) + { + return { ctor::c_opt::define, def.substr(0, pos), def.substr(pos + 1) }; + } + else + { + return { ctor::c_opt::define, def }; + } + } return { ctor::c_opt::custom, flag }; } @@ -257,6 +580,62 @@ ctor::cxx_flag cxx_option(const std::string& flag) return { ctor::cxx_opt::include_path, path }; } + if(flag.starts_with("-std=")) + { + std::string std = flag.substr(5); + return { ctor::cxx_opt::cpp_std, std }; + } + + if(flag.starts_with("-O")) + { + std::string opt = flag.substr(2, 1); + return { ctor::cxx_opt::optimization, opt }; + } + + if(flag.starts_with("-Wall")) + { + return { ctor::cxx_opt::warn_all }; + } + + if(flag.starts_with("-Werror")) + { + return { ctor::cxx_opt::warnings_as_errors }; + } + + if(flag.starts_with("-Wconversion")) + { + return { ctor::cxx_opt::warn_conversion}; + } + + if(flag.starts_with("-Wshadow")) + { + return { ctor::cxx_opt::warn_shadow}; + } + + if(flag.starts_with("-Wextra")) + { + return { ctor::cxx_opt::warn_extra}; + } + + if(flag.starts_with("-g")) + { + return { ctor::cxx_opt::debug }; + } + + if(flag.starts_with("-D")) + { + std::string def = flag.substr(2); + auto pos = def.find('='); + if(pos != def.npos) + { + return { ctor::cxx_opt::define, def.substr(0, pos), def.substr(pos + 1) }; + } + else + { + return { ctor::cxx_opt::define, def }; + } + } + return { ctor::cxx_opt::custom, flag }; } @@ -269,6 +648,11 @@ ctor::ld_flag ld_option(const std::string& flag) return { ctor::ld_opt::library_path, path }; } + if(flag.starts_with("-pthread")) + { + return { ctor::ld_opt::threads }; + } + return { ctor::ld_opt::custom, flag }; } @@ -277,7 +661,8 @@ ctor::ar_flag ar_option(const std::string& flag) return { ctor::ar_opt::custom, flag }; } -std::vector cxx_option(ctor::cxx_opt opt, const std::string& arg) +std::vector cxx_option(ctor::cxx_opt opt, const std::string& arg, + const std::string& arg2) { switch(opt) { @@ -287,6 +672,12 @@ std::vector cxx_option(ctor::cxx_opt opt, const std::string& arg) return {"-g"}; case ctor::cxx_opt::warn_all: return {"-Wall"}; + case ctor::cxx_opt::warn_conversion: + return {"-Wconversion"}; + case ctor::cxx_opt::warn_shadow: + return {"-Wshadow"}; + case ctor::cxx_opt::warn_extra: + return {"-Wextra"}; case ctor::cxx_opt::warnings_as_errors: return {"-Werror"}; case ctor::cxx_opt::generate_dep_tree: @@ -303,6 +694,12 @@ std::vector cxx_option(ctor::cxx_opt opt, const std::string& arg) return {"-fPIC"}; case ctor::cxx_opt::position_independent_executable: return {"-fPIE"}; + case ctor::cxx_opt::define: + if(!arg2.empty()) + { + return {"-D" + arg + "=" + arg2}; + } + return {"-D" + arg}; case ctor::cxx_opt::custom: return {arg}; } @@ -311,7 +708,8 @@ std::vector cxx_option(ctor::cxx_opt opt, const std::string& arg) return {}; } -std::vector c_option(ctor::c_opt opt, const std::string& arg) +std::vector c_option(ctor::c_opt opt, const std::string& arg, + const std::string& arg2) { switch(opt) { @@ -321,6 +719,12 @@ std::vector c_option(ctor::c_opt opt, const std::string& arg) return {"-g"}; case ctor::c_opt::warn_all: return {"-Wall"}; + case ctor::c_opt::warn_conversion: + return {"-Wconversion"}; + case ctor::c_opt::warn_shadow: + return {"-Wshadow"}; + case ctor::c_opt::warn_extra: + return {"-Wextra"}; case ctor::c_opt::warnings_as_errors: return {"-Werror"}; case ctor::c_opt::generate_dep_tree: @@ -337,6 +741,12 @@ std::vector c_option(ctor::c_opt opt, const std::string& arg) return {"-fPIC"}; case ctor::c_opt::position_independent_executable: return {"-fPIE"}; + case ctor::c_opt::define: + if(!arg2.empty()) + { + return {"-D" + arg + "=" + arg2}; + } + return {"-D" + arg}; case ctor::c_opt::custom: return {arg}; } @@ -345,7 +755,8 @@ std::vector c_option(ctor::c_opt opt, const std::string& arg) return {}; } -std::vector ld_option(ctor::ld_opt opt, const std::string& arg) +std::vector ld_option(ctor::ld_opt opt, const std::string& arg, + [[maybe_unused]]const std::string& arg2) { switch(opt) { @@ -379,7 +790,8 @@ std::vector ld_option(ctor::ld_opt opt, const std::string& arg) return {}; } -std::vector ar_option(ctor::ar_opt opt, const std::string& arg) +std::vector ar_option(ctor::ar_opt opt, const std::string& arg, + [[maybe_unused]]const std::string& arg2) { switch(opt) { @@ -399,7 +811,8 @@ std::vector ar_option(ctor::ar_opt opt, const std::string& arg) return {}; } -std::vector asm_option(ctor::asm_opt opt, const std::string& arg) +std::vector asm_option(ctor::asm_opt opt, const std::string& arg, + [[maybe_unused]]const std::string& arg2) { switch(opt) { @@ -420,6 +833,8 @@ std::string get_arch(ctor::output_system system) case ctor::toolchain::clang: case ctor::toolchain::gcc: return gcc::get_arch(system); + case ctor::toolchain::msvc: + return msvc::get_arch(system); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -435,6 +850,8 @@ ctor::arch get_arch(ctor::output_system system, const std::string& str) case ctor::toolchain::clang: case ctor::toolchain::gcc: return gcc::get_arch(str); + case ctor::toolchain::msvc: + return msvc::get_arch(str); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -444,13 +861,16 @@ ctor::arch get_arch(ctor::output_system system, const std::string& str) std::vector c_option(ctor::toolchain toolchain, ctor::c_opt opt, - const std::string& arg) + const std::string& arg, + const std::string& arg2) { switch(toolchain) { case ctor::toolchain::gcc: case ctor::toolchain::clang: - return gcc::c_option(opt, arg); + return gcc::c_option(opt, arg, arg2); + case ctor::toolchain::msvc: + return msvc::c_option(opt, arg, arg2); case ctor::toolchain::any: { std::ostringstream ss; @@ -459,6 +879,10 @@ std::vector c_option(ctor::toolchain toolchain, { ss << ", \"" << arg << "\""; } + if(!arg2.empty()) + { + ss << ", \"" << arg2 << "\""; + } ss << "}"; return { ss.str() }; } @@ -472,13 +896,16 @@ std::vector c_option(ctor::toolchain toolchain, std::vector cxx_option(ctor::toolchain toolchain, ctor::cxx_opt opt, - const std::string& arg) + const std::string& arg, + const std::string& arg2) { switch(toolchain) { case ctor::toolchain::gcc: case ctor::toolchain::clang: - return gcc::cxx_option(opt, arg); + return gcc::cxx_option(opt, arg, arg2); + case ctor::toolchain::msvc: + return msvc::cxx_option(opt, arg, arg2); case ctor::toolchain::any: { std::ostringstream ss; @@ -487,6 +914,10 @@ std::vector cxx_option(ctor::toolchain toolchain, { ss << ", \"" << arg << "\""; } + if(!arg2.empty()) + { + ss << ", \"" << arg2 << "\""; + } ss << "}"; return { ss.str() }; } @@ -500,13 +931,16 @@ std::vector cxx_option(ctor::toolchain toolchain, std::vector ld_option(ctor::toolchain toolchain, ctor::ld_opt opt, - const std::string& arg) + const std::string& arg, + const std::string& arg2) { switch(toolchain) { case ctor::toolchain::gcc: case ctor::toolchain::clang: - return gcc::ld_option(opt, arg); + return gcc::ld_option(opt, arg, arg2); + case ctor::toolchain::msvc: + return msvc::ld_option(opt, arg, arg2); case ctor::toolchain::any: { std::ostringstream ss; @@ -515,6 +949,10 @@ std::vector ld_option(ctor::toolchain toolchain, { ss << ", \"" << arg << "\""; } + if(!arg2.empty()) + { + ss << ", \"" << arg2 << "\""; + } ss << "}"; return { ss.str() }; } @@ -528,13 +966,16 @@ std::vector ld_option(ctor::toolchain toolchain, std::vector ar_option(ctor::toolchain toolchain, ctor::ar_opt opt, - const std::string& arg) + const std::string& arg, + const std::string& arg2) { switch(toolchain) { case ctor::toolchain::gcc: case ctor::toolchain::clang: - return gcc::ar_option(opt, arg); + return gcc::ar_option(opt, arg, arg2); + case ctor::toolchain::msvc: + return msvc::ar_option(opt, arg, arg2); case ctor::toolchain::any: { std::ostringstream ss; @@ -543,6 +984,10 @@ std::vector ar_option(ctor::toolchain toolchain, { ss << ", \"" << arg << "\""; } + if(!arg2.empty()) + { + ss << ", \"" << arg2 << "\""; + } ss << "}"; return { ss.str() }; } @@ -556,13 +1001,16 @@ std::vector ar_option(ctor::toolchain toolchain, std::vector asm_option(ctor::toolchain toolchain, ctor::asm_opt opt, - const std::string& arg) + const std::string& arg, + const std::string& arg2) { switch(toolchain) { case ctor::toolchain::gcc: case ctor::toolchain::clang: - return gcc::asm_option(opt, arg); + return gcc::asm_option(opt, arg, arg2); + case ctor::toolchain::msvc: + return msvc::asm_option(opt, arg, arg2); case ctor::toolchain::any: { std::ostringstream ss; @@ -571,6 +1019,10 @@ std::vector asm_option(ctor::toolchain toolchain, { ss << ", \"" << arg << "\""; } + if(!arg2.empty()) + { + ss << ", \"" << arg2 << "\""; + } ss << "}"; return { ss.str() }; } @@ -590,6 +1042,8 @@ ctor::c_flag c_option(const std::string& flag, ctor::toolchain toolchain) case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::c_option(flag); + case ctor::toolchain::msvc: + return msvc::c_option(flag); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -605,6 +1059,8 @@ ctor::cxx_flag cxx_option(const std::string& flag, ctor::toolchain toolchain) case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::cxx_option(flag); + case ctor::toolchain::msvc: + return msvc::cxx_option(flag); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -620,6 +1076,8 @@ ctor::ld_flag ld_option(const std::string& flag, ctor::toolchain toolchain) case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::ld_option(flag); + case ctor::toolchain::msvc: + return msvc::ld_option(flag); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -635,6 +1093,8 @@ ctor::ar_flag ar_option(const std::string& flag, ctor::toolchain toolchain) case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::ar_option(flag); + case ctor::toolchain::msvc: + return msvc::ar_option(flag); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -649,6 +1109,7 @@ ctor::asm_flag asm_option(const std::string& flag, ctor::toolchain toolchain) { case ctor::toolchain::gcc: case ctor::toolchain::clang: + case ctor::toolchain::msvc: case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -665,7 +1126,7 @@ std::vector to_strings(ctor::toolchain toolchain, if(flag.toolchain == ctor::toolchain::any || flag.toolchain == toolchain) { - return c_option(toolchain, flag.opt, flag.arg); + return c_option(toolchain, flag.opt, flag.arg, flag.arg2); } return {}; @@ -677,7 +1138,7 @@ std::vector to_strings(ctor::toolchain toolchain, if(flag.toolchain == ctor::toolchain::any || flag.toolchain == toolchain) { - return cxx_option(toolchain, flag.opt, flag.arg); + return cxx_option(toolchain, flag.opt, flag.arg, flag.arg2); } return {}; @@ -689,7 +1150,7 @@ std::vector to_strings(ctor::toolchain toolchain, if(flag.toolchain == ctor::toolchain::any || flag.toolchain == toolchain) { - return ld_option(toolchain, flag.opt, flag.arg); + return ld_option(toolchain, flag.opt, flag.arg, flag.arg2); } return {}; @@ -701,7 +1162,7 @@ std::vector to_strings(ctor::toolchain toolchain, if(flag.toolchain == ctor::toolchain::any || flag.toolchain == toolchain) { - return ar_option(toolchain, flag.opt, flag.arg); + return ar_option(toolchain, flag.opt, flag.arg, flag.arg2); } return {}; @@ -713,7 +1174,7 @@ std::vector to_strings(ctor::toolchain toolchain, if(flag.toolchain == ctor::toolchain::any || flag.toolchain == toolchain) { - return asm_option(toolchain, flag.opt, flag.arg); + return asm_option(toolchain, flag.opt, flag.arg, flag.arg2); } return {}; @@ -732,10 +1193,11 @@ ctor::toolchain guess_toolchain(const std::string& opt) return ctor::toolchain::gcc; } - //if(opt[0] == '/') - //{ - // return ctor::toolchain::msvc; - //} + if(opt[0] == '/') + { + return ctor::toolchain::msvc; + } + return ctor::toolchain::any; } } @@ -806,8 +1268,8 @@ ctor::target_type target_type_from_extension(ctor::toolchain toolchain, } } - if(toolchain == ctor::toolchain::any// || - //toolchain == ctor::toolchain::msvc || + if(toolchain == ctor::toolchain::any || + toolchain == ctor::toolchain::msvc// || //toolchain == ctor::toolchain::mingw || ) { diff --git a/src/tools.h b/src/tools.h index 188d49f..0e7fc15 100644 --- a/src/tools.h +++ b/src/tools.h @@ -32,31 +32,36 @@ ctor::toolchain getToolChain(ctor::output_system system); //! tool-chain std::vector c_option(ctor::toolchain toolchain, ctor::c_opt option, - const std::string& arg = {}); + const std::string& arg = {}, + const std::string& arg2 = {}); //! Get tool argument(s) for specific option type matching the supplied //! tool-chain std::vector cxx_option(ctor::toolchain toolchain, ctor::cxx_opt option, - const std::string& arg = {}); + const std::string& arg = {}, + const std::string& arg2 = {}); //! Get tool argument(s) for specific option type matching the supplied //! tool-chain std::vector ld_option(ctor::toolchain toolchain, ctor::ld_opt option, - const std::string& arg = {}); + const std::string& arg = {}, + const std::string& arg2 = {}); //! Get tool argument(s) for specific option type matching the supplied //! tool-chain std::vector ar_option(ctor::toolchain toolchain, ctor::ar_opt option, - const std::string& arg = {}); + const std::string& arg = {}, + const std::string& arg2 = {}); //! Get tool argument(s) for specific option type matching the supplied //! tool-chain std::vector asm_option(ctor::toolchain toolchain, ctor::asm_opt option, - const std::string& arg = {}); + const std::string& arg = {}, + const std::string& arg2 = {}); diff --git a/src/util.cc b/src/util.cc index 73b158d..cfa0d85 100644 --- a/src/util.cc +++ b/src/util.cc @@ -7,10 +7,17 @@ #include #include +namespace { +char to_lower_c(char ch) +{ + return static_cast(::tolower(ch)); +} +} + std::string to_lower(const std::string& str) { std::string out{str}; - std::transform(out.begin(), out.end(), out.begin(), ::tolower); + std::transform(out.begin(), out.end(), out.begin(), to_lower_c); return out; } @@ -19,17 +26,25 @@ std::string readFile(const std::string& fileName) std::ifstream ifs(fileName.c_str(), std::ios::in | std::ios::binary | std::ios::ate); - std::ifstream::pos_type fileSize = ifs.tellg(); + auto tell = ifs.tellg(); + if(tell < 0) + { + return {}; + } + auto fileSize = static_cast(tell); ifs.seekg(0, std::ios::beg); - std::vector bytes(static_cast(fileSize)); - ifs.read(bytes.data(), fileSize); + std::vector bytes(fileSize); + ifs.read(bytes.data(), static_cast(bytes.size())); - return {bytes.data(), static_cast(fileSize)}; + return { bytes.data(), bytes.size() }; } std::vector readDeps(const std::string& depFile) { +#if defined(_WIN32) + return {};// TODO: parse json +#endif if(!std::filesystem::exists(depFile)) { return {}; @@ -229,15 +244,36 @@ std::string locate(const std::string& prog, } } + if(std::filesystem::exists(program + ".exe")) + { + if(check_executable(program + ".exe")) + { + return program + ".exe"; + } + } + for(const auto& path_str : paths) { std::filesystem::path path(path_str); - auto prog_path = path / program; - if(std::filesystem::exists(prog_path)) { - if(check_executable(prog_path)) + auto prog_path = path / program; + if(std::filesystem::exists(prog_path)) + { + if(check_executable(prog_path)) + { + return prog_path.string(); + } + } + } + + { + auto prog_path = path / (program + ".exe"); + if(std::filesystem::exists(prog_path)) { - return prog_path.string(); + if(check_executable(prog_path)) + { + return prog_path.string(); + } } } } diff --git a/test/ctor.cc b/test/ctor.cc index ccf1c31..66159b5 100644 --- a/test/ctor.cc +++ b/test/ctor.cc @@ -10,15 +10,18 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) return { { + .name = "testprog", .type = ctor::target_type::unit_test, .system = ctor::output_system::build, .target = "testprog", .sources = { - "testprog.cc", + {"testprog.cc"}, }, .flags = { .cxxflags = { - "-std=c++20", "-O3", "-Wall", "-Werror", + "-std=c++20", "-O3", "-Wall",// "-Werror", + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/EHsc"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/D_CRT_SECURE_NO_WARNINGS"}, }, }, }, @@ -35,9 +38,11 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) .depends = { "testprog", }, .flags = { .cxxflags = { - "-std=c++20", "-O3", "-Wall", "-Werror", + "-std=c++20", "-O3", "-Wall",// "-Werror", "-I../src", "-Iuunit", "-DOUTPUT=\"execute\"", + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/EHsc"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/D_CRT_SECURE_NO_WARNINGS"}, }, .ldflags = { "-pthread" }, }, @@ -50,12 +55,14 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) "tasks_test.cc", "testmain.cc", }, - .depends = { "libctor_nomain.a" }, + .depends = { "libctor_nomain.lib" }, .flags = { .cxxflags = { - "-std=c++20", "-O3", "-Wall", "-Werror", + "-std=c++20", "-O3", "-Wall",// "-Werror", "-I../src", "-Iuunit", "-DOUTPUT=\"tasks\"", + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/EHsc"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/D_CRT_SECURE_NO_WARNINGS"}, }, .ldflags = { "-pthread" }, }, @@ -68,12 +75,14 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) "source_type_test.cc", "testmain.cc", }, - .depends = { "libctor_nomain.a" }, + .depends = { "libctor_nomain.lib" }, .flags = { .cxxflags = { - "-std=c++20", "-O3", "-Wall", "-Werror", + "-std=c++20", "-O3", "-Wall",// "-Werror", "-I../src", "-Iuunit", "-DOUTPUT=\"source_type\"", + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/EHsc"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/D_CRT_SECURE_NO_WARNINGS"}, }, .ldflags = { "-pthread" }, }, @@ -91,16 +100,18 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) //.depends = { "libctor_nomain.a" }, .flags = { .cxxflags = { - "-std=c++20", "-O3", "-Wall", "-Werror", + "-std=c++20", "-O3", "-Wall",// "-Werror", "-I../src", "-Iuunit", "-DOUTPUT=\"tools\"", + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/EHsc"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/D_CRT_SECURE_NO_WARNINGS"}, }, }, }, { .type = ctor::target_type::unit_test_library, .system = ctor::output_system::build, - .target = "libctor_nomain.a", + .target = "libctor_nomain.lib", .sources = { "../src/build.cc", "../src/configure.cc", @@ -116,11 +127,32 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) "../src/tools.cc", "../src/util.cc", "../src/externals_manual.cc", + {ctor::toolchain::msvc, "../getopt-for-windows/getopt.c"}, }, .flags = { + .cflags = { + "-O3", +// "-g", +// "-Wall", +// "-Wconversion", +// "-Wextra", + //"-Werror", + "-I../src", + {ctor::toolchain::msvc, ctor::c_opt::custom, "/I../getopt-for-windows"}, + {ctor::toolchain::msvc, ctor::c_opt::custom, "/D_X86_"}, + {ctor::toolchain::msvc, ctor::c_opt::custom, "/EHsc"}, + {ctor::toolchain::msvc, ctor::c_opt::custom, "/external:W0"}, + {ctor::toolchain::msvc, ctor::c_opt::custom, "/D_CRT_SECURE_NO_WARNINGS"}, + }, .cxxflags = { - "-std=c++20", "-O3", "-Wall", "-Werror", + "-std=c++20", "-O3", "-Wall",// "-Werror", "-I../src", + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/Igetopt-for-windows"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/D_X86_"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/EHsc"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/external:W0"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/D_CRT_SECURE_NO_WARNINGS"}, + {ctor::toolchain::msvc, ctor::cxx_opt::custom, "/Dstrdup=_strdup"}, }, .ldflags = { "-pthread" }, }, diff --git a/test/execute_test.cc b/test/execute_test.cc index 4c686bf..027ef3b 100644 --- a/test/execute_test.cc +++ b/test/execute_test.cc @@ -30,11 +30,11 @@ public: uASSERT(!cmd.empty()); auto value = execute(s, cmd, {"retval", "0"}, {}, false); - uASSERT_EQUAL(0, value); + assert_equal(0, value, __FILE__, __LINE__); value = execute(s, cmd, {"retval", "1"}, {}, false); - uASSERT_EQUAL(1, value); + assert_equal(1, value, __FILE__, __LINE__); value = execute(s, "no-such-binary", {}, {}, false); - uASSERT_EQUAL(1, value); + assert_equal(1, value, __FILE__, __LINE__); } void env() @@ -59,7 +59,7 @@ public: env["LANG"] = "foo"; auto value = execute(s, cmd, {"envdump", tmp.get()}, env, false); - uASSERT_EQUAL(0, value); + assert_equal(0, value, __FILE__, __LINE__); std::vector vars; { diff --git a/test/source_type_test.cc b/test/source_type_test.cc index 288f1e5..ced8e3a 100644 --- a/test/source_type_test.cc +++ b/test/source_type_test.cc @@ -53,22 +53,22 @@ public: { { // c++ TestableTaskCC task("hello.cc"); - uASSERT_EQUAL(ctor::language::cpp, task.language()); + assert_equal(ctor::language::cpp, task.language(), __FILE__, __LINE__); } { // c TestableTaskCC task("hello.c"); - uASSERT_EQUAL(ctor::language::c, task.language()); + assert_equal(ctor::language::c, task.language(), __FILE__, __LINE__); } { // asm TestableTaskCC task("hello.s"); - uASSERT_EQUAL(ctor::language::assembler, task.language()); + assert_equal(ctor::language::assembler, task.language(), __FILE__, __LINE__); } { // custom/explicit language TestableTaskCC task( {"hello.foo", ctor::language::assembler} ); - uASSERT_EQUAL(ctor::language::assembler, task.language()); + assert_equal(ctor::language::assembler, task.language(), __FILE__, __LINE__); } // Note: Failure state will result in exit(1) so cannot be tested diff --git a/test/suite/test.sh b/test/suite/test.sh index c112351..23740a9 100755 --- a/test/suite/test.sh +++ b/test/suite/test.sh @@ -1,4 +1,6 @@ #!/bin/bash +#set -x + : ${CXX:=g++} : ${CTORDIR:=../../build} : ${BUILDDIR:=build} diff --git a/test/tasks_test.cc b/test/tasks_test.cc index 3de6982..c6909c0 100644 --- a/test/tasks_test.cc +++ b/test/tasks_test.cc @@ -93,17 +93,17 @@ public: using namespace std::string_literals; ctor::settings settings{}; const auto& targets = getTargets(settings); - uASSERT_EQUAL(4u, targets.size()); + assert_equal(4u, targets.size(), __FILE__, __LINE__); - uASSERT_EQUAL("target1"s, targets[0].config.target); - uASSERT_EQUAL("target2"s, targets[1].config.target); - uASSERT_EQUAL("target3"s, targets[2].config.target); - uASSERT_EQUAL("target4"s, targets[3].config.target); + assert_equal("target1"s, targets[0].config.target, __FILE__, __LINE__); + assert_equal("target2"s, targets[1].config.target, __FILE__, __LINE__); + assert_equal("target3"s, targets[2].config.target, __FILE__, __LINE__); + assert_equal("target4"s, targets[3].config.target, __FILE__, __LINE__); - uASSERT_EQUAL("test"s, targets[0].path); - uASSERT_EQUAL("test"s, targets[1].path); - uASSERT_EQUAL("test"s, targets[2].path); - uASSERT_EQUAL("test"s, targets[3].path); + assert_equal("test"s, targets[0].path, __FILE__, __LINE__); + assert_equal("test"s, targets[1].path, __FILE__, __LINE__); + assert_equal("test"s, targets[2].path, __FILE__, __LINE__); + assert_equal("test"s, targets[3].path, __FILE__, __LINE__); } void getTasks_test() @@ -112,26 +112,26 @@ public: ctor::settings settings{ .builddir = "foo" }; { auto tasks = getTasks(settings); - uASSERT_EQUAL(6u, tasks.size()); + assert_equal(6u, tasks.size(), __FILE__, __LINE__); // Note: count() is used here because the order doesn't matter - 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)); + assert_equal(1u, count(tasks, "target1"s), __FILE__, __LINE__); + assert_equal(1u, count(tasks, "target2"s), __FILE__, __LINE__); + assert_equal(1u, count(tasks, "target3"s), __FILE__, __LINE__); + assert_equal(1u, count(tasks, "target4"s), __FILE__, __LINE__); + assert_equal(1u, count(tasks, "test/target1-foo_cc.o"s), __FILE__, __LINE__); + assert_equal(1u, count(tasks, "test/target1-bar_c.o"s), __FILE__, __LINE__); } { auto tasks = getTasks(settings, {"target1", "target3"}); - uASSERT_EQUAL(4u, tasks.size()); - 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)); + assert_equal(4u, tasks.size(), __FILE__, __LINE__); + assert_equal(1u, count(tasks, "target1"s), __FILE__, __LINE__); + assert_equal(1u, count(tasks, "target3"s), __FILE__, __LINE__); + assert_equal(1u, count(tasks, "test/target1-foo_cc.o"s), __FILE__, __LINE__); + assert_equal(1u, count(tasks, "test/target1-bar_c.o"s), __FILE__, __LINE__); } { auto tasks = getTasks(settings, {"no-such-target"}); - uASSERT_EQUAL(0u, tasks.size()); + assert_equal(0u, tasks.size(), __FILE__, __LINE__); } } @@ -146,10 +146,10 @@ public: for(auto& task : dirtyTasks) { - uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } - uASSERT_EQUAL(nullptr, getNextTask(allTasks, dirtyTasks)); + assert_equal(nullptr, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); } { // Zero (One task, no dirty) @@ -162,10 +162,10 @@ public: for(auto& task : dirtyTasks) { - uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } - uASSERT_EQUAL(nullptr, getNextTask(allTasks, dirtyTasks)); + assert_equal(nullptr, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); } { // One (One task, one dirty) @@ -179,11 +179,11 @@ public: for(auto& task : dirtyTasks) { - uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } - uASSERT_EQUAL(task1, getNextTask(allTasks, dirtyTasks)); - uASSERT_EQUAL(0u, dirtyTasks.size()); + assert_equal(task1, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); + assert_equal(0u, dirtyTasks.size(), __FILE__, __LINE__); } { // One (Two tasks, one dirty) @@ -199,11 +199,11 @@ public: for(auto& task : dirtyTasks) { - uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } - uASSERT_EQUAL(task2, getNextTask(allTasks, dirtyTasks)); - uASSERT_EQUAL(0u, dirtyTasks.size()); + assert_equal(task2, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); + assert_equal(0u, dirtyTasks.size(), __FILE__, __LINE__); } { // One (Two tasks, one dirty which depends on the other) @@ -221,11 +221,11 @@ public: for(auto& task : dirtyTasks) { - uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } - uASSERT_EQUAL(task2, getNextTask(allTasks, dirtyTasks)); - uASSERT_EQUAL(0u, dirtyTasks.size()); + assert_equal(task2, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); + assert_equal(0u, dirtyTasks.size(), __FILE__, __LINE__); } { // One (Two tasks, Both dirty, one depends on the other) @@ -244,11 +244,11 @@ public: for(auto& task : dirtyTasks) { - uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } - uASSERT_EQUAL(task1, getNextTask(allTasks, dirtyTasks)); - uASSERT_EQUAL(1u, dirtyTasks.size()); + assert_equal(task1, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); + assert_equal(1u, dirtyTasks.size(), __FILE__, __LINE__); } } diff --git a/test/testprog.cc b/test/testprog.cc index dbfb665..c135061 100644 --- a/test/testprog.cc +++ b/test/testprog.cc @@ -2,7 +2,13 @@ #include #include -extern const char **environ; // see 'man environ' +#if defined(_WIN32) +#define WINDOWS_LEAN_AND_MEAN +#include +#undef max +#else +extern char **environ; // see 'man environ' +#endif int main(int argc, const char* argv[]) { @@ -20,10 +26,35 @@ int main(int argc, const char* argv[]) return 0; } std::ofstream ostrm(argv[2], std::ios::binary); +#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 5d114d0..e1a2ff6 100644 --- a/test/tmpfile.h +++ b/test/tmpfile.h @@ -4,7 +4,6 @@ #pragma once #include -#include #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -12,6 +11,9 @@ #include #include #include +#include +#else +#include #endif struct tmp_file @@ -22,20 +24,28 @@ struct tmp_file #ifdef _WIN32 char templ[] = "ctor_tmp_file-XXXXXX"; // buffer for filename _mktemp_s(templ, sizeof(templ)); - fd = open(templ, O_CREAT | O_RDWR); + fd = _open(templ, O_CREAT | O_RDWR); + filename = templ; + auto sz = _write(fd, data.data(), data.size()); + (void)sz; + _close(fd); #else char templ[] = "/tmp/ctor_tmp_file-XXXXXX"; // buffer for filename fd = mkstemp(templ); -#endif filename = templ; auto sz = write(fd, data.data(), data.size()); (void)sz; close(fd); +#endif } ~tmp_file() { +#ifdef _WIN32 + _unlink(filename.data()); +#else unlink(filename.data()); +#endif } const std::string& get() const diff --git a/test/tools_test.cc b/test/tools_test.cc index a428ea1..91da470 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; } @@ -125,7 +128,7 @@ const ctor::configuration& ctor::get_configuration() return cfg; } -const std::string& ctor::configuration::get(const std::string& key, const std::string& defval) const +std::string ctor::configuration::get(const std::string& key, [[maybe_unused]]const std::string& default_value) const { if(key == ctor::cfg::host_cxx) { @@ -175,24 +178,24 @@ public: // // gcc // - uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/gcc")); - uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/gcc-10")); - uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/x86_64-pc-linux-gnu-g++-9.3.0")); + assert_equal(ctor::toolchain::gcc, getToolChain("/usr/bin/gcc"), __FILE__, __LINE__); + assert_equal(ctor::toolchain::gcc, getToolChain("/usr/bin/gcc-10"), __FILE__, __LINE__); + assert_equal(ctor::toolchain::gcc, getToolChain("/usr/bin/x86_64-pc-linux-gnu-g++-9.3.0"), __FILE__, __LINE__); - 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")); + assert_equal(ctor::toolchain::gcc, getToolChain("/usr/bin/g++"), __FILE__, __LINE__); + assert_equal(ctor::toolchain::gcc, getToolChain("/usr/bin/g++-10"), __FILE__, __LINE__); + assert_equal(ctor::toolchain::gcc, getToolChain("/usr/bin/x86_64-pc-linux-gnu-g++-9.3.0"), __FILE__, __LINE__); // // clang // - 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")); + assert_equal(ctor::toolchain::clang, getToolChain("/usr/bin/clang"), __FILE__, __LINE__); + assert_equal(ctor::toolchain::clang, getToolChain("/usr/bin/clang-16"), __FILE__, __LINE__); + assert_equal(ctor::toolchain::clang, getToolChain("/usr/lib/llvm/16/bin/i686-pc-linux-gnu-clang-16"), __FILE__, __LINE__); - 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")); + assert_equal(ctor::toolchain::clang, getToolChain("/usr/bin/clang++"), __FILE__, __LINE__); + assert_equal(ctor::toolchain::clang, getToolChain("/usr/bin/clang++-16"), __FILE__, __LINE__); + assert_equal(ctor::toolchain::clang, getToolChain("/usr/lib/llvm/16/bin/i686-pc-linux-gnu-clang++-16"), __FILE__, __LINE__); } @@ -206,153 +209,153 @@ public: // exp = { "-o", "foo" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::output, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-g" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::debug); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Wall" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::warn_all); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Werror" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::warnings_as_errors); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-MMD" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::generate_dep_tree); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-c" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::no_link); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Ifoo" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::include_path, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-std=foo" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::c_std, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Ofoo" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::optimization, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIC" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::position_independent_code); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIE" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::position_independent_executable); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-foo" }; act = c_option(ctor::toolchain::gcc, ctor::c_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // clang // exp = { "-o", "foo" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::output, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-g" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::debug); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Wall" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::warn_all); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Werror" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::warnings_as_errors); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-MMD" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::generate_dep_tree); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-c" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::no_link); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Ifoo" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::include_path, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-std=foo" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::c_std, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Ofoo" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::optimization, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIC" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::position_independent_code); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIE" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::position_independent_executable); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-foo" }; act = c_option(ctor::toolchain::clang, ctor::c_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // any // exp = { "{ctor::c_opt::output, \"foo\"}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::output, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::c_opt::debug}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::debug); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::c_opt::warn_all}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::warn_all); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::c_opt::warnings_as_errors}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::warnings_as_errors); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::c_opt::generate_dep_tree}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::generate_dep_tree); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::c_opt::no_link}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::no_link); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::c_opt::include_path, \"foo\"}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::include_path, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::c_opt::c_std, \"foo\"}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::c_std, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::c_opt::optimization, \"foo\"}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::optimization, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::c_opt::position_independent_code}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::position_independent_code); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::c_opt::position_independent_executable}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::position_independent_executable); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::c_opt::custom, \"-foo\"}" }; act = c_option(ctor::toolchain::any, ctor::c_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); } void getOption_toolchain_cxx_test() @@ -365,153 +368,153 @@ public: // exp = { "-o", "foo" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::output, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-g" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::debug); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Wall" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::warn_all); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Werror" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::warnings_as_errors); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-MMD" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::generate_dep_tree); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-c" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::no_link); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Ifoo" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::include_path, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-std=foo" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::cpp_std, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Ofoo" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::optimization, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIC" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::position_independent_code); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIE" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::position_independent_executable); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-foo" }; act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // clang // exp = { "-o", "foo" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::output, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-g" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::debug); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Wall" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::warn_all); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Werror" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::warnings_as_errors); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-MMD" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::generate_dep_tree); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-c" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::no_link); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Ifoo" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::include_path, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-std=foo" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::cpp_std, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Ofoo" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::optimization, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIC" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::position_independent_code); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIE" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::position_independent_executable); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-foo" }; act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // any // exp = { "{ctor::cxx_opt::output, \"foo\"}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::output, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::cxx_opt::debug}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::debug); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::cxx_opt::warn_all}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::warn_all); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::cxx_opt::warnings_as_errors}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::warnings_as_errors); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::cxx_opt::generate_dep_tree}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::generate_dep_tree); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::cxx_opt::no_link}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::no_link); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::cxx_opt::include_path, \"foo\"}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::include_path, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::cxx_opt::cpp_std, \"foo\"}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::cpp_std, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::cxx_opt::optimization, \"foo\"}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::optimization, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::cxx_opt::position_independent_code}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::position_independent_code); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::cxx_opt::position_independent_executable}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::position_independent_executable); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::cxx_opt::custom, \"-foo\"}" }; act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); } void getOption_toolchain_ld_test() @@ -524,153 +527,153 @@ public: // exp = { "-o", "foo" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::output, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-s" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::strip); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Wall" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::warn_all); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Werror" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::warnings_as_errors); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Lfoo" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::library_path, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-lfoo" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::link, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-std=foo" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::cpp_std, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-shared" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::build_shared); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-pthread" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::threads); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIC" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::position_independent_code); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIE" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::position_independent_executable); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-foo" }; act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // clang // exp = { "-o", "foo" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::output, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-s" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::strip); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Wall" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::warn_all); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Werror" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::warnings_as_errors); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-Lfoo" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::library_path, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-lfoo" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::link, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-std=foo" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::cpp_std, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-shared" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::build_shared); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-pthread" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::threads); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIC" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::position_independent_code); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-fPIE" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::position_independent_executable); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-foo" }; act = ld_option(ctor::toolchain::clang, ctor::ld_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // any // exp = { "{ctor::ld_opt::output, \"foo\"}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::output, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::ld_opt::strip}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::strip); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::ld_opt::warn_all}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::warn_all); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::ld_opt::warnings_as_errors}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::warnings_as_errors); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::ld_opt::library_path, \"foo\"}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::library_path, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::ld_opt::link, \"foo\"}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::link, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::ld_opt::cpp_std, \"foo\"}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::cpp_std, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::ld_opt::build_shared}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::build_shared); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::ld_opt::threads}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::threads); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::ld_opt::position_independent_code}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::position_independent_code); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::ld_opt::position_independent_executable}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::position_independent_executable); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "{ctor::ld_opt::custom, \"-foo\"}" }; act = ld_option(ctor::toolchain::any, ctor::ld_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); } void getOption_toolchain_ar_test() @@ -683,53 +686,53 @@ public: // exp = { "-r" }; act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::replace); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-s" }; act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::add_index); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-c" }; act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::create); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "foo" }; act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::output, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-foo" }; act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // clang // exp = { "-r" }; act = ar_option(ctor::toolchain::clang, ctor::ar_opt::replace); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-s" }; act = ar_option(ctor::toolchain::clang, ctor::ar_opt::add_index); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-c" }; act = ar_option(ctor::toolchain::clang, ctor::ar_opt::create); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "foo" }; act = ar_option(ctor::toolchain::clang, ctor::ar_opt::output, "foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { "-foo" }; act = ar_option(ctor::toolchain::clang, ctor::ar_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // any // exp = { "{ctor::ar_opt::custom, \"-foo\"}" }; act = ar_option(ctor::toolchain::any, ctor::ar_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); } void getOption_toolchain_asm_test() @@ -742,21 +745,21 @@ public: // exp = { "-foo" }; act = asm_option(ctor::toolchain::gcc, ctor::asm_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // clang // exp = { "-foo" }; act = asm_option(ctor::toolchain::clang, ctor::asm_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // any // exp = { "{ctor::asm_opt::custom, \"-foo\"}" }; act = asm_option(ctor::toolchain::any, ctor::asm_opt::custom, "-foo"); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); } @@ -770,22 +773,22 @@ public: // exp = { ctor::c_opt::include_path, "foo" }; act = c_option("-Ifoo", ctor::toolchain::gcc); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { ctor::c_opt::custom, "foo" }; act = c_option("foo", ctor::toolchain::gcc); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // clang // exp = { ctor::c_opt::include_path, "foo" }; act = c_option("-Ifoo", ctor::toolchain::clang); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { ctor::c_opt::custom, "foo" }; act = c_option("foo", ctor::toolchain::clang); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); } void getOption_str_cxx_test() @@ -798,22 +801,22 @@ public: // exp = { ctor::cxx_opt::include_path, "foo" }; act = cxx_option("-Ifoo", ctor::toolchain::gcc); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { ctor::cxx_opt::custom, "foo" }; act = cxx_option("foo", ctor::toolchain::gcc); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // clang // exp = { ctor::cxx_opt::include_path, "foo" }; act = cxx_option("-Ifoo", ctor::toolchain::clang); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { ctor::cxx_opt::custom, "foo" }; act = cxx_option("foo", ctor::toolchain::clang); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); } void getOption_str_ld_test() @@ -826,22 +829,22 @@ public: // exp = { ctor::ld_opt::library_path, "foo" }; act = ld_option("-Lfoo", ctor::toolchain::gcc); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { ctor::ld_opt::custom, "foo" }; act = ld_option("foo", ctor::toolchain::gcc); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // clang // exp = { ctor::ld_opt::library_path, "foo" }; act = ld_option("-Lfoo", ctor::toolchain::clang); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); exp = { ctor::ld_opt::custom, "foo" }; act = ld_option("foo", ctor::toolchain::clang); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); } void getOption_str_ar_test() @@ -854,14 +857,14 @@ public: // exp = { ctor::ar_opt::custom, "foo" }; act = ar_option("foo", ctor::toolchain::gcc); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // clang // exp = { ctor::ar_opt::custom, "foo" }; act = ar_option("foo", ctor::toolchain::clang); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); } void getOption_str_asm_test() @@ -874,14 +877,14 @@ public: // exp = { ctor::asm_opt::custom, "foo" }; act = asm_option("foo", ctor::toolchain::gcc); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); // // clang // exp = { ctor::asm_opt::custom, "foo" }; act = asm_option("foo", ctor::toolchain::clang); - uASSERT_EQUAL(exp, act); + assert_equal(exp, act, __FILE__, __LINE__); } @@ -893,7 +896,7 @@ public: // 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); + assert_equal(exp, act, __FILE__, __LINE__); } void to_strings_cxx_test() @@ -904,7 +907,7 @@ public: // 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); + assert_equal(exp, act, __FILE__, __LINE__); } void to_strings_ld_test() @@ -915,7 +918,7 @@ public: // 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); + assert_equal(exp, act, __FILE__, __LINE__); } void to_strings_ar_test() @@ -926,7 +929,7 @@ public: // 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); + assert_equal(exp, act, __FILE__, __LINE__); } void to_strings_asm_test() @@ -937,7 +940,7 @@ public: // 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); + assert_equal(exp, act, __FILE__, __LINE__); } }; -- cgit v1.2.3