2012-11-30 1 views
73

하나의 파일에 대한 플래그를 컴파일 특정 파일 ("foo.cpp"라고 가정 해 봅시다) 하위 디렉토리에 컴파일 플래그를 적용하지 않으려면 -WeffC++ (변경할 수없는 상용 라이브러리 포함)로 전환하고 싶습니다. 상황을 단순화하기 위해 -Wall만을 사용하기 위해 시도했습니다.재정의 내 최상위 CMakeLists.txt 파일에 내가 지정한 것을 의미한다, 내가 프로젝트를 컴파일 플래그의 글로벌 설정을 사용하고자하는

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

이 작동하지 않았습니다. 는 또한 일하지 둘 다있는

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

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

을 시도했다.

마지막으로, 나는이 (고화질) 제거 시도 :

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

+0

관련 항목 : [CMake에서 단 하나의 실행 파일 만 컴파일러 플래그를 변경하는 방법?] (https://stackoverflow.com/q/24238937/608639) Andre의 대답은 기존 옵션을 새로운 옵션으로 대체하는 방법 인 것으로 나타났습니다 . – jww

답변

87

위의 시도는 예상대로 덮어 쓰지 않고 플래그/파일을 추가하는 것입니다. 예를 들어, Properties on Source Files - COMPILE_FLAGS의 문서에서 :

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

당신은 컴파일러 명령에 -Weffc++-Wno-effc++를 추가하는 효과, 후자 설정 승리해야

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

를 수행하여 foo.cpp에의 -Weffc++ 플래그를 취소하다 할 수 있어야한다. 전체 명령을 참조하십시오이 참 경우가 있음을 확인하려면, 당신은 옆으로

make VERBOSE=1 

을 할 수 있으며, GNU C++ 표준 라이브러리의 관리자들 중 하나는 this answer-Weffc++에 매우 부정적인 의견을 제시한다.

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

그것은 사용하는 것이 바람직 할 것이다

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

또는 CMake 버전 < 3 add_compile_options.응답에서

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

아래의 의견에 질문을 촉진하는, 나는 그것이 확실하게 하나의 파일에에게 플래그를 제거하는 것은 불가능하다고 생각 : 0 뭔가 더 좋아해야 할 일. 그 이유는 특정 소스 파일의 경우 대상의 COMPILE_OPTIONSCOMPILE_FLAGS 이 적용되었지만 해당 소스 파일의 속성에는 표시되지 않기 때문입니다.

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

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

첫 번째 - source files' propertiesCOMPILE_OPTIONS, 단지 COMPILE_FLAGS을 포함하지 않습니다. 타겟의 COMPILE_OPTIONSgenerator expressions이 포함될 수 있지만 COMPILE_FLAGS은 해당 타겟을 지원하지 않기 때문에 문제가됩니다. 따라서 깃발을 검색하는 동안 발전기 표현을 수용해야하며, 플래그가 하나 이상의 플래그에 포함되어 있으면 생성자 표현식을 "구문 분석"해야 할 수도 있습니다. 플래그가 하나 이상의 플래그가 나머지 플래그에 다시 적용되어야하는지 여부를 확인해야합니다. 소스 파일.

두 번째 - CMake v3.0 이후로 대상에 INTERFACE_COMPILE_OPTIONS을 지정할 수 있습니다. 즉, 대상의 종속성이 INTERFACE_COMPILE_OPTIONS을 통해 대상의 COMPILE_OPTIONS을 추가하거나 무시할 수 있습니다. 따라서 대상의 종속성을 재귀 적으로 반복해야합니다 (대상에 대한 LINK_LIBRARIES의 목록에는 생성자 표현식도 포함될 수 있으므로 특히 쉬운 작업이 아닙니다). 문제 플래그를 적용하는 대상을 찾고 시도해보십시오 그 목표는 INTERFACE_COMPILE_OPTIONS입니다.

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


1 : 소스 파일에 COMPILE_FLAGS 특성과는 달리 그 참고 대상에서 COMPILE_FLAGS 속성이 사용되지 않습니다.

+5

하지만 실제로 파일을 추가하지 않고 별도로 컴파일 플래그를 설정하는 방법은 무엇입니까? 예를 들어 파일 대신 결과 타겟에 다른 컴파일 플래그를 사용하고 싶지만 추가 된 이후에 수동으로 제거해야합니다. 추가하지 않지만 실제로 지정된 파일/대상에 대해서만 속성을 설정하는 속성이 있습니까? –

+2

-fno-flag를 사용할 수 없거나 (-fflag가 설정된 경우) 우리가 할 수있는 일은 무엇입니까? – gnzlbg

+0

@ Baradé 원본 파일을 저장할 수 없습니다. – Fraser