I’ve a C++ project built using CMake v3.25.0
. The project uses Catch2 v3.7.0
for unit testing. For development convenience I’m trying to cross-compile it from Linux to Windows. Following CMake’s cross compilation guideline, I’ve the following windows.cmake
file in my project:
# the name of the target operating system
set(CMAKE_SYSTEM_NAME Windows)
# which compilers to use for C and C++
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
# where is the target environment located
set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
# adjust the default behavior of the FIND_XXX() commands:
# search programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# search headers and libraries in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
I build as follows:
cmake -DCMAKE_TOOLCHAIN_FILE=windows.cmake --preset="$PRESET" -S .
cmake --build --preset="$PRESET" --parallel "$(nproc)" --target install
This is the CMakeLists.txt
file that builds the test binary:
Include(FetchContent)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.7.0
)
FetchContent_MakeAvailable(Catch2)
list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
add_executable(tests
tests.cpp
${CMAKE_SOURCE_DIR}/src/filesystem_api.cpp
)
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)
target_include_directories(tests
PRIVATE
${CMAKE_SOURCE_DIR}/include
)
include(CTest)
include(Catch)
catch_discover_tests(tests)
When the build begins, CMake
correctly identifies cross-compiler:
Preset CMake variables:
CMAKE_BUILD_TYPE="Release"
CMAKE_CXX_FLAGS_RELEASE="-O3"
CMAKE_C_FLAGS_RELEASE="-O3"
CMAKE_INSTALL_PREFIX:PATH="/home/nishad/project/dir-stats/out/win-release/bin"
-- The CXX compiler identification is GNU 13.0.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/x86_64-w64-mingw32-g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test HAVE_FLAG__ffile_prefix_map__home_nishad_project_dir_stats_out_win_release__deps_catch2_src__
-- Performing Test HAVE_FLAG__ffile_prefix_map__home_nishad_project_dir_stats_out_win_release__deps_catch2_src__ - Success
-- Configuring done (10.0s)
-- Generating done (0.0s)
It then builds Catch2
, builds main binary and test binary tests.exe
. After building and linking tests.exe
, it throws the following error:
[ 96%] Linking CXX static library libCatch2.a
[ 96%] Built target Catch2
[ 97%] Building CXX object _deps/catch2-build/src/CMakeFiles/Catch2WithMain.dir/catch2/internal/catch_main.cpp.obj
[ 97%] Linking CXX static library libCatch2Main.a
[ 97%] Built target Catch2WithMain
[ 99%] Building CXX object tests/CMakeFiles/tests.dir/tests.cpp.obj
[ 99%] Building CXX object tests/CMakeFiles/tests.dir/__/src/filesystem_api.cpp.obj
[100%] Linking CXX executable tests.exe
CMake Error at /home/nishad/project/dir-stats/out/win-release/_deps/catch2-src/extras/CatchAddTests.cmake:81 (message):
Error running test executable
'/home/nishad/project/dir-stats/out/win-release/tests/tests.exe':
Result: 53
Output:
Call Stack (most recent call first):
/home/nishad/project/dir-stats/out/win-release/_deps/catch2-src/extras/CatchAddTests.cmake:193 (catch_discover_tests_impl)
gmake[2]: *** [tests/CMakeFiles/tests.dir/build.make:120: tests/tests.exe] Error 1
gmake[2]: *** Deleting file 'tests/tests.exe'
gmake[1]: *** [CMakeFiles/Makefile2:205: tests/CMakeFiles/tests.dir/all] Error 2
gmake: *** [Makefile:136: all] Error 2
It looks like it tried to run tests.exe
on Linux host, which will fail obviously. Tracing back the error, it is initiated from here: https://github.com/catchorg/Catch2/blob/v3.7.0/extras/CatchAddTests.cmake#L74, which seems like part of the unit test build process by Catch2
.
Is there any way to only build tests.exe
but not run when cross-compiling?