단일 파일에 대한 컴파일 플래그 무시


109

프로젝트를 컴파일하기 위해 전역 플래그 집합을 사용하고 싶습니다. 즉, 최상위 CMakeLists.txt 파일에서 다음을 지정했습니다.

ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )

그러나 하위 디렉토리에있는 특정 파일 ( "foo.cpp")의 경우 컴파일 플래그를 -Weffc ++ (내가 변경할 수없는 상용 라이브러리 포함)를 적용하지 않도록 전환하고 싶습니다. -Wall 만 사용하도록 상황을 단순화하기 위해 다음을 시도했습니다.

 SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
 ADD_EXECUTABLE( foo foo.cpp )

, 작동하지 않았습니다. 나는 또한 시도했다

SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )

ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )

, 둘 다 작동하지 않았습니다.

마지막으로이 정의를 제거해 보았습니다.

REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )

, 또한 작동하지 않았습니다 (즉, 상업 도서관에 대한 많은 스타일 경고를받습니다). (** 참고 : 실행 파일이 빌드 된 후 -Weffc ++ 지시문을 다시 포함하지 않으면 경고가 표시되지 않습니다.)

또한 일시적으로 컴파일 플래그를 제거하려고 시도했습니다 : http://www.cmake.org/pipermail/cmake/2007-June/014614.html ,하지만 도움이되지 않았습니다.

이것에 대한 우아한 해결책이 없습니까?


1
마지막 시도가 작동하지만 빌드 된 후에야 캐싱 문제가 아닐 수 있습니까? 변경 후 CMakeCache를 삭제 해보십시오.
Cameron

관련, CMake에서 실행 파일 하나에 대한 컴파일러 플래그를 변경하는 방법을 참조하세요 . Andre의 대답은 기존 옵션을 새로운 옵션으로 대체하는 방법으로 보이는 것을 보여줍니다.
jww

답변:


126

위의 시도는 예상대로 덮어 쓰지 않고 파일 / 대상에 플래그를 추가하는 것입니다. 예를 들어 소스 파일의 속성에 대한 문서 -COMPILE_FLAGS :

이 플래그는이 소스 파일이 빌드 될 때 컴파일 플래그 목록에 추가됩니다.

다음 -Weffc++을 수행하여 foo.cpp에 대한 플래그 를 카운터 맨드 할 수 있어야합니다.

set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)

이것은 컴파일러 명령에 -Wno-effc++after 를 추가하는 효과가 있어야 -Weffc++하며 후자의 설정이 우선합니다. 전체 명령을보고 이것이 사실인지 확인하려면 다음을 수행 할 수 있습니다.

make VERBOSE=1

여담는 GNU C ++ 표준 라이브러리의 관리자들 중 하나에 매우 부정적인 의견을 제시대로 -Weffc++에서 이 답변 .

또 다른 요점은 add_definitions의도 된 전 처리기 정의가 아닌 컴파일러 플래그에 이것을 사용하고 있다는 의미에서 오용 하고 있다는 것입니다.

사용하는 것이 바람직합니다 add_compile_options

add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x)

또는 CMake 버전 <3.0의 경우 다음과 같은 작업을 수행합니다.

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x")

아래 의견에 대한 추가 질문에 대한 응답으로 단일 파일에서 플래그 를 안정적으로 제거 하는 것은 불가능하다고 생각 합니다. 그 이유는 특정 소스 파일에 대해, 그것은을 가지고 있다는 것입니다 COMPILE_OPTIONS1 목표의 적용 만이 그 소스 파일의 속성 중 하나에 표시되지 않습니다.COMPILE_FLAGS

대상의에서 문제 플래그를 제거한 COMPILE_OPTIONS다음 각 대상의 소스에 개별적으로 적용하고 필요에 따라 특정 소스 파일에서 생략 할 수 있습니다.

그러나 이것은 많은 시나리오에서 작동 할 수 있지만 몇 가지 문제가 있습니다.

첫째 - 소스 파일의 속성은 포함되지 않습니다 COMPILE_OPTIONSCOMPILE_FLAGS. COMPILE_OPTIONS대상의에 생성자 표현식 이 포함될 수 있지만 COMPILE_FLAGS지원하지 않기 때문에 이는 문제 입니다. 따라서 플래그를 검색하는 동안 제너레이터 표현식을 수용해야하며 플래그가 하나 이상의 플래그에 포함 된 경우 생성기 표현식을 "분석"하여 나머지에 다시 적용해야하는지 여부를 확인해야 할 수도 있습니다. 소스 파일.

둘째-CMake v3.0 이후 대상은 INTERFACE_COMPILE_OPTIONS. 대상의 종속성 추가하거나 대상의를 대체 할 수있는이 수단 COMPILE_OPTIONS의를 통해 INTERFACE_COMPILE_OPTIONS. 따라서 LINK_LIBRARIES문제 플래그를 적용하는 항목을 찾기 위해 모든 대상의 종속성 (대상 목록에 생성기 표현식도 포함될 수 있으므로 특히 쉬운 작업이 아님)을 반복적으로 반복해야 하며 문제 플래그를 적용하고 제거해야합니다. 목표 INTERFACE_COMPILE_OPTIONS도.

이 복잡성 단계에서 소스 파일에서 특정 플래그를 무조건 제거하는 기능을 제공하기 위해 CMake에 패치를 제출하려고합니다.


1 : COMPILE_FLAGS소스 파일 의 속성 과 달리 COMPILE_FLAGS대상 의 속성은 더 이상 사용되지 않습니다.


6
그러나 파일을 추가하지 않고 파일에 대한 컴파일 플래그를 실제로 어떻게 설정합니까? 예를 들어, 결과 타겟에 대해 파일과 다른 컴파일 플래그를 사용하고 싶지만 추가되었으므로 수동으로 제거해야합니다. 추가하지 않고 실제로 지정된 파일 / 대상에 대해서만 설정하는 속성이 없습니까?
Baradé 2014

2
-fno-flag를 사용할 수없고 -fflag가 설정되어있을 때 우리는 무엇을 할 수 있습니까?
gnzlbg 2015

@ Baradé 할 수 없습니다-소스 파일이 아닙니다.
Fraser

@gnzlbg 다시 말하지만, 우리는 거의 막혔습니다. 좀 더 많은 정보를 제공하기 위해 내 답변을 업데이트했습니다 (그리고 일부 시나리오 에서 작동하는 가능한 해결 방법 ).
Fraser

단일 파일 컴파일 옵션 설정에 대한 해결 방법이 실제로 없습니까? gcov가 충돌하는 일부 파일에 대해 gcc 적용 범위 생성을 비활성화해야합니다.
Lothar

5

@Fraser의 정답에 추가하기 만하면됩니다.

특정 폴더에 특수 플래그를 추가하려는 경우 다음을 수행 할 수 있습니다.

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_property(SOURCE ${SPECIAL_SRC_FILES} PROPERTY COMPILE_FLAGS -Wno-effc++)

또는

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_source_files_properties(${SPECIAL_SRC_FILES} PROPERTIES COMPILE_FLAGS -Wno-effc++)

여기에 설명 된대로 GLOB를 사용하지 않는 것이 좋습니다.


0

@Fraser 답변을 사용하여 변수에 세미콜론으로 구분 된 여러 경로가 포함되어 있기 때문에 Qt 포함을 처리하기 위해 다음을 만들었습니다. 즉, 먼저 foreach()루프를 추가하고 수동으로 포함 플래그 만들어야합니다 . 그러나 그것은 한 가지 예외를 허용합니다 : foo.cpp (한 파일은 현재 Qt를 사용하지만 장기적으로는 해당 종속성을 제거하고 Qt가 다른 곳에서 크립하지 않도록하고 싶습니다).

find_package(Qt5Core REQUIRED)
set(QT_INCLUDE_PROPERTIES "")
foreach(DIR ${Qt5Core_INCLUDE_DIRS})
    set(QT_INCLUDE_PROPERTIES "${QT_INCLUDE_PROPERTIES} -isystem ${DIR}")
endforeach()
set_source_files_properties(foo.cpp PROPERTIES
    COMPILE_FLAGS
        ${QT_INCLUDE_PROPERTIES}
)

Qt 헤더가 생성하는 경고를 피하기 위해 -isystem대신을 사용합니다 -I(많은 경고가 켜져 있음).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.