Skip to content

Commit 77f0abb

Browse files
feat(cmake): add Intel oneAPI compiler (ICX/ICPX) support
- Add IntelLLVM to all compiler detection points: CompilerWarnings, StandardProjectSettings, Hardening, Sanitizers, Tests, StaticAnalyzers, ProjectOptions - Add Intel to CI matrix (Linux only) - Install oneAPI directly from Intel apt repo - Pre-install Conan deps with clang profile (binary compatible) and skip auto-provider via myproject_SKIP_CONAN_PROVIDER - Skip gcovr and codecov for Intel (incompatible coverage format) Signed-off-by: Helder Ferreira <helder@versatushpc.com.br> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b68d6e9 commit 77f0abb

12 files changed

Lines changed: 118 additions & 72 deletions

.github/workflows/ci.yml

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ jobs:
3838
# you can specify the version after `-` like "llvm-15.0.2".
3939
- llvm-19.1.1
4040
- gcc-14
41+
- intel
4142
generator:
4243
- "Ninja Multi-Config"
4344
build_type:
@@ -54,6 +55,12 @@ jobs:
5455
- os: windows-latest
5556
compiler: gcc-14
5657

58+
# Intel oneAPI is only available on Linux
59+
- os: windows-latest
60+
compiler: intel
61+
- os: macos-latest
62+
compiler: intel
63+
5764
include:
5865
# Add appropriate variables for gcov version required. This will intentionally break
5966
# if you try to use a compiler that does not have gcov set
@@ -65,6 +72,10 @@ jobs:
6572
enable_ipo: Off
6673
gcov_executable: "llvm-cov gcov"
6774

75+
- compiler: intel
76+
enable_ipo: Off
77+
gcov_executable: gcov
78+
6879
- os: macos-latest
6980
enable_ipo: Off
7081

@@ -144,6 +155,7 @@ jobs:
144155

145156

146157
- name: Setup Cpp
158+
if: ${{ matrix.compiler != 'intel' }}
147159
uses: aminya/setup-cpp@v1
148160
with:
149161
compiler: ${{ matrix.compiler }}
@@ -161,9 +173,39 @@ jobs:
161173
gcovr: true
162174
opencppcoverage: true
163175

176+
- name: Install Intel oneAPI
177+
if: ${{ matrix.compiler == 'intel' }}
178+
run: |
179+
wget -qO- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB | sudo gpg --dearmor -o /usr/share/keyrings/oneapi-archive-keyring.gpg
180+
echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
181+
sudo apt-get update
182+
sudo apt-get install -y intel-oneapi-compiler-dpcpp-cpp cmake ninja-build ccache cppcheck gcovr
183+
184+
- name: Configure Intel oneAPI environment
185+
if: ${{ matrix.compiler == 'intel' }}
186+
run: |
187+
echo "/opt/intel/oneapi/compiler/latest/bin" >> $GITHUB_PATH
188+
echo "LD_LIBRARY_PATH=/opt/intel/oneapi/compiler/latest/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV
189+
echo "CC=icx" >> $GITHUB_ENV
190+
echo "CXX=icpx" >> $GITHUB_ENV
191+
164192
- name: Install Conan and Lizard
165193
run: pip install conan lizard
166194

195+
- name: Configure Conan for Intel ICX
196+
if: ${{ matrix.compiler == 'intel' }}
197+
run: |
198+
ICX=/opt/intel/oneapi/compiler/latest/bin/icx
199+
ICX_CLANG_VER=$($ICX -dM -E -x c /dev/null 2>/dev/null | grep __clang_major__ | awk '{print $3}')
200+
echo "ICX underlying Clang version: $ICX_CLANG_VER"
201+
CC=clang CXX=clang++ conan profile detect --force
202+
sed -i "s/compiler.version=.*/compiler.version=$ICX_CLANG_VER/" ~/.conan2/profiles/default
203+
sed -i "s/compiler.cppstd=.*/compiler.cppstd=23/" ~/.conan2/profiles/default
204+
cat ~/.conan2/profiles/default
205+
conan install . --output-folder=build --build=missing -s build_type=Debug
206+
conan install . --output-folder=build --build=missing -s build_type=Release
207+
conan install . --output-folder=build --build=missing -s build_type=RelWithDebInfo
208+
167209
- name: Pre-install Conan deps for macOS GCC
168210
if: ${{ runner.os == 'macOS' && contains(matrix.compiler, 'gcc') }}
169211
run: |
@@ -194,8 +236,12 @@ jobs:
194236
run: |
195237
EXTRA_CMAKE_ARGS=""
196238
# macOS GCC: deps pre-installed with libstdc++11 profile
239+
if [[ "${{ matrix.compiler }}" == "intel" ]]; then
240+
EXTRA_CMAKE_ARGS="-D${{ env.PROJECT_NAME }}_SKIP_CONAN_PROVIDER=ON -DCMAKE_PREFIX_PATH=$PWD/build"
241+
fi
242+
# macOS GCC: deps pre-installed with libstdc++11 profile
197243
if [[ "${{ runner.os }}" == "macOS" && "${{ matrix.compiler }}" =~ gcc ]]; then
198-
EXTRA_CMAKE_ARGS="-Dmyproject_SKIP_CONAN_PROVIDER=ON -DCMAKE_PREFIX_PATH=$PWD/build"
244+
EXTRA_CMAKE_ARGS="-D${{ env.PROJECT_NAME }}_SKIP_CONAN_PROVIDER=ON -DCMAKE_PREFIX_PATH=$PWD/build"
199245
fi
200246
cmake -S . -B ./build -G "${{matrix.generator}}" $EXTRA_CMAKE_ARGS -D${{ env.PROJECT_NAME }}_ENABLE_IPO=${{matrix.enable_ipo }} -DCMAKE_BUILD_TYPE:STRING=${{matrix.build_type}} -D${{ env.PROJECT_NAME }}_PACKAGING_MAINTAINER_MODE:BOOL=${{matrix.packaging_maintainer_mode}} -D${{ env.PROJECT_NAME }}_ENABLE_COVERAGE:BOOL=${{ matrix.build_type == 'Debug' }} -D${{ env.PROJECT_NAME }}_ENABLE_BLOATY:BOOL=OFF -D${{ env.PROJECT_NAME }}_ENABLE_INCLUDE_WHAT_YOU_USE:BOOL=OFF -DGIT_SHA:STRING=${{ github.sha }}
201247
@@ -211,7 +257,10 @@ jobs:
211257
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
212258
run: |
213259
ctest -C ${{matrix.build_type}}
214-
gcovr -j ${{env.nproc}} --root ../ --print-summary --xml-pretty --xml coverage.xml . --gcov-executable '${{ matrix.gcov_executable }}'
260+
# Intel ICX uses a different coverage format incompatible with gcov
261+
if [[ "${{ matrix.compiler }}" != "intel" ]]; then
262+
gcovr -j ${{env.nproc}} --root ../ --print-summary --xml-pretty --xml coverage.xml . --gcov-executable '${{ matrix.gcov_executable }}'
263+
fi
215264
216265
- name: Windows - Test and coverage
217266
if: runner.os == 'Windows'
@@ -234,6 +283,7 @@ jobs:
234283
235284
236285
- name: Publish to codecov
286+
if: ${{ matrix.compiler != 'intel' }}
237287
uses: codecov/codecov-action@v5
238288
with:
239289
fail_ci_if_error: true

.github/workflows/codeql-analysis.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,12 @@ jobs:
8181
gcovr: false
8282
opencppcoverage: false
8383

84-
# make sure coverage is only enabled for Debug builds, since it sets -O0 to make sure coverage
85-
# has meaningful results
84+
- name: Install Conan and Lizard
85+
run: pip install conan lizard
86+
8687
- name: Configure CMake
8788
run: |
88-
cmake -S . -B ./build -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE:STRING=${{matrix.build_type}} -D${{ env.PROJECT_NAME }}_PACKAGING_MAINTAINER_MODE:BOOL=${{matrix.packaging_maintainer_mode}} -D${{ env.PROJECT_NAME }}_ENABLE_COVERAGE:BOOL=${{ matrix.build_type == 'Debug' }}
89+
cmake -S . -B ./build -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE:STRING=${{matrix.build_type}} -D${{ env.PROJECT_NAME }}_PACKAGING_MAINTAINER_MODE:BOOL=${{matrix.packaging_maintainer_mode}} -D${{ env.PROJECT_NAME }}_ENABLE_COVERAGE:BOOL=${{ matrix.build_type == 'Debug' }} -D${{ env.PROJECT_NAME }}_ENABLE_BLOATY:BOOL=OFF -D${{ env.PROJECT_NAME }}_ENABLE_INCLUDE_WHAT_YOU_USE:BOOL=OFF
8990
9091
# Initializes the CodeQL tools for scanning.
9192
- name: Initialize CodeQL

.github/workflows/wasm.yml

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
build-and-deploy:
1616
runs-on: ubuntu-latest
1717
steps:
18-
- uses: actions/checkout@v4
18+
- uses: actions/checkout@v6
1919

2020
- name: Setup Emscripten
2121
uses: mymindstorm/setup-emsdk@v14
@@ -28,12 +28,32 @@ jobs:
2828
sudo apt-get install -y ninja-build
2929
pip install conan lizard
3030
31+
- name: Project Name
32+
uses: cardinalby/export-env-action@v2
33+
with:
34+
envFile: '.github/constants.env'
35+
36+
- name: Configure Conan for Emscripten threading
37+
run: |
38+
# The cmake-conan provider auto-detects Emscripten but builds
39+
# packages without threading flags. FTXUI requires pthreads.
40+
# Configure the default Conan profile to pass -pthread so all
41+
# packages (especially spdlog) are built with atomics support.
42+
conan profile detect --force
43+
echo "" >> ~/.conan2/profiles/default
44+
echo "[conf]" >> ~/.conan2/profiles/default
45+
echo "tools.build:cflags=[\"-pthread\"]" >> ~/.conan2/profiles/default
46+
echo "tools.build:cxxflags=[\"-pthread\"]" >> ~/.conan2/profiles/default
47+
echo "tools.build:sharedlinkflags=[\"-pthread\"]" >> ~/.conan2/profiles/default
48+
echo "tools.build:exelinkflags=[\"-pthread\"]" >> ~/.conan2/profiles/default
49+
cat ~/.conan2/profiles/default
50+
3151
- name: Configure CMake
3252
run: |
3353
emcmake cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
34-
-Dmyproject_ENABLE_BLOATY=OFF \
35-
-Dmyproject_ENABLE_INCLUDE_WHAT_YOU_USE=OFF \
36-
-Dmyproject_ENABLE_CLANG_TIDY=OFF
54+
-D${{ env.PROJECT_NAME }}_ENABLE_BLOATY=OFF \
55+
-D${{ env.PROJECT_NAME }}_ENABLE_INCLUDE_WHAT_YOU_USE=OFF \
56+
-D${{ env.PROJECT_NAME }}_ENABLE_CLANG_TIDY=OFF
3757
3858
- name: Build all WASM targets
3959
run: emmake cmake --build build --target web-dist

CI_KNOWN_ISSUES.md

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,27 @@
11
# CI Known Issues
22

3-
This document tracks CI limitations and their resolutions. Most issues
4-
stemmed from the migration from CPM/FetchContent to Conan 2.0.
5-
6-
## clang-tidy and Conan include paths (RESOLVED)
7-
8-
**Status:** Fixed by removing the `-p` flag from `StaticAnalyzers.cmake`.
9-
10-
**Root cause:** The `-p` flag in `CMAKE_CXX_CLANG_TIDY` options told CMake
11-
to have clang-tidy use `compile_commands.json` instead of passing the full
12-
compile command directly. This broke include resolution for Conan packages
13-
whose headers live in external `-isystem` paths (`~/.conan2/p/...`). Without
14-
`-p`, CMake appends `-- <full compile command>` to clang-tidy, which includes
15-
all `-isystem` paths and works reliably with Conan.
16-
17-
## macOS + GCC Conan ABI (RESOLVED)
18-
19-
**Status:** Fixed by overriding the Conan profile for macOS GCC in CI.
20-
21-
**Root cause:** Conan's default macOS profile detects Apple Clang and sets
22-
`compiler.libcxx=libc++`. When building with GCC 14 (which uses `libstdc++`),
23-
this causes ABI mismatches at link time. Fixed by creating a GCC-specific
24-
Conan profile with `compiler=gcc` and `compiler.libcxx=libstdc++11`.
25-
26-
## codecov fail_ci_if_error (RESOLVED)
27-
28-
**Status:** Set to `true`. Requires `CODECOV_TOKEN` repository secret.
29-
30-
**Setup:** Add `CODECOV_TOKEN` to the repository secrets at
31-
`Settings > Secrets and variables > Actions`. The token is obtained from
32-
[codecov.io](https://codecov.io) after linking the repository. Derived repos
33-
must configure their own token.
34-
35-
## GCC coverage on macOS ARM
36-
37-
**Status:** Skipped in `cmake/Tests.cmake` when `APPLE AND GNU`.
38-
39-
**Root cause:** GCC's `--coverage` flag links against `libgcov`, which
40-
Apple's ARM linker can't find. Tests still run and pass; only coverage
41-
instrumentation is skipped. GCC coverage works on Linux.
42-
43-
## Intel ICX coverage
44-
45-
**Status:** gcovr skipped when `matrix.compiler == intel` in `ci.yml`.
46-
47-
**Root cause:** Intel ICX produces coverage data in a format incompatible
48-
with `gcov`. Tests still run and pass; only the coverage report is skipped.
49-
50-
**Possible fix:** Use `llvm-cov` from the oneAPI toolkit to process ICX
51-
coverage data. Nice-to-have, not a blocker.
3+
Tracked issues with links to GitHub issues for follow-up.
4+
5+
## Resolved
6+
7+
- **clang-tidy + Conan**: Fixed by removing `-p` flag from
8+
`StaticAnalyzers.cmake`. clang-tidy works on all compilers.
9+
- **macOS GCC ABI mismatch**: Fixed by pre-installing Conan deps
10+
with a GCC-specific `libstdc++11` profile.
11+
- **CodeQL missing Conan**: Fixed by adding `pip install conan lizard`
12+
and disabling Bloaty/IWYU in the CodeQL workflow.
13+
- **codecov**: Set to `fail_ci_if_error: true`. Derived repos must
14+
configure their own `CODECOV_TOKEN` repository secret from
15+
[codecov.io](https://codecov.io).
16+
17+
## Open
18+
19+
- **WASM + Emscripten threading** ([#4](https://github.com/VersatusHPC/cmake_template/issues/4)):
20+
spdlog built by Conan without atomics/bulk-memory, but the project
21+
uses Emscripten pthreads. Emscripten pinned to 3.1.74 (Conan
22+
doesn't support emcc 23+).
23+
- **macOS GCC coverage** ([#5](https://github.com/VersatusHPC/cmake_template/issues/5)):
24+
Apple ARM linker can't find libgcov. Tests pass, coverage skipped.
25+
- **Intel ICX coverage** ([#6](https://github.com/VersatusHPC/cmake_template/issues/6)):
26+
gcov incompatible with ICX coverage format. Tests pass, coverage
27+
skipped.

ProjectOptions.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ macro(myproject_supports_sanitizers)
1212
if(EMSCRIPTEN)
1313
set(SUPPORTS_UBSAN OFF)
1414
set(SUPPORTS_ASAN OFF)
15-
elseif((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" OR CMAKE_CXX_COMPILER_ID MATCHES ".*GNU.*") AND NOT WIN32)
15+
elseif((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" OR CMAKE_CXX_COMPILER_ID MATCHES ".*GNU.*" OR CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") AND NOT WIN32)
1616

1717
message(STATUS "Sanity checking UndefinedBehaviorSanitizer, it should be supported on this platform")
1818
set(TEST_PROGRAM "int main() { return 0; }")
@@ -33,7 +33,7 @@ macro(myproject_supports_sanitizers)
3333
set(SUPPORTS_UBSAN OFF)
3434
endif()
3535

36-
if((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" OR CMAKE_CXX_COMPILER_ID MATCHES ".*GNU.*") AND WIN32)
36+
if((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" OR CMAKE_CXX_COMPILER_ID MATCHES ".*GNU.*" OR CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") AND WIN32)
3737
set(SUPPORTS_ASAN OFF)
3838
else()
3939
if (NOT WIN32)

cmake/CompilerWarnings.cmake

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,12 @@ function(
9191

9292
if(MSVC)
9393
set(PROJECT_WARNINGS_CXX ${MSVC_WARNINGS})
94-
elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
94+
elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
9595
set(PROJECT_WARNINGS_CXX ${CLANG_WARNINGS})
9696
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
9797
set(PROJECT_WARNINGS_CXX ${GCC_WARNINGS})
9898
else()
9999
message(AUTHOR_WARNING "No compiler warnings set for CXX compiler: '${CMAKE_CXX_COMPILER_ID}'")
100-
# TODO support Intel compiler
101100
endif()
102101

103102
# use the same warning flags for C

cmake/Emscripten.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ function(myproject_configure_wasm_target target)
8989
"-sUSE_PTHREADS=1"
9090
"-sPROXY_TO_PTHREAD=1"
9191
"-sPTHREAD_POOL_SIZE=${myproject_WASM_PTHREAD_POOL_SIZE}"
92-
# Enable asyncify for emscripten_sleep and async operations
93-
"-sASYNCIFY=1"
94-
"-sASYNCIFY_STACK_SIZE=${myproject_WASM_ASYNCIFY_STACK_SIZE}"
92+
# NOTE: Asyncify is disabled because it conflicts with pthreads +
93+
# wasm-exceptions on Emscripten 3.1.x (wasm-opt UNREACHABLE crash).
94+
# PROXY_TO_PTHREAD handles async operations instead.
9595
# Memory configuration
9696
"-sALLOW_MEMORY_GROWTH=1"
9797
"-sINITIAL_MEMORY=${myproject_WASM_INITIAL_MEMORY}"

cmake/Hardening.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ macro(
1313
message(STATUS "*** MSVC flags: /sdl /DYNAMICBASE /guard:cf /NXCOMPAT /CETCOMPAT")
1414
list(APPEND NEW_LINK_OPTIONS /NXCOMPAT /CETCOMPAT)
1515

16-
elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang|GNU")
16+
elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang|GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
1717
list(APPEND NEW_CXX_DEFINITIONS -D_GLIBCXX_ASSERTIONS)
1818
message(STATUS "*** GLIBC++ Assertions (vector[], string[], ...) enabled")
1919

cmake/Sanitizers.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ function(
77
ENABLE_SANITIZER_THREAD
88
ENABLE_SANITIZER_MEMORY)
99

10-
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
10+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
1111
set(SANITIZERS "")
1212

1313
if(${ENABLE_SANITIZER_ADDRESS})
@@ -30,7 +30,7 @@ function(
3030
endif()
3131
endif()
3232

33-
if(${ENABLE_SANITIZER_MEMORY} AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
33+
if(${ENABLE_SANITIZER_MEMORY} AND (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM"))
3434
message(
3535
WARNING
3636
"Memory sanitizer requires all the code (including libc++) to be MSan-instrumented otherwise it reports false positives"

cmake/StandardProjectSettings.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ endif()
1818
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
1919

2020
# Enhance error reporting and compiler messages
21-
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
21+
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
2222
add_compile_options($<$<COMPILE_LANGUAGE:C>:-fcolor-diagnostics> $<$<COMPILE_LANGUAGE:CXX>:-fcolor-diagnostics>)
2323
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
2424
add_compile_options($<$<COMPILE_LANGUAGE:C>:-fdiagnostics-color=always>

0 commit comments

Comments
 (0)