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


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_OPTIONS및 1 목표의 적용 만이 그 소스 파일의 속성 중 하나에 표시되지 않습니다.COMPILE_FLAGS

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

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

첫째 - 소스 파일의 속성은 포함되지 않습니다 COMPILE_OPTIONS만 COMPILE_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.