CMake에서 경고 수준을 설정하는 방법은 무엇입니까?


116

CMake를 사용하여 프로젝트 (전체 솔루션이 아님)에 대한 경고 수준 을 설정하는 방법은 무엇입니까? Visual StudioGCC 에서 작동해야합니다 .

다양한 옵션을 찾았지만 대부분 작동하지 않거나 문서와 일치하지 않는 것 같습니다.

답변:


96

업데이트 :이 답변은 Modern CMake 시대 이전입니다. 모든 정상적인 CMake 사용자는 CMAKE_CXX_FLAGS직접 조작 하지 target_compile_options말고 대신 명령을 호출해야 합니다. 권장 모범 사례를 제시 하는 mrts의 답변 을 확인하십시오 .

다음과 유사한 작업을 수행 할 수 있습니다.

if(MSVC)
  # Force to always compile with W4
  if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
    string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  else()
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
  endif()
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
  # Update if necessary
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic")
endif()

새 버전의 Visual Studio (최소 2013)는 /Wall플래그 (이름 EnableAllWarnings)를 지원합니다. 보다 더 많은 경고를 생성합니다 /W4. 그러나 내 경험상 너무 많은 경고를 생성합니다.
Adam Badura

12
/Wallclang과 마찬가지로 경고에 대한 '감산'전략을 따르려는 경우 사용할 수 있습니다 -Weverything. 활성화 할 경고를 선택하는 대신 모든 것을 활성화 한 다음 비활성화 할 특정 경고를 선택합니다.
bames53

86

최신 CMake에서는 다음이 잘 작동합니다.

if(MSVC)
  target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
  target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif()

제 동료가 대체 버전을 제안했습니다.

target_compile_options(${TARGET_NAME} PRIVATE
  $<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
  $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic -Werror>
)

${TARGET_NAME}실제 대상 이름으로 바꿉니다 . -Werror선택 사항이며 모든 경고를 오류로 바꿉니다.

또는 add_compile_options(...)주석에서 @aldo가 제안한대로 모든 대상에 적용하려면 사용하십시오.

또한, 차이 이해해야합니다 PRIVATEPUBLIC(공공 옵션이 주어진 목표에 따라 목표에 의해 상속됩니다).


19
또는 단순히 add_compile_options(...)모든 대상에 적용하려는 경우.
aldo

1
참고로 최신 CMake는 else()또는 에서 조건을 반복 할 필요가 없습니다 endif().
Timmmm

1
@Timmmm 머리 주셔서 감사합니다! 메모 일 뿐입니 까, 아니면 조건을 제거 하시겠습니까?
mrts

1
@helmesjo 아니요, Timmmm은 4 월 9 일 편집 이전에 존재했던 CMake 코드를 참조했습니다. 편집 내역을 살펴보면 Timmmm이 지적한 것과 동일한 제거 된 비트를 볼 수 있습니다.
FeRD

2
@aldo 문제 add_compile_options()는 경고가를 통해 추가 된 대상으로 전파된다는 것 add_subdirectory()입니다. 이러한 방식으로 외부 라이브러리를 포함하면 해당 라이브러리가 다른 경고 수준으로 디자인 된 경우 많은 경고를받을 수 있습니다.
trozen

24

내가 작성한 일부 CMake 모듈 에는 실험적인 교차 플랫폼 경고 억제 기능이 포함되어 있습니다 .

sugar_generate_warning_flags(
    target_compile_options
    target_properties
    ENABLE conversion
    TREAT_AS_ERRORS ALL
)

set_target_properties(
    foo
    PROPERTIES
    ${target_properties}
    COMPILE_OPTIONS
    "${target_compile_options}"
)

Xcode의 결과 :

  • 설정 CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION엑스 코드 속성 (일명 빌드 설정 -> 경고 -> 의심스러운 암시 적 변환 -> YES )
  • 컴파일러 플래그 추가 : -Werror

Makefile gcc 및 clang :

  • 컴파일러 플래그 추가 : -Wconversion,-Werror

비주얼 스튜디오:

  • 컴파일러 플래그 추가 : /WX,/w14244

연결


1
cmake가이 기능을 제공하지 않는 것은 부끄러운
Slava

3
좋은 소식. cmake 메일 링리스트가 아니라 여기에 게시해서 미안하지만 레벨이 없으면 쓸모가 없습니다. 모두 명시 적으로 나열하기에는 너무 많은 경고가 있습니다. 한 가지 방법으로 통합하려면 두 개의 별도 cmake_level-예를 들어 clang을 기반으로 한 통합 경고 집합과 컴파일러에 특정한 의미를 갖는 native_level입니다. 그들 중 하나는 아마도 수평으로 단축 될 수 있습니다. 죄송합니다 정말 대화와 가지고 뭔가 잘못 수행하지 않은 경우
슬라바

1
@ void.pointer는 유효한 포인트를 발생시킵니다. 귀하의 제안 대답은 읽습니다 : " 내가있어 이 기능을 추가 할 계획" . 당신이 약간의 간단한 조사를했고 이제 다른 누군가가 당신을 위해 무거운 일을 해주길 바라고 있다는 말은 아닙니다. 구현 (및 진행 상황에 대한 질문)에 기여하고 싶지 않다면 답변을 편집하고 1 년 넘게 진행하지 않은 작업에서 자신을 분리해야합니다.
IInspectable

"1 년이 지난 지금도 진전이 없습니다." - 이제이 있다 유효한 점은. 년 이상 함께, 통과 제로 진행. 이것은 버려진 프로젝트의 매우 강력한 표시입니다. 우리가 틀렸다는 것을 증명하고 싶다면 진행 상황을 보여주세요. 그것은 일어나지 않았지만 제안 된 답변은 여전히 ​​기능이 CMake에 추가 될 것이라고 제안합니다. 몇 년 후에는 사용할 수없는 기능에 대해 모든 소란을 피우는 이유는 무엇입니까? 전혀 도움이되지 않습니다. 진행 상황을 보여 주거나 오해의 소지가 없도록 답변을 수정하세요.
IInspectable

5
이해하지 못하는 것 같습니다. 기능을 구현할 것을 제안하는 경우 적절한시기에 해당 기능을 구현해야합니다. 실패하면 제안 된 답변에서 해당 약속을 제거하라는 메시지가 표시됩니다. 해당 기능을 구현하겠다는 약속이 전혀 없었으므로 달리 주장하지 마십시오. 큰 것을 압니다. 나는 또한 당신이 이것을 풀 수 없을 수도 있음을 이해합니다. 나는 단순히 당신의 대답이 그것을 반영하도록 요청하는 것입니다.
IInspectable

6

지금까지 찾은 최고의 솔루션은 다음과 같습니다 (컴파일러 검사 포함).

if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
    add_definitions(/W2)
endif()

그러면 Visual Studio에서 경고 수준 2가 설정됩니다. 나는 -W2그것이 GCC에서도 작동 한다고 생각 합니다 (예상되지 않음).

@Williams의 업데이트 : -WallGCC 용 이어야합니다 .


6
GCC의 경고 플래그는 것이 -Wall어쩌면 -Wextra같은에서 설명 gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Milliams

1
내가 사용하는 목록은 -W -Wall -Wextra -pedantic입니다. -WextraIIRC -W는 이후 버전의 GCC에서 대체 되었지만 호환성을 위해 둘 다 남겨 둡니다.
Jimmio92 2016 년

2
이것은 add_definitions 의 의도 된 목적이 아닙니다 ( "전 처리기 정의를 추가하기위한 것입니다" ). 모범 사례 권장 사항도 아닙니다. 이 명령에 전달 된 인수는 예상하지 않은 도구를 호출하는 생성 된 빌드 스크립트에 표시됩니다 (예 : 리소스 컴파일러).
IInspectable

이것은 "컴파일러 검사"가 아니라 빌드 도구 검사입니다.
Thomas

3

당으로 Cmake 3.17.1 문서 :

if (MSVC)
    # warning level 4 and all warnings as errors
    add_compile_options(/W4 /WX)
else()
    # lots of warnings and all warnings as errors
    add_compile_options(-Wall -Wextra -pedantic -Werror)
endif()

GCC와 Clang은 이러한 플래그를 공유하므로 3 개를 모두 포함해야합니다.


이것을 사용하지 마십시오. 대신 target_compile_options ()를 사용하십시오. 최신 문서를 참조하는 것은 "올바른"것처럼 보이지만 이전 버전과의 호환성을위한 오래된 항목입니다.
caoanan

1
@caoanan 문서에는 이에 대한 이전 버전과의 호환성에 대한 언급이 없습니다. add_compile_options디렉토리 전체에 해당하는 반면 target_compile_options단일 대상에만 해당됩니다.
TehWan

2
if(MSVC)
    string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()

당신이 사용하는 경우 target_compile_options- cmake 두 번 사용하려고합니다 /W*컴파일러가 경고를 줄 것이다 플래그를.


감사합니다. 나는 순진하게을 사용하여 무시되는 add_compile_options수많은 경고를 얻었 /W3습니다 /W4. CMake가이 기초적인 옵션 (경고 수준 설정)을 다루지 않는다는 사실은 믿을 수 없습니다.
부활
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.