Предупреждения CMake и компилятора
Я использую CMake
для создания make файлов unix. После этого я скомпилирую проект с помощью утилиты make
.
Проблема в том, что я не вижу никаких предупреждений! Например, это приводит к чистой сборке без предупреждений:
#include <iostream>
class Foo
{
int first;
int second;
public:
Foo(int a, int b)
: second(a) // invalid initialization order
, first(b)
{
}
};
int main(int argc, char** argv)
{
int unused; // unused variable
int x;
double y = 3.14159;
x = y; // invalid cast
Foo foo(1,2);
std::cout << y << std::endl;
return 0;
}
Неиспользуемая переменная и переменная с потерями - никаких предупреждений! Мой файл CMakeLists.txt
минималистичен:
cmake_minimum_required(VERSION 2.8)
add_executable(main main.cpp)
Когда я запускаю CMake
, а затем make
мой вывод выглядит следующим образом:
[100%] Building CXX object CMakeFiles/main.dir/main.cpp.o
Linking CXX executable main
[100%] Built target main
Но когда я добавляю эту строку кода:
#warning ("Custom warning")
Результат
содержит предупреждение:
[100%] Building CXX object CMakeFiles/main.dir/main.cpp.o
../src/main.cpp:15:2: warning: #warning ("Custom Warning") [-Wcpp]
Linking CXX executable main
[100%] Built target main
Я использую Ubuntu 12.04 LTS и GCC в качестве компилятора. Возможно, CMake передает некоторый флаг компилятору, что приводит к отсутствию предупреждений. Как я могу проверить это? Я не могу читать make файлы, созданные CMake, они немного загадочны.
Ответы
Ответ 1
Позиции в предупреждениях компилятора разделены. Есть сторонники пакетов, которые скажут вам, что они знают, что они делают, а предупреждения компилятора следует игнорировать в любом случае. (Я думаю, что они не могут быть более ошибочными.) Но я думаю, именно поэтому CMake в основном оставляет настройки предупреждения самостоятельно.
Если вы хотите быть немного более сложным в этом вопросе, проверьте использование компилятора и добавьте флаг к определенному свойству конкретной цели.
Применить к одной цели
if ( CMAKE_COMPILER_IS_GNUCC )
target_compile_options(main PRIVATE "-Wall")
endif()
if ( MSVC )
target_compile_options(main PRIVATE "/W4")
endif()
Применить ко всем целям
if ( CMAKE_COMPILER_IS_GNUCC )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
endif()
if ( MSVC )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
Примечание: добавьте -Werror для GCC или /WX для MSVC, чтобы обрабатывать все предупреждения как ошибки. Это относится ко всем предупреждениям как к ошибкам. Это может быть удобно для новых проектов для обеспечения строгости предупреждения.
Кроме того, -Wall
не означает "все ошибки"; исторически это означало "все ошибки, которые все могли бы согласовать". Начните с -Wall -Wextra
, затем прочтите руководство для своей версии GCC и найдите, что еще может сделать компилятор для вас в отношении предупреждений.
Ответ 2
Решите проблему с этой строкой кода:
add_definitions ("-Wall")
Результат теперь выглядит следующим образом:
[100%] Building CXX object CMakeFiles/main.dir/main.cpp.o
../src/main.cpp:15:2: warning: #warning ("Custom warning") [-Wcpp]
../src/main.cpp: In constructor ‘WarnSrc::WarnSrc(int, int)’:
../src/main.cpp:6:9: warning: ‘WarnSrc::second’ will be initialized after [-Wreorder]
../src/main.cpp:5:9: warning: ‘int WarnSrc::first’ [-Wreorder]
../src/main.cpp:8:5: warning: when initialized here [-Wreorder]
../src/main.cpp: In function ‘int main(int, char**)’:
../src/main.cpp:19:9: warning: unused variable ‘unused’ [-Wunused-variable]
../src/main.cpp:20:9: warning: variable ‘x’ set but not used [-Wunused-but-set-variable]
Linking CXX executable main
[100%] Built target main