Check If Source Code Can Be Compiled and Run using CMake

Check If Source Code Can Be Compiled and Run using CMake

When developing cross-platform C or C++ projects, you may need to verify not just whether code compiles, but also whether it runs successfully on the target system. This is especially useful when testing for specific CPU instruction sets, compiler options, or runtime behaviors that depend on the host environment. This tutorial demonstrates how to check if source code can be compiled and run using CMake.

CMake provides a convenient command, check_source_runs, that attempts to compile and execute a small code snippet during the configuration stage. Based on the result, it sets a variable which you can use to conditionally enable or disable specific parts of the code or configuration logic.

The following CMakeLists.txt example checks if the compiler and system support the AVX-512 instruction set for floating-point operations:

cmake_minimum_required(VERSION 3.27)
project(myapp)

set(CMAKE_CXX_STANDARD 17)

include(CheckSourceRuns)
include(CMakePushCheckState)

cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_FLAGS "-mavx512f")
check_source_runs(CXX "
    #include <immintrin.h>
    int main() {
        __m512 a = _mm512_set1_ps(0);
        (void) a;
        return 0;
    }
" HAVE_AVX512)
cmake_pop_check_state()
if (HAVE_AVX512)
    # ...
endif ()

add_executable(${PROJECT_NAME} main.cpp)

When CMake runs, it generates a small temporary source file using the provided code snippet, compiles it, and attempts to execute the resulting binary. If the program runs without errors, the corresponding variable is set to TRUE. This variable can then be referenced in the CMake configuration logic or exposed to the source code as a preprocessor definition.

In the provided example, the CMakePushCheckState module is used to temporarily set a compiler option (-mavx512f) while verifying whether AVX-512 instructions are supported and can execute successfully on the current system. Some compilers may accept the -mavx512f option and compile code using AVX-512 instructions, but the generated binary may fail to run on CPUs that lack AVX-512 support.

By default, check_source_runs prints diagnostic messages like:

-- Performing Test HAVE_AVX512
-- Performing Test HAVE_AVX512 - Success

If you prefer not to see diagnostic messages from these checks, you can use CMAKE_REQUIRED_QUIET variable:

# ...

cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_QUIET TRUE)
set(CMAKE_REQUIRED_FLAGS "-mavx512f")
check_source_runs(CXX "
    #include <immintrin.h>
    int main() {
        __m512 a = _mm512_set1_ps(0);
        (void) a;
        return 0;
    }
" HAVE_AVX512)
cmake_pop_check_state()

# ...

Leave a Comment

Cancel reply

Your email address will not be published.