Search code examples
cmake

Neither `try_compile` nor `try_run` behaves correctly on incorrect source code?


I have this simple C code which checks for MUSL, and otherwise gives syntax which will fail to compile:

set(is_musl_src [=[
#include <stdlib.h>

#ifndef _GNU_SOURCE
    #define _GNU_SOURCE
    #include <features.h>
    #ifndef __USE_GNU
        #define __MUSL__
    #endif
#else
    #include <features.h>
    #ifndef __USE_GNU
        #define __MUSL__
    #endif
#endif

#ifdef __MUSL__
int main(void) {
    return EXIT_SUCCESS;
#else
#include "noottt.h"
$$#@ 4 5%905i035 35 45 34%^5
#endif
}
]=])

I've also tried normal syntax at the end there like:

int main(void) {
#ifdef __MUSL__
    return EXIT_SUCCESS;
#else
    return EXIT_FAILURE;
#endif
}

However no matter what I try the variables all give the same results on Ubuntu (glibc) and Alpine (musl):

check_c_source_runs("${is_musl_src}" IS_MUSL)
try_compile(COMPILE_RESULT_VAR0
        SOURCE_FROM_VAR is_musl.c is_musl_src
        C_STANDARD 90
)
try_run(RESULT_VAR
        COMPILE_RESULT_VAR1
        SOURCE_FROM_VAR is_musl.c "${is_musl_src}"
        C_STANDARD 90
)
try_run(RESULT_VAR
        COMPILE_RESULT_VAR2
        SOURCE_FROM_VAR is_musl.c is_musl_src
        C_STANDARD 90
)
message(STATUS "IS_MUSL = ${IS_MUSL}")
message(STATUS "RESULT_VAR = ${RESULT_VAR}")
message(STATUS "COMPILE_RESULT_VAR0 = ${COMPILE_RESULT_VAR0}")
message(STATUS "COMPILE_RESULT_VAR1 = ${COMPILE_RESULT_VAR1}")
message(STATUS "COMPILE_RESULT_VAR2 = ${COMPILE_RESULT_VAR2}")

Solution

  • Your mistake is simple, but easy to trip over. Quoting from man 7 feature_test_macros on my local glibc system

    NOTE: In order to be effective, a feature test macro must be defined before including any header files.

    _GNU_SOURCE being one of those feature test macros, must be defined before including any header files. Delete the #include <stdlib.h> from your test.