CMake указывает, что компилятор не поддерживает флаг, но это делает - PullRequest
0 голосов
/ 19 мая 2018

Я использую CMake для настройки переносимой компиляции проекта C, и я хотел проверить, поддерживает ли используемый компилятор различные флаги компиляции, которые я готов использовать.

Предположим, у меня есть этот простой Cфайл noinit.c, который использует неинициализированную переменную:

#include <stdio.h>

int main(void)
{
    int i; // Uninitialized
    printf("%d\n", i+2);
    return 0;
}

Я хотел бы, чтобы компилятор выдавал ошибку, поэтому я использую флаги -Wall -Werror.Это мой CMakeLists.txt файл:

cmake_minimum_required(VERSION 3.1 FATAL_ERROR)

project(cmake_compiler_flag_test C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

include(CheckCCompilerFlag)
list(APPEND COMPILER_FLAGS_TO_USE "-Wall" "-Werror")
foreach (FLAG IN LISTS COMPILER_FLAGS_TO_USE)
    # Check if the compiler supports the flag. The result of this test
    # is printed to STDOUT when calling `cmake`.
    check_c_compiler_flag(${FLAG} COMPILER_SUPPORTS_${FLAG})
    # Regardless of the test, force the usage of the flag anyway.
    string(APPEND CMAKE_C_FLAGS " ${FLAG}")
endforeach()

add_executable(noinit noinit.c)

Когда я вызываю CMake, он говорит, что мой компилятор не поддерживает -Werror.

> mkdir build
> cd build
> cmake ..
-- The C compiler identification is AppleClang 9.1.0.9020039
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Performing Test COMPILER_SUPPORTS_-Wall
-- Performing Test COMPILER_SUPPORTS_-Wall - Success
-- Performing Test COMPILER_SUPPORTS_-Werror
-- Performing Test COMPILER_SUPPORTS_-Werror - Failed  # <-- NOTICE THE FAIL HERE!
-- Configuring done
-- Generating done
-- Build files have been written to: /some/path/to/cmake_compiler_flag_test/build

Но когда я вызываю компилятор (которыйподдерживает флаг), на самом деле он работает, как ожидалось, и выдает ошибку относительно неинициализированной переменной:

> make
[ 50%] Building C object CMakeFiles/noinit.dir/noinit.c.o
/some/path/to/cmake_compiler_flag_test/noinit.c:5:20: error: variable 'i' is
      uninitialized when used here [-Werror,-Wuninitialized]
    printf("%d\n", i+2);
                   ^
/some/path/to/cmake_compiler_flag_test/noinit.c:4:10: note: initialize the
      variable 'i' to silence this warning
    int i; // Uninitialized
         ^
          = 0
1 error generated.
make[2]: *** [CMakeFiles/noinit.dir/noinit.c.o] Error 1
make[1]: *** [CMakeFiles/noinit.dir/all] Error 2
make: *** [all] Error 2

Я что-то не так делаю в конфигурации CMake или это ошибка CMake?

Инструменты и их версии, использованные для этого теста:

  • macOS 10.13.4
  • *1025* CMake 3.11.2
  • протестированных компиляторов (оба показывают ту же проблему):
    • Apple LLVM версии 9.1.0 (clang-902.0.39.1)
    • gcc-8 (Homebrew GCC 8.1.0) 8.1.0

1 Ответ

0 голосов
/ 20 мая 2018

CMakeFiles/CMakeError.log несколько показателен:

In file included from <built-in>:341: 
<command line>:1:27: error: ISO C99 requires whitespace after 
the macro name [-Werror,-Wc99-extensions] 
#define COMPILER_SUPPORTS_-Werror 1

1 error generated.

Похоже, что создание имени вашей переменной (COMPILER_SUPPORTS_${FLAG}) завершилось неудачей, так как в имени есть дефис, -.Вы можете удалить этот дефис из ${FLAG} перед добавлением или найти другой способ его обойти.

Согласно вашему собственному предложению, вы можете добавить строку

string(REPLACE "-" "" FLAG_NO_HYPHEN ${FLAG})

передпроверить флаг компилятора, а затем использовать

check_c_compiler_flag(${FLAG} COMPILER_SUPPORTS_${FLAG_NO_HYPHEN})

.


Фактическая странная вещь для меня заключается в том, что -Wall кажется успешным, что, вероятно, отбросит вас (если оба раза не сработали, то более очевидно, что в CMakeLists.txt) что-то не так.
Инвертирование порядка двух строк-флагов в list(...) вблизи вершины фактически приведет к сбою обоих тестов.

CMakeFiles/CMakeOutput.log, в данном случае, показывает

In file included from <built-in>:341:
<command line>:1:27: warning: ISO C99 requires whitespace after the
macro name [-Wc99-extensions]
#define COMPILER_SUPPORTS_-Wall 1

1 warning generated.

Здесь это только предупреждение, но в обратном порядке оба теста становятся ошибками.

Возможно, кто-тознает, почему это так, и может прокомментировать это.Или это просто ошибка в CMake.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...