diff --git a/.github/workflows/build-and-test-workflow.yml b/.github/workflows/build-and-test-workflow.yml index 3d1f87c62f..a0c368eadd 100644 --- a/.github/workflows/build-and-test-workflow.yml +++ b/.github/workflows/build-and-test-workflow.yml @@ -14,28 +14,11 @@ on: jobs: build: - # Build platform runs-on: ${{ inputs.platform }} - name: ${{ inputs.platform }}-${{ inputs.build_type }} - # The default compiler on macos is clang, switch to gcc. Specifying the version is necessary. - # It seems like gcc and g++ are symbolic links to the default clang and clang++ compilers, respectively. - # CMAKE_CXX_COMPILER_ID will evaluate to AppleClang rather than GNU on macos. - env: - CC: gcc-12 - CXX: g++-12 - # Build steps steps: - # Step: Install GCC (macOS only) - - name: Install GCC - if: startsWith(runner.os, 'macOS') - run: | - brew install gcc@12 - echo "CC=$(brew --prefix)/bin/gcc-12" >> $GITHUB_ENV - echo "CXX=$(brew --prefix)/bin/g++-12" >> $GITHUB_ENV - # Step: Checkout - name: Checkout uses: actions/checkout@v4 @@ -43,6 +26,15 @@ jobs: with: fetch-depth: 0 + # Step: Set compiler (use system Clang for all macOS versions) + - name: Set compiler (macOS Clang) + if: runner.os == 'macOS' + run: | + echo "Using system Clang for ${{ inputs.platform }}" + echo "CC=clang" >> "$GITHUB_ENV" + echo "CXX=clang++" >> "$GITHUB_ENV" + echo "Configured Clang toolchain: $(clang --version | head -n 1)" + # Step: Set paths - name: Set paths id: paths @@ -59,13 +51,26 @@ jobs: sudo apt-get install libboost-all-dev doxygen fi + # Step: Install OpenMP + - name: Install OpenMP + run: brew install libomp + + # Step: Set OpenMP environment variables + - name: Set OpenMP environment variables + run: | + echo "LDFLAGS=-L/opt/homebrew/opt/libomp/lib" >> $GITHUB_ENV + echo "CPPFLAGS=-I/opt/homebrew/opt/libomp/include" >> $GITHUB_ENV + echo "Debug: Checking OpenMP installation:" + ls -la /opt/homebrew/opt/libomp/lib/ || echo "OpenMP lib directory not found" + ls -la /opt/homebrew/opt/libomp/include/ || echo "OpenMP include directory not found" + file /opt/homebrew/opt/libomp/lib/libomp.dylib || echo "libomp.dylib not found" + # Step: Restore cached user-provided dependencies - name: Restore cached user-provided dependencies uses: actions/cache/restore@v4 id: restore-cached-external-dependencies with: - key: ${{ inputs.platform }}-${{ inputs.build_type }}-cache-key-v4 - restore-keys: ${{ inputs.platform }}-${{ inputs.build_type }}-cache-key-v4 + key: ${{ inputs.platform }}-${{ inputs.build_type }}-cache-key-v5 path: ${{ steps.paths.outputs.ext_deps_dir }}/netcdf-c/install/netcdf-c # Step: Check if netCDF cache directory already has contents (defensive guard) @@ -95,7 +100,7 @@ jobs: uses: actions/cache/save@v4 if: steps.check-nc-cache.outputs.has-deps == 'false' with: - key: ${{ inputs.platform }}-${{ inputs.build_type }}-cache-key-v4 + key: ${{ inputs.platform }}-${{ inputs.build_type }}-cache-key-v5 path: ${{ steps.paths.outputs.ext_deps_dir }}/netcdf-c/install/netcdf-c # Step: CMake configuration @@ -107,10 +112,21 @@ jobs: -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DCMAKE_PREFIX_PATH=${{ steps.paths.outputs.ext_deps_dir }}/netcdf-c/install/netcdf-c -DCMAKE_INSTALL_PREFIX=${{ steps.paths.outputs.install_dir }} + -DCMAKE_VERBOSE_MAKEFILE=ON + -DCMAKE_OSX_ARCHITECTURES=arm64 + -DOpenMP_C_FLAGS="-Xpreprocessor -fopenmp -I/opt/homebrew/opt/libomp/include" + -DOpenMP_CXX_FLAGS="-Xpreprocessor -fopenmp -I/opt/homebrew/opt/libomp/include" + -DOpenMP_C_LIB_NAMES="omp" + -DOpenMP_CXX_LIB_NAMES="omp" + -DOpenMP_omp_LIBRARY="/opt/homebrew/opt/libomp/lib/libomp.dylib" + -DCMAKE_C_FLAGS="-Xpreprocessor -fopenmp -I/opt/homebrew/opt/libomp/include" + -DCMAKE_CXX_FLAGS="-Xpreprocessor -fopenmp -I/opt/homebrew/opt/libomp/include -v" + -DCMAKE_EXE_LINKER_FLAGS="-L/opt/homebrew/opt/libomp/lib -lomp -Wl,-v" + -DCMAKE_SHARED_LINKER_FLAGS="-L/opt/homebrew/opt/libomp/lib -lomp -Wl,-v" # Step: CMake build - name: Build - run: cmake --build ${{ steps.paths.outputs.build_dir }} --config ${{ inputs.build_type }} -j 4 + run: cmake --build ${{ steps.paths.outputs.build_dir }} --config ${{ inputs.build_type }} -j 4 --verbose # Step: Test # Works if runner.os == 'Linux' or runner.os == 'macOS' diff --git a/cmake/compiler_config.cmake b/cmake/compiler_config.cmake index 76d86a0cc6..312139a98a 100644 --- a/cmake/compiler_config.cmake +++ b/cmake/compiler_config.cmake @@ -9,22 +9,41 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Add compiler-specific options and definitions per supported platform -if (UNIX) - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") +if(APPLE) + # macOS: support AppleClang / Clang (system toolchain). GCC may also be supported but Clang is preferred. + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + message(STATUS "Configuring build for macOS with ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER_VERSION}).") + # Common warning and visibility flags + add_compile_options("-fvisibility=hidden;-Wall;-Wextra;-pedantic;-Werror;-Wno-unused-function") + # Be lenient for Eigen (deprecated enum conversion) on all macOS Clang builds + add_compile_options($<$:-Wno-deprecated-enum-enum-conversion>) + # Optimization / debug flags + add_compile_options("$<$:-O2>") + add_compile_options("$<$:-g>") + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # Fallback: allow GNU on macOS if explicitly selected + message(STATUS "Configuring build for macOS with GNU ${CMAKE_CXX_COMPILER_VERSION}.") add_compile_options("-fvisibility=hidden;-Werror;-Wall;-Wextra;-pedantic;-Wno-unused-function") - - if(APPLE AND (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm64")) + if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm64") # CMake automatically sets -Xarch_arm64 (for clang) but gcc doesn't support it unset(_CMAKE_APPLE_ARCHS_DEFAULT) - # Be lenient on macos with arm64 toolchain to prevent Eigen -Werror=deprecated-enum-enum-conversion error add_compile_options($<$:-Wno-deprecated-enum-enum-conversion>) - # Suppress notes related to ABI changes add_compile_options($<$:-Wno-psabi>) endif() add_compile_options("$<$:-O2>") add_compile_options("$<$:-g>") else() - message(FATAL_ERROR "Unsupported compiler. Only GNU is supported under Linux. Found ${CMAKE_CXX_COMPILER_ID}.") + message(FATAL_ERROR "Unsupported compiler on macOS. Supported: AppleClang/Clang or GNU. Found ${CMAKE_CXX_COMPILER_ID}.") + endif() +elseif(UNIX) + # Linux: require GNU + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + message(STATUS "Configuring build for Linux with GNU ${CMAKE_CXX_COMPILER_VERSION}.") + add_compile_options("-fvisibility=hidden;-Werror;-Wall;-Wextra;-pedantic;-Wno-unused-function") + add_compile_options("$<$:-O2>") + add_compile_options("$<$:-g>") + else() + message(FATAL_ERROR "Unsupported compiler on Linux. Only GNU is supported. Found ${CMAKE_CXX_COMPILER_ID}.") endif() elseif(WIN32) if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") @@ -37,7 +56,7 @@ elseif(WIN32) message(FATAL_ERROR "Unsupported compiler. Only MSVC is supported under Windows. Found ${CMAKE_CXX_COMPILER_ID}.") endif() else() - message(FATAL_ERROR "Unsupported platform. Only Linux and Windows are supported.") + message(FATAL_ERROR "Unsupported platform. Only macOS, Linux and Windows are supported.") endif() # CMAKE_SOURCE_DIR is passed to the src in order to strip it out of the path of srcs where exceptions may occur diff --git a/cmake/fetch_content.cmake b/cmake/fetch_content.cmake index 507265118a..c280a1b561 100644 --- a/cmake/fetch_content.cmake +++ b/cmake/fetch_content.cmake @@ -70,7 +70,7 @@ if(${USE_LIBFMT}) FetchContent_Declare( Eigen GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git - GIT_TAG 21cd3fe20990a5ac1d683806f605110962aac3f1 + GIT_TAG 549bf8c75b6aae071cde2f28aa48f16ee3ae60b0 ) FetchContent_MakeAvailable(Eigen) diff --git a/extern/triangle/CMakeLists.txt b/extern/triangle/CMakeLists.txt index 8d9cb93fc6..d2a45126a5 100644 --- a/extern/triangle/CMakeLists.txt +++ b/extern/triangle/CMakeLists.txt @@ -38,10 +38,11 @@ target_compile_definitions( ) # platform-specific compiler options and definitions for disabling warnings -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - target_compile_options(${target_name} PRIVATE "-w") -elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - target_compile_options(${target_name} PRIVATE "/w") +# Use the C compiler ID because this target is pure C. Disable warnings for GCC and Clang. +if(CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") + target_compile_options(${target_name} PRIVATE -w) +elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC") + target_compile_options(${target_name} PRIVATE /w) endif() # group the sources and headers in IDE project generation diff --git a/libs/MeshKernel/include/MeshKernel/Constants.hpp b/libs/MeshKernel/include/MeshKernel/Constants.hpp index 96c5de1731..8cd340b685 100644 --- a/libs/MeshKernel/include/MeshKernel/Constants.hpp +++ b/libs/MeshKernel/include/MeshKernel/Constants.hpp @@ -33,14 +33,15 @@ #include #include -#if defined(__linux__) || defined(__APPLE__) +#if defined(__GNUC__) && !defined(__clang__) +// GCC only: suppress -Wmaybe-uninitialized (not recognized by Clang / AppleClang) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif #include -#if defined(__linux__) || defined(__APPLE__) +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif diff --git a/libs/MeshKernel/include/MeshKernel/LandBoundaries.hpp b/libs/MeshKernel/include/MeshKernel/LandBoundaries.hpp index bba2dd4265..7134f58a35 100644 --- a/libs/MeshKernel/include/MeshKernel/LandBoundaries.hpp +++ b/libs/MeshKernel/include/MeshKernel/LandBoundaries.hpp @@ -35,6 +35,11 @@ #include +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdefaulted-function-deleted" +#endif + namespace meshkernel { class Polygons; @@ -246,3 +251,7 @@ namespace meshkernel }; } // namespace meshkernel + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif \ No newline at end of file diff --git a/libs/MeshKernel/include/MeshKernel/Mesh2DToCurvilinear.hpp b/libs/MeshKernel/include/MeshKernel/Mesh2DToCurvilinear.hpp index 6bb123151c..9415467032 100644 --- a/libs/MeshKernel/include/MeshKernel/Mesh2DToCurvilinear.hpp +++ b/libs/MeshKernel/include/MeshKernel/Mesh2DToCurvilinear.hpp @@ -211,8 +211,7 @@ namespace meshkernel {1, 0}, {0, 1}}}; ///< increments for the new nodes depending on the node direction - const int n_maxNumRowsColumns = 1000000; ///< The maximum number of allowed rows or columns - + MatrixWithNegativeIndices m_mapping; ///< Unstructured node indices in the curvilinear grid }; diff --git a/libs/MeshKernel/include/MeshKernel/ProjectionConversions.hpp b/libs/MeshKernel/include/MeshKernel/ProjectionConversions.hpp index 92465a7a4b..cf2c049da8 100644 --- a/libs/MeshKernel/include/MeshKernel/ProjectionConversions.hpp +++ b/libs/MeshKernel/include/MeshKernel/ProjectionConversions.hpp @@ -29,7 +29,8 @@ #include -#if defined(__linux__) || defined(__APPLE__) +#if defined(__GNUC__) && !defined(__clang__) +// GCC only: suppress -Wmaybe-uninitialized (Clang/AppleClang doesn't support it) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif @@ -39,7 +40,7 @@ #include #undef BOOST_ALLOW_DEPRECATED_HEADERS -#if defined(__linux__) || defined(__APPLE__) +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif diff --git a/libs/MeshKernel/include/MeshKernel/Utilities/LinearAlgebra.hpp b/libs/MeshKernel/include/MeshKernel/Utilities/LinearAlgebra.hpp index 0acf1301a0..91472e4204 100644 --- a/libs/MeshKernel/include/MeshKernel/Utilities/LinearAlgebra.hpp +++ b/libs/MeshKernel/include/MeshKernel/Utilities/LinearAlgebra.hpp @@ -30,14 +30,15 @@ #include "MeshKernel/Definitions.hpp" #include "MeshKernel/Exceptions.hpp" -#ifdef __linux__ +#if defined(__GNUC__) && !defined(__clang__) +// GCC only: suppress -Wmaybe-uninitialized (Clang does not have this warning group) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif #include #include -#ifdef __linux__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif diff --git a/libs/MeshKernel/src/Mesh2D.cpp b/libs/MeshKernel/src/Mesh2D.cpp index 472f692c7c..236acd5e4f 100644 --- a/libs/MeshKernel/src/Mesh2D.cpp +++ b/libs/MeshKernel/src/Mesh2D.cpp @@ -2672,7 +2672,7 @@ std::vector Mesh2D::NodeMaskFromPolygon(const Polygons& polygon, bool insid for (UInt i = 0; i < nodeMask.size(); ++i) { - auto isInPolygon = nodePolygonIndices[i]; + bool isInPolygon = static_cast(nodePolygonIndices[i]); if (!inside) { isInPolygon = !isInPolygon; diff --git a/tools/test_utils/src/MakeCurvilinearGrids.cpp b/tools/test_utils/src/MakeCurvilinearGrids.cpp index a059fa5193..7d045bc00c 100644 --- a/tools/test_utils/src/MakeCurvilinearGrids.cpp +++ b/tools/test_utils/src/MakeCurvilinearGrids.cpp @@ -25,7 +25,6 @@ size_t CurvilinearGridCountValidNodes(meshkernelapi::CurvilinearGrid const& curv size_t CurvilinearGridCountValidNodes(meshkernel::CurvilinearGrid const& curvilinearGrid) { size_t validNodes = 0; - size_t index = 0; for (meshkernel::UInt n = 0; n < curvilinearGrid.NumN(); ++n) { for (meshkernel::UInt m = 0; m < curvilinearGrid.NumM(); ++m) @@ -34,7 +33,6 @@ size_t CurvilinearGridCountValidNodes(meshkernel::CurvilinearGrid const& curvili { validNodes++; } - index++; } } return validNodes;