2016-10-06 5 views
2

現在、コードカバレッジとテストはC言語で行われています。私の現在のスタックはIDEの場合はClion、コンパイラの場合はClang、カバレッジの場合はgcovとlcovです。 、テストフレームワークのためのUnity、テスト中の模擬/スタブのためのCMock。Cテスト - UnityとCMakeで未定義のリファレンス

私は現在、次のパッケージ構造を持っている:

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) 
:マイアプリレベルCMakeLists.txtがどのように見える

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) 

:よう

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のでnoobのですだから、srcのcファイルに依存するように私のテストをセットアップするはずの正しい方法は何ですか?

私はちょうどTEST_ASSERT_EQUAL(1,1)を行う代わりに、util.c関数に電話をかける私は見ていた場合:

1 Tests 0 Failures 0 Ignores 
OK 

Process finished with exit code 0 

私はリンカー上の100%こだわっているようなので、私は感じます何らかの問題。

答えて

2

util.cは、testsの一部ではありません。testsにリンクされたライブラリでもコンパイルされていません。したがって、にはmy_methodの定義を提供しないため、未定義の参照です。

main.cファイルは、実行可能ファイルmy_c_appのソースにありません。あなたの主な機能は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静的ライブラリでコンパイルされています。このラインについて

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) 

を:あなたのアプリは、あなたが同様にあなたの試験レベルCMakeLists.txtで、それに対してテストをリンクすることができ、それに対してリンクされている

add_test(tests util_test.c) 

私はに署名を見ることができませんdocumentationはターゲットとそのソースを取得します。あなたはこれで何を達成しようとしていますか?あなたの代わりにCMAKE_C_FLAGSC_STANDARDを使用してCのバージョンを指定することも

注:

SET(CMAKE_C_STANDARD 99) 

コンパイルの定義は、グローバルな環境汚染を避けるためにtarget_compile_definitionsと同様に宣言することができます。

+0

ご連絡ありがとうございます。あなたが言っていたことはかなり明確です。複雑さを増すために、srcディレクトリは* .soにラップされていますが、私の状況では一意ではなく、* .soをレールアプリケーションに入れ、呼び出された場所にFFIを使用することで、メインが必要はありません。私はそれが問題を複雑すぎると感じていた。私は 'add_executable(tests $ {TEST_SOURCES})'を追加することでこれを回避することができました.TEST_SOURCESはsrcから必要なファイルで定義されています。しかし、はい、あなたが言っていることはよく受け入れられています。 – isuPatches

関連する問題