CMake : 단위 테스트를 사용한 프로젝트 구조

프로덕션 소스 ( src하위 폴더) 및 테스트 (하위 폴더) 를 포함하도록 프로젝트를 구성하려고합니다 test. CMake를 사용하여이를 빌드하고 있습니다. 최소한의 예로 다음 파일이 있습니다.

CMakeLists.txt :

cmake_minimum_required (VERSION 2.8) 
project (TEST) 

add_subdirectory (src) 
add_subdirectory (test) 

src / CMakeLists.txt :

add_executable (demo main.cpp sqr.cpp) 

src / sqr.h

#ifndef SQR_H
#define SQR_H
double sqr(double);    
#endif // SQR_H

src / sqr.cpp

#include "sqr.h"
double sqr(double x) { return x*x; }

src / main.cpp-sqr을 사용하지만 실제로는 중요하지 않습니다

test / CMakeLists.txt :

find_package(Boost COMPONENTS system filesystem unit_test_framework REQUIRED)

include_directories (${TEST_SOURCE_DIR}/src) 

ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK) 

add_executable (test test.cpp ${TEST_SOURCE_DIR}/src/sqr.cpp) 

target_link_libraries(test
                      ${Boost_FILESYSTEM_LIBRARY}
                      ${Boost_SYSTEM_LIBRARY}
                      ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                      )

enable_testing()
add_test(MyTest test)

test / test.cpp :

#define BOOST_TEST_MODULE SqrTests
#include <boost/test/unit_test.hpp>

#include "sqr.h"

BOOST_AUTO_TEST_CASE(FailTest)
{
    BOOST_CHECK_EQUAL(5, sqr(2));
}

BOOST_AUTO_TEST_CASE(PassTest)
{
    BOOST_CHECK_EQUAL(4, sqr(2));
}

몇 가지 질문 :

  1. 이 구조가 의미가 있습니까? 이 코드를 구성 할 때 모범 사례는 무엇입니까? (C #과 java에서 왔으며 어떤 의미에서는 더 쉽습니다)
  2. 파일의 src폴더에서 모든 파일을 나열해야한다는 사실이 마음에 들지 않습니다 test/CMakeLists.txt. 이것이 라이브러리 프로젝트 인 경우 라이브러리를 링크하면됩니다. 다른 프로젝트의 모든 cpp 파일을 나열하지 않는 방법이 있습니까?
  3. 라인 무엇 enable_testing()add_test(MyTest test)일이? 효과가 없습니다. CMake (또는 CTest)에서 테스트를 실행하려면 어떻게해야합니까?
  4. 지금까지는 cmake .루트 폴더에서 방금 실행 했지만 임시 파일이 어디서나 엉망이되었습니다. 합리적인 구조로 컴파일 결과를 얻으려면 어떻게해야합니까?


답변

질문 1 및 2의 경우 main.cpp (이 경우 src / sqr.cpp 및 src / sqr.h)를 제외한 테스트 파일이 아닌 파일에서 라이브러리를 만드는 것이 좋습니다. 그러면 목록을 피할 수 있습니다 (더 중요하게 모든 소스를 두 번 다시 컴파일하십시오.

질문 3의 경우,이 명령은 “MyTest”라는 테스트를 추가하여 인수없이 실행 가능한 “test”를 호출합니다. 그러나 최상위 CMakeLists.txt가 아닌 test / CMakeLists.txt에 이러한 명령을 추가 했으므로 빌드 트리의 “test”서브 디렉토리 내에서만 테스트를 호출 할 수 있습니다 (try cd test && ctest -N). 최상위 빌드 디렉토리에서 테스트를 실행 add_test하려면 최상위 CMakeLists.txt에서 호출해야합니다 . 또한 add_test테스트 exe가 동일한 CMakeLists.txt에 정의되어 있지 않기 때문에 더 자세한 형태를 사용해야 함을 의미합니다.

귀하의 경우 루트 폴더에서 cmake를 실행하기 때문에 빌드 트리와 소스 트리가 동일합니다. 이것은 소스 빌드로 알려져 있으며 이상적이지 않으므로 질문 4로 이어집니다.

빌드 트리를 생성하는 데 선호되는 방법은 소스 외부 빌드를 수행하는 것입니다. 즉, 소스 트리 외부에 디렉토리를 작성하고 cmake를 실행하는 것입니다. 프로젝트 루트에 “빌드”디렉토리를 만들고 실행하더라도 cmake ..소스 트리를 방해하지 않는 깔끔한 구조를 제공 할 수 있습니다.

마지막으로 실행 파일을 “test”(대소 문자 구분)로 호출하지 마십시오. 그 이유는 이 답변을 참조하십시오 .

이러한 변경을 달성하기 위해 다음을 수행합니다.

CMakeLists.txt :

cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src) 
add_subdirectory (test)
enable_testing ()
add_test (NAME MyTest COMMAND Test)

src / CMakeLists.txt :

add_library (Sqr sqr.cpp sqr.h)
add_executable (demo main.cpp)
target_link_libraries (demo Sqr)

test / CMakeLists.txt :

find_package (Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src
                     ${Boost_INCLUDE_DIRS}
                     )
add_definitions (-DBOOST_TEST_DYN_LINK)
add_executable (Test test.cpp)
target_link_libraries (Test
                       Sqr
                       ${Boost_FILESYSTEM_LIBRARY}
                       ${Boost_SYSTEM_LIBRARY}
                       ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                       )

답변

나는 @Fraser의 예를 좋아하지만 test / CMakeLists.txt에서 add_test 명령을 사용하고 add_subdirectory (test) 전에 enable_testing을 사용합니다.

이렇게하면 test / CMakeLists.txt에 테스트를 지정하면서 최상위 빌드 디렉토리에서 테스트를 실행할 수 있습니다.

결과는 다음과 같습니다 (@Fraser의 예를 재사용했습니다).

CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src)

enable_testing ()
add_subdirectory (test)

src / CMakeLists.txt

add_library (Sqr sqr.cpp sqr.h)
add_executable (demo main.cpp)
target_link_libraries (demo Sqr)

test / CMakeLists.txt

find_package (Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src
                     ${Boost_INCLUDE_DIRS}
                     )
add_definitions (-DBOOST_TEST_DYN_LINK)
add_executable (Test test.cpp)
target_link_libraries (Test
                       Sqr
                       ${Boost_FILESYSTEM_LIBRARY}
                       ${Boost_SYSTEM_LIBRARY}
                       ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                       )
add_test (NAME MyTest COMMAND Test)