Как сделать так, чтобы CHECK_CXX_COMPILER_FLAG потерпел неудачу на недопустимом значении?

Наш CMakeFile.txt содержит следующее для путей кода SunCC. SunCC использует -xarch=XXX а не стиль GCC -mXXX,

CHECK_CXX_COMPILER_FLAG("-xarch=sha" CRYPTOPP_IA32_SHA)

Когда мы запускаем CMake под компилятором Sun, это приводит к:

-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test CRYPTOPP_IA32_SSSE3
-- Performing Test CRYPTOPP_IA32_SSSE3 - Success
-- Performing Test CRYPTOPP_IA32_SSE4
-- Performing Test CRYPTOPP_IA32_SSE4 - Success
-- Performing Test CRYPTOPP_IA32_CLMUL
-- Performing Test CRYPTOPP_IA32_CLMUL - Success
-- Performing Test CRYPTOPP_IA32_AES
-- Performing Test CRYPTOPP_IA32_AES - Success
-- Performing Test CRYPTOPP_IA32_SHA
-- Performing Test CRYPTOPP_IA32_SHA - Success
...

Однако, когда мы компилируем, это приводит к:

$ make sha-simd.o shacal2-simd.o VERBOSE=1

make -f CMakeFiles/cryptopp-object.dir/build.make CMakeFiles/cryptopp-object.dir/sha-simd.cpp.o
Building CXX object CMakeFiles/cryptopp-object.dir/sha-simd.cpp.o
/opt/solarisstudio12.4/bin/CC -m32 -template=no%extdef -g -xO2 -DNDEBUG -xarch=sha -o CMakeFiles/cryptopp-object.dir/sha-simd.cpp.o -c /export/home/test/sha-simd.cpp
CC: Warning: illegal use of -xarch option, illegal value ignored: sha

make -f CMakeFiles/cryptopp-object.dir/build.make CMakeFiles/cryptopp-object.dir/shacal2-simd.cpp.o
Building CXX object CMakeFiles/cryptopp-object.dir/shacal2-simd.cpp.o
/opt/solarisstudio12.4/bin/CC -m32 -template=no%extdef -g -xO2 -DNDEBUG -xarch=sha -o CMakeFiles/cryptopp-object.dir/shacal2-simd.cpp.o -c /export/home/test/shacal2-simd.cpp
CC: Warning: illegal use of -xarch option, illegal value ignored: sha

Добавление SunCC -errwarn а также -errwarn=%all не помогает CMake обнаружить сбой.

Сообщение может вызвать много проблем для пользователей. Это также нарушает наше управление чистыми компиляциями. Мы хотели бы очистить его и избежать каких-либо проблем.

Как мы говорим CMake, чтобы потерпеть неудачу CHECK_CXX_COMPILER_FLAG проверка на незаконное значение?

2 ответа

Думаю, когда проверяет флаг компилятора, CMake просто проверяет результат команды компиляции. Так как сообщение "Предупреждение" не влияет на результат, CMake не может обнаружить, что флаг фактически игнорируется.

Вы можете вручную проверить флаг с помощью команды try_compile, чтобы вы могли проверить вывод для некоторых шаблонов (например, для "Предупреждение").

Существует также макрос CHECK_CXX_SOURCE_COMPILES, который уже принимает шаблон для сопоставления.

Смотрите также этот вопрос и мой ответ на него.

CheckCompilerOption может использоваться в качестве замены современного CMake при использовании SunCC.

function(CheckCompilerOption option variable)

    if (${CMAKE_CXX_COMPILER_ID} STREQUAL "SunPro")

        message(STATUS "Performing Test ${variable}")        
        execute_process(
            COMMAND sh -c "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} ${option} -E -xdumpmacros /dev/null 2>&1"
            COMMAND egrep -i -c "illegal value ignored"
            RESULT_VARIABLE COMMAND_RESULT
            OUTPUT_VARIABLE COMMAND_OUTPUT
            OUTPUT_STRIP_TRAILING_WHITESPACE)

            if (COMMAND_RESULT STREQUAL "1" AND COMMAND_OUTPUT STREQUAL "0")
                set(${variable} 1 PARENT_SCOPE)
                message(STATUS "Performing Test ${variable} - Success")
            else ()
                set(${variable} 0 PARENT_SCOPE)
                message(STATUS "Performing Test ${variable} - Failed")
            endif ()

    else()

        CHECK_CXX_COMPILER_FLAG(${option} ${variable})

    endif()

endfunction(CheckCompilerOption)

"${${variable}}" выглядит странно, но я считаю, что это правильно на основе существующего кода. Первая версия с разыменованием была неверной. CMake документы для function не обсуждайте это и не предлагайте пример, поэтому мы снова летели вслепую. Это упоминается в разделе Что такое синтаксис CMake для установки и использования переменных? Переполнение стека.

Это можно назвать как ожидалось:

CheckCompilerOption("-msse4.1 -maes" CRYPTOPP_IA32_AES)
CheckCompilerOption("-msse4.2 -msha" CRYPTOPP_IA32_SHA)
...

CheckCompilerOption("-march=armv7-a -mfloat-abi=hard -mfpu=neon" CRYPTOPP_ARMV7A_HARD)
CheckCompilerOption("-march=armv7-a -mfloat-abi=softfp -mfpu=neon" CRYPTOPP_ARMV7A_SOFTFP)
...

CheckCompilerOption("-march=armv8-a+crc" CRYPTOPP_ARMV8A_CRC)
CheckCompilerOption("-march=armv8-a+crypto" CRYPTOPP_ARMV8A_CRYPTO)
...

CheckCompilerOption("-xarch=aes" CRYPTOPP_SUNCC_AES)
CheckCompilerOption("-xarch=sha" CRYPTOPP_SUNCC_SHA)

Если вам нужно вернуться дальше, чем CMake 3.0 (как в Ubuntu 10 или CentOS 5 с CMake 2.8), тогда откажитесь CHECK_CXX_COMPILER_FLAG и используйте верхнюю часть функции для Clang, GCC, ICC и т. д.

Синтаксис GCC для проверки показан ниже. Команда использует SSSE3 в качестве примера.

$(CXX) -x c++ $(CXXFLAGS) -mssse3 -dM -E - </dev/null 2>&1 | egrep -i -c __SSSE3__
Другие вопросы по тегам