From 5ae2c7d511eea5eedf699e7930a75d0e914cb044 Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 4 Aug 2025 13:32:53 +0200 Subject: [PATCH 1/5] added MinGW workflow Co-authored-by: glankk --- .github/workflows/CI-mingw.yml | 114 +++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 .github/workflows/CI-mingw.yml diff --git a/.github/workflows/CI-mingw.yml b/.github/workflows/CI-mingw.yml new file mode 100644 index 00000000..d2020825 --- /dev/null +++ b/.github/workflows/CI-mingw.yml @@ -0,0 +1,114 @@ +name: CI-mingw + +on: [push, pull_request] + +permissions: + contents: read + +defaults: + run: + shell: msys2 {0} + +jobs: + build: + + strategy: + matrix: + compiler: [g++, clang++] + msystem: [MSYS, MINGW32, MINGW64, CLANG64] + include: + - msystem: MSYS + pkg-prefix: '' + - msystem: MINGW32 + pkg-prefix: 'mingw-w64-i686-' + - msystem: MINGW64 + pkg-prefix: 'mingw-w64-x86_64-' + - msystem: CLANG64 + pkg-prefix: 'mingw-w64-clang-x86_64-' + - compiler: g++ + compiler-pkg: gcc + - compiler: clang++ + compiler-pkg: clang + exclude: + - msystem: CLANG64 + compiler: g++ + fail-fast: false + + runs-on: windows-2025 + + env: + CXX: ${{ matrix.compiler }} + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up MSYS2 + uses: msys2/setup-msys2@v2 + with: + release: false # use pre-installed + msystem: ${{ matrix.msystem }} + # TODO: install mingw-w64-x86_64-make and use mingw32.make instead - currently fails with "Windows Subsystem for Linux has no installed distributions." + # TODO: also run tests with non-prefixed Python? + install: >- + make + ${{ matrix.pkg-prefix }}cmake + ${{ matrix.pkg-prefix }}python + ${{ matrix.pkg-prefix }}python-pytest + + - name: install compiler + run: | + pacman -S --noconfirm ${{ matrix.pkg-prefix }}${{ matrix.compiler-pkg }} + ${CXX} -v + + - name: make simplecpp + run: | + make -j$(nproc) CXXOPTS="-Werror" + + # gcc *and* clang are required to run-tests.py + # install it at this point since it has gcc as dependency which might interfere with the build + - name: install compiler (clang) + if: matrix.compiler == 'g++' + run: | + pacman -S --noconfirm clang + + - name: install compiler (gcc) + if: matrix.compiler == 'clang++' + run: | + pacman -S --noconfirm gcc + + - name: make test + run: make -j$(nproc) test + + - name: selfcheck + run: | + make -j$(nproc) selfcheck + + - name: Run CMake + run: | + cmake -S . -B cmake.output -DCMAKE_COMPILE_WARNING_AS_ERROR=On + + - name: CMake simplecpp + run: | + cmake --build cmake.output --target simplecpp -- -j $(nproc) + + - name: CMake testrunner + run: | + cmake --build cmake.output --target testrunner -- -j $(nproc) + + - name: Run testrunner + run: | + ./cmake.output/testrunner + + - name: Run with libstdc++ debug mode + if: matrix.compiler == 'g++' + run: | + make clean + make -j$(nproc) test selfcheck CXXOPTS="-Werror -g3 -D_GLIBCXX_DEBUG" + + - name: Run with libc++ hardening mode + if: matrix.compiler == 'clang++' && matrix.msystem == 'CLANG64' + run: | + make clean + make -j$(nproc) test selfcheck CXXOPTS="-Werror -stdlib=libc++ -g3 -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG" LDOPTS="-lc++" From 932bccd23a4838ff6163986a1d154449dc55bbf5 Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 2 Sep 2025 09:24:25 +0200 Subject: [PATCH 2/5] mitigated some compiler warnings Co-authored-by: glankk --- CMakeLists.txt | 12 +++++++++++- simplecpp.cpp | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f13fb3fb..1884796b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,9 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") add_compile_options(-Woverloaded-virtual) # when a function declaration hides virtual functions from a base class add_compile_options(-Wsuggest-attribute=noreturn) - add_compile_options_safe(-Wuseless-cast) + if (NOT MINGW) + add_compile_options_safe(-Wuseless-cast) + endif() # we are not interested in these set_source_files_properties(test.cpp PROPERTIES COMPILE_FLAGS -Wno-multichar) @@ -62,6 +64,14 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") # contradicts -Wcovered-switch-default add_compile_options(-Wno-switch-default) + if (MINGW) + add_compile_options(-Wno-reserved-macro-identifier) + add_compile_options(-Wno-unused-macros) + endif() + + # these are experimental warning which might produce false positives + add_compile_options_safe(-Wno-thread-safety-negative) + add_compile_options_safe(-Wno-thread-safety-beta) # TODO: fix these? add_compile_options(-Wno-padded) diff --git a/simplecpp.cpp b/simplecpp.cpp index d56a6ce8..548a2250 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -3121,7 +3121,7 @@ std::pair simplecpp::FileDataCache::get(const std:: bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id) { #ifdef _WIN32 - HANDLE hFile = CreateFileA(path.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE hFile = CreateFileA(path.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) return false; From 6b50ff4325ff0843e69a7b31c71b0627d79da657 Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 17 Sep 2025 09:56:12 +0200 Subject: [PATCH 3/5] selfcheck.sh: adjustments for MinGW --- selfcheck.sh | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/selfcheck.sh b/selfcheck.sh index e708023a..b2129cc9 100755 --- a/selfcheck.sh +++ b/selfcheck.sh @@ -41,16 +41,20 @@ if [ "$cxx_type" = "Ubuntu" ] || [ "$cxx_type" = "Debian" ]; then fi # TODO: generate defines from compiler -if [ "$cxx_type" = "g++" ]; then +if [ "$cxx_type" = "g++" ] || [ "$cxx_type" = "g++.exe" ]; then defs= defs="$defs -D__GNUC__" defs="$defs -D__STDC__" defs="$defs -D__x86_64__" defs="$defs -D__STDC_HOSTED__" defs="$defs -D__CHAR_BIT__=8" + if [ "${MSYSTEM}" = "MINGW32" ] || [ "${MSYSTEM}" = "MINGW64" ]; then + defs="$defs -D_WIN32" + fi defs="$defs -D__has_builtin(x)=(1)" defs="$defs -D__has_cpp_attribute(x)=(1)" defs="$defs -D__has_attribute(x)=(1)" + defs="$defs -Ddefined(x)=(0)" inc= while read line @@ -63,12 +67,19 @@ elif [ "$cxx_type" = "clang" ]; then defs="$defs -D__x86_64__" defs="$defs -D__STDC_HOSTED__" defs="$defs -D__CHAR_BIT__=8" + defs="$defs -D__BYTE_ORDER__=1234" + defs="$defs -D__SIZEOF_SIZE_T__=8" + if [ "${MSYSTEM}" = "MINGW32" ] || [ "${MSYSTEM}" = "MINGW64" ] || [ "${MSYSTEM}" = "CLANG64" ]; then + defs="$defs -D_WIN32" + fi defs="$defs -D__has_builtin(x)=(1)" defs="$defs -D__has_cpp_attribute(x)=(1)" defs="$defs -D__has_feature(x)=(1)" - defs="$defs -D__has_include_next(x)=(0)" + defs="$defs -D__has_include_next(x)=(1)" defs="$defs -D__has_attribute(x)=(0)" defs="$defs -D__building_module(x)=(0)" + defs="$defs -D__has_extension(x)=(1)" + defs="$defs -Ddefined(x)=(0)" inc= while read line From d8e95d7e6252e155c9d3aa7fae57b43cb01a6584 Mon Sep 17 00:00:00 2001 From: firewave Date: Fri, 3 Oct 2025 11:26:31 +0200 Subject: [PATCH 4/5] abs --- .github/workflows/CI-mingw.yml | 5 +++- simplecpp.cpp | 8 ++++--- test.cpp | 44 ++++++++++++++++++++-------------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/.github/workflows/CI-mingw.yml b/.github/workflows/CI-mingw.yml index d2020825..eeba6a10 100644 --- a/.github/workflows/CI-mingw.yml +++ b/.github/workflows/CI-mingw.yml @@ -79,10 +79,13 @@ jobs: pacman -S --noconfirm gcc - name: make test - run: make -j$(nproc) test + run: | + # TODO: run tests with Windows paths + make -j$(nproc) test - name: selfcheck run: | + # TODO: run tests with Windows paths make -j$(nproc) selfcheck - name: Run CMake diff --git a/simplecpp.cpp b/simplecpp.cpp index 548a2250..1bdd5a70 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -2449,7 +2449,7 @@ namespace simplecpp { bool isAbsolutePath(const std::string &path) { -#ifdef SIMPLECPP_WINDOWS +#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MSYS__) // C:\\path\\file // C:/path/file if (path.length() >= 3 && std::isalpha(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) @@ -2459,10 +2459,12 @@ namespace simplecpp { // //host/path/file if (path.length() >= 2 && (path[0] == '\\' || path[0] == '/') && (path[1] == '\\' || path[1] == '/')) return true; +#endif - return false; -#else +#if !defined(_WIN32) || defined(__MINGW32__) return !path.empty() && path[0] == '/'; +#else + return false; #endif } } diff --git a/test.cpp b/test.cpp index 26e3b95b..3922cb38 100644 --- a/test.cpp +++ b/test.cpp @@ -3257,36 +3257,44 @@ static void safe_api() } static void isAbsolutePath() { -#ifdef _WIN32 - ASSERT_EQUALS(true, simplecpp::isAbsolutePath("C:\\foo\\bar")); - ASSERT_EQUALS(true, simplecpp::isAbsolutePath("C:/foo/bar")); - ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\\\foo\\bar")); +#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MSYS__) + constexpr bool supportsWin = true; +#else + constexpr bool supportsWin = false; +#endif + +#if !defined(_WIN32) || defined(__MINGW32__) + constexpr bool supportsUnx = true; +#else + constexpr bool supportsUnx = false; +#endif + + // valid Windows paths + ASSERT_EQUALS(supportsWin, simplecpp::isAbsolutePath("C:\\foo\\bar")); + ASSERT_EQUALS(supportsWin, simplecpp::isAbsolutePath("C:/foo/bar")); + ASSERT_EQUALS(supportsWin, simplecpp::isAbsolutePath("\\\\foo\\bar")); + + // valid Unix paths + ASSERT_EQUALS(supportsUnx, simplecpp::isAbsolutePath("/foo/bar")); + ASSERT_EQUALS(supportsUnx, simplecpp::isAbsolutePath("/")); + + // valid Windows and Unix paths + ASSERT_EQUALS(supportsWin || supportsUnx, simplecpp::isAbsolutePath("//host/foo/bar")); + // invalid paths ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo\\bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo/bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo.cpp")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:foo.cpp")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:foo\\bar.cpp")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("bar.cpp")); - //ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\")); // TODO ASSERT_EQUALS(false, simplecpp::isAbsolutePath("0:\\foo\\bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("0:/foo/bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\foo\\bar")); + + //ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\")); // TODO //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\\\")); // TODO //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("//")); // TODO - ASSERT_EQUALS(false, simplecpp::isAbsolutePath("/foo/bar")); - ASSERT_EQUALS(false, simplecpp::isAbsolutePath("/")); -#else - ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/foo/bar")); - ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/")); - ASSERT_EQUALS(true, simplecpp::isAbsolutePath("//host/foo/bar")); - - ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo/bar")); - ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo.cpp")); - ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:\\foo\\bar")); - ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:/foo/bar")); - ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\\\foo\\bar")); -#endif } // crashes detected by fuzzer From 6714ec125ae06b60457689f8d149ff6a9f3ac480 Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 22 Oct 2025 13:14:43 +0200 Subject: [PATCH 5/5] revert --- simplecpp.cpp | 8 +++----- test.cpp | 44 ++++++++++++++++++-------------------------- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 1bdd5a70..548a2250 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -2449,7 +2449,7 @@ namespace simplecpp { bool isAbsolutePath(const std::string &path) { -#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MSYS__) +#ifdef SIMPLECPP_WINDOWS // C:\\path\\file // C:/path/file if (path.length() >= 3 && std::isalpha(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) @@ -2459,12 +2459,10 @@ namespace simplecpp { // //host/path/file if (path.length() >= 2 && (path[0] == '\\' || path[0] == '/') && (path[1] == '\\' || path[1] == '/')) return true; -#endif -#if !defined(_WIN32) || defined(__MINGW32__) - return !path.empty() && path[0] == '/'; -#else return false; +#else + return !path.empty() && path[0] == '/'; #endif } } diff --git a/test.cpp b/test.cpp index 3922cb38..26e3b95b 100644 --- a/test.cpp +++ b/test.cpp @@ -3257,44 +3257,36 @@ static void safe_api() } static void isAbsolutePath() { -#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MSYS__) - constexpr bool supportsWin = true; -#else - constexpr bool supportsWin = false; -#endif - -#if !defined(_WIN32) || defined(__MINGW32__) - constexpr bool supportsUnx = true; -#else - constexpr bool supportsUnx = false; -#endif - - // valid Windows paths - ASSERT_EQUALS(supportsWin, simplecpp::isAbsolutePath("C:\\foo\\bar")); - ASSERT_EQUALS(supportsWin, simplecpp::isAbsolutePath("C:/foo/bar")); - ASSERT_EQUALS(supportsWin, simplecpp::isAbsolutePath("\\\\foo\\bar")); - - // valid Unix paths - ASSERT_EQUALS(supportsUnx, simplecpp::isAbsolutePath("/foo/bar")); - ASSERT_EQUALS(supportsUnx, simplecpp::isAbsolutePath("/")); - - // valid Windows and Unix paths - ASSERT_EQUALS(supportsWin || supportsUnx, simplecpp::isAbsolutePath("//host/foo/bar")); +#ifdef _WIN32 + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("C:\\foo\\bar")); + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("C:/foo/bar")); + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\\\foo\\bar")); - // invalid paths ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo\\bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo/bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo.cpp")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:foo.cpp")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:foo\\bar.cpp")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("bar.cpp")); + //ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\")); // TODO ASSERT_EQUALS(false, simplecpp::isAbsolutePath("0:\\foo\\bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("0:/foo/bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\foo\\bar")); - - //ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\")); // TODO //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\\\")); // TODO //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("//")); // TODO + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("/foo/bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("/")); +#else + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/foo/bar")); + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/")); + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("//host/foo/bar")); + + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo/bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo.cpp")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:\\foo\\bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:/foo/bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\\\foo\\bar")); +#endif } // crashes detected by fuzzer