2016-10-06 2 views
2

현재 코드 범위와 테스트가있는 프로젝트 설정을 얻으려고합니다. 현재 스택은 IDE 용 Clion, 컴파일러 용 Clang, 적용 범위 용 gcov 및 lcov입니다. , 테스트 프레임 워크를위한 Unity, 테스트 중 mocking/stubbing을위한 CMock.C 테스트 - Unity 및 CMake를 사용하는 정의되지 않은 참조

I 현재 다음과 같은 패키지 구조를 가지고 :

SET(CMAKE_CXX_FLAGS "-O0") 
SET(CMAKE_C_FLAGS "-DLINUX -O0 -Wall -std=c99") 

set(SOURCE_FILES 
     util.c 
     util.h) 

add_executable(my_c_app ${SOURCE_FILES}) 

set(THREADS_PREFER_PTHREAD_FLAG ON) 
find_package(Threads REQUIRED) 
target_link_libraries(my_c_app Threads::Threads) 

target_include_directories(my_c_app PUBLIC ${PROJECT_SOURCE_DIR}/include) 
:

cmake_minimum_required(VERSION 3.6) 

project(my_c_app) 

set(CMAKE_C_COMPILER "/usr/bin/clang") 

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake/modules) 


set(CMAKE_VERBOSE_MAKEFILE ON) 

add_subdirectory(external) 
add_subdirectory(src) 
add_subdirectory(tests) 

내 응용 프로그램 수준 CMakeLists.txt은 다음과 같습니다처럼

app/root 
    | build 
     | *.* 
    |- cmake 
    |- modules 
     |- CodeCoverage.cmake 
    |- coverage 
     |- coverage.info 
    |- external 
     |- Unity 
     |- CMock 
     |- CMakeLists.txt 
    |- src 
     |- *.c 
     |- *.h 
     |- CMakeLists.txt 
    |- tests 
     |- *.c 
     |- *.h 
     |- CMakeLists.txt 
    |- CMakeLists.txt 

내 높은 수준의 CMakeLists.txt 보인다

테스트 레벨 CMakeLists.txt는 다음과 같습니다 :

enable_testing() 

include(CodeCoverage) 
include(CTest) 

SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage") 
SET(CMAKE_C_FLAGS "-DLINUX -O0 -Wall -std=c99 -g -fprofile-arcs -ftest-coverage") 

SETUP_TARGET_FOR_COVERAGE(coverage tests ${PROJECT_SOURCE_DIR}/coverage/coverage "'/usr/*';'tests/*';'external/*'") 

add_executable(tests util_test.c) 

target_link_libraries(tests Unity CMock) 

add_test(tests util_test.c) 

현재 제 문제는 올바르게 처리하지 못하고 있습니다. util.c의 기능을 테스트하는 동안 나는 정의되지 않은 참조를 얻고있다 :

CMakeFiles/tests.dir/util_test.c.o: In function `test_my_method': 
/home/patches/my_c_app/tests/util_test.c:6: undefined reference to `my_method' 

내 util_test.c는 현재 :

#include <unity.h> 
#include "../src/util.h" 

void test_my_method(void) { 
    uchar result = my_method(); 
    // assertion and other logic would go here 
} 

int main(void) { 
    UNITY_BEGIN(); 
    RUN_TEST(test_my_method); 
    return UNITY_END(); 
} 

나는 시험 중심의 C 개발 및 CMake에서 멍청한 놈이야 그래서 src에있는 c 파일에 종속되도록 내 테스트를 설정해야하는 적절한 방법은 무엇입니까? 난 그냥 대신 util.c 기능으로 전화를 걸의 TEST_ASSERT_EQUAL (1,1) 할 경우

내가 볼 않는 : 나는 100 %는 링커에 붙어있어 같은

1 Tests 0 Failures 0 Ignores 
OK 

Process finished with exit code 0 

를 그래서 나는 느낌이 어떤 종류의 문제.

답변

2

util.ctests 소스의 일부가 아니며 tests에 링크 된 라이브러리에서도 컴파일되지 않습니다. 따라서 에 my_method에 대한 정의를 제공하지 않으므로 정의되지 않은 참조입니다.

실행 파일 my_c_app의 소스에 main.c 파일이 없습니다. 귀하의 주요 기능은 util.c에 정의되어 있습니다. 내가 옳다 경우 main.c 파일에 그것을 밖으로 가지고 가고,에 앱 수준의 CMakeLists.txt을 변경

SET(CMAKE_CXX_FLAGS "-O0") 
SET(CMAKE_C_FLAGS "-DLINUX -O0 -Wall -std=c99") 

set(SOURCE_FILES 
     util.c 
     util.h) 

add_library(my_c_lib STATIC ${SOURCE_FILES}) 

set(THREADS_PREFER_PTHREAD_FLAG ON) 
find_package(Threads REQUIRED) 
target_link_libraries(my_c_app Threads::Threads) 

target_include_directories(my_c_app PUBLIC ${PROJECT_SOURCE_DIR}/include) 

add_executable(my_c_app main.c) 
target_link_libraries(my_c_app my_c_lib) 

지금 당신의 소스가 당신에 연결할 수 my_c_lib 정적 라이브러리에 컴파일됩니다. 앱이 반대 연결되어, 당신은뿐만 아니라 테스트 레벨 CMakeLists.txt에 대해 테스트를 연결할 수 있습니다

enable_testing() 

include(CodeCoverage) 
include(CTest) 

SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage") 
SET(CMAKE_C_FLAGS "-DLINUX -O0 -Wall -std=c99 -g -fprofile-arcs -ftest-coverage") 

SETUP_TARGET_FOR_COVERAGE(coverage tests ${PROJECT_SOURCE_DIR}/coverage/coverage "'/usr/*';'tests/*';'external/*'") 

add_executable(tests util_test.c) 

target_link_libraries(tests Unity CMock my_c_lib) 
             ^^^^^^^^ 

add_test(tests util_test.c) 

을이 라인 소개 : 나는에 서명을 볼 수 없습니다

add_test(tests util_test.c) 

documentation은 목표물과 그 출처를 가지고 있습니다. 이걸로 무엇을 이루려고합니까?당신이 C_STANDARD 대신 CMAKE_C_FLAGS를 사용하여 C 버전을 지정할 수 있습니다

참고 :

SET(CMAKE_C_STANDARD 99) 

컴파일 정의는 글로벌 오염을 방지 할뿐만 아니라 target_compile_definitions로 선언 할 수있다.

+0

세부 정보를 보내 주셔서 감사합니다. 당신이 말한 것은 명백합니다. 추가 복잡성을 위해, src 디렉토리는 * .so로 싸여 있지만 고유하고 내 상황에 대해 언급되지 않은 것은 레일 응용 프로그램에 * .so를 넣고 FFI를 사용하여 메인이 호출되도록합니다. 필요 없습니다. 나는 그것이 질문을 너무 복잡하게 만들 것이라고 생각했다. 나는 TEST_SOURCES가 src로부터 필요한 파일들로 정의 된 곳에'add_executable (tests $ {TEST_SOURCES})'를 추가함으로써 이것을 해결할 수 있었다. 그러나 그렇습니다, 당신이 말하는 것은 잘 받았습니다. – isuPatches