2012-08-07 3 views
4

현재 CMake를 사용하여 프로젝트를 만들고 CppUnit을 테스트하고 있습니다. 내 CMake 파일에서 나는 두 개의 실행 파일을 만든다. sample은 컴파일 된 소스입니다. 그리고 sample_test으로 테스트를 실행합니다. 난 내 CMakeLists.txtCppUnit과 CMake : .cpp 파일이 두 번 컴파일됩니다.

SET(SAMPLE_ROOT_PATH ${PROJECT_BINARY_DIR}) 
SET(SAMPLE_SOURCE_PATH ${SAMPLE_ROOT_PATH}/src) 
SET(SAMPLE_TEST_SOURCE_PATH ${SAMPLE_ROOT_PATH}/test) 
SET(SAMPLE_BIN_PATH ${SAMPLE_ROOT_PATH}/bin) 
SET(SAMPLE_EXEC_NAME sample) 
SET(SAMPLE_TEST_EXEC_NAME sample_test) 

SET(EXECUTABLE_OUTPUT_PATH ${SAMPLE_BIN_PATH}) 

FILE(GLOB_RECURSE SAMPLE_SOURCE_FILES ${SAMPLE_SOURCE_PATH}/*.cpp) 
FILE(GLOB_RECURSE SAMPLE_TEST_SOURCE_FILES ${SAMPLE_TEST_SOURCE_PATH}/*.cpp) 
SET(SAMPLE_TEST_SOURCE_FILES ${SAMPLE_TEST_SOURCE_FILES} ${SAMPLE_SOURCE_FILES} 
) 
LIST(REMOVE_ITEM SAMPLE_TEST_SOURCE_FILES ${SAMPLE_SOURCE_PATH}/main.cpp) 

SET(CMAKE_CXX_FLAGS "-g -Wall") 

ADD_EXECUTABLE(${SAMPLE_EXEC_NAME} ${SAMPLE_SOURCE_FILES}) 
ADD_EXECUTABLE(${SAMPLE_TEST_EXEC_NAME} ${SAMPLE_TEST_SOURCE_FILES}) 

의 여기에 일부

r에 경우이 Object.cpp, World.cppKeyBuffer.cpp 두 번 컴파일 얻을 당신이 볼 수 있듯이 make

[ 8%] Building CXX object CMakeFiles/sample.dir/src/KeyBuffer.cpp.obj 
[ 12%] Building CXX object CMakeFiles/sample.dir/src/main.cpp.obj 
[ 20%] Building CXX object CMakeFiles/sample.dir/src/Object.cpp.obj 
[ 45%] Building CXX object CMakeFiles/sample.dir/src/World.cpp.obj 
Linking CXX executable bin/sample.exe 
[ 45%] Built target sample 
[ 50%] Building CXX object CMakeFiles/sample_test.dir/test/KeyBufferTest.cpp.obj 

[ 54%] Building CXX object CMakeFiles/sample_test.dir/test/ObjectTest.cpp.obj 
[ 66%] Building CXX object CMakeFiles/sample_test.dir/src/KeyBuffer.cpp.obj 
[ 75%] Building CXX object CMakeFiles/sample_test.dir/src/Object.cpp.obj 
[100%] Building CXX object CMakeFiles/sample_test.dir/src/World.cpp.obj 
Linking CXX executable bin/sample_test.exe 

의 출력입니다! 어떻게 방지 할 수 있습니까? 아니면 CMake를 사용하여 CppUnit 테스트를 처리하는 더 좋은 방법이 있습니까?

답변

4

각 대상에는 서로 다른 컴파일러 플래그가 구성되어있을 수 있으므로 두 개의 대상에 하나의 원본 파일을 추가하는 경우 두 대상에 대해이 하나의 원본 파일에서 개별 개체 파일을 생성해야합니다.

일반적인 해결책은 공유 소스 파일을 정적 라이브러리로 컴파일 한 다음 두 응용 프로그램 대상에 링크하는 것입니다.

+0

좋아요.이 제품을 사용해 보겠습니다. – MarcDefiant

4

개념적으로 CMake는 각 타겟 (즉, 실행 파일 또는 라이브러리)을 별도의 빌드 단위로 취급합니다. 생성 된 빌드 시스템은 대상에 속한 각 소스 파일에 대한 오브젝트 파일을 생성합니다. 기본적으로 CMake는 컴파일 설정 (컴파일 플래그, 전 처리기 정의 ...)이 정확히 동일하더라도 여러 타겟에서 사용되는 소스 파일의 중복 된 컴파일을 피할 수 없습니다.

개체 라이브러리를 사용 add_library 생성하려면 :

CMake 2.8.8은 new feature 피하는 중복 컴파일의 문제를 해결하기 위해 OBJECT_LIBRARY 목표라고 소개 add_library 또는 add_executable 만든

FILE(GLOB_RECURSE SAMPLE_SOURCE_FILES ${SAMPLE_SOURCE_PATH}/*.cpp) 
ADD_LIBRARY(sample_objects OBJECT EXCLUDE_FROM_ALL ${SAMPLE_SOURCE_FILES}) 

다른 목표를 할 수있다 $<TARGET_OBJECTS:objlib>의 표현식을 사용하여 객체를 참조하십시오.

ADD_EXECUTABLE(${SAMPLE_EXEC_NAME} $<TARGET_OBJECTS:sample_objects>) 

FILE(GLOB_RECURSE SAMPLE_TEST_SOURCE_FILES ${SAMPLE_TEST_SOURCE_PATH}/*.cpp) 
ADD_EXECUTABLE(${SAMPLE_TEST_EXEC_NAME} $<TARGET_OBJECTS:sample_objects> ${SAMPLE_TEST_SOURCE_FILES}) 

중복 컴파일을 피하기 위해 일반 정적 라이브러리를 사용하는 경우와 비교할 때 객체 라이브러리는 링크 할 필요가 없다는 장점이 있습니다. 그 위에는 가져 오기, 내보내기 또는 설치가 불가능합니다.