CMake无法正确链接库

时间:2018-04-06 12:24:53

标签: c cmake linker googletest

我正在做作业,而我的项目树是

.
├── CMakeLists.txt
├── main.c
├── src
│   ├── CMakeLists.txt
│   ├── game
│   │   ├── game.c
│   │   └── game.h
│   └── main.c
└── test
    ├── CMakeLists.txt
    ├── homework_tests
    │   ├── CMakeLists.txt
    │   ├── gtest.cpp
    │   └── gtest.h
    └── lib
        └──googletest
            └──googletest
                └──[library files (not compiled)]

main.c文件里面只有一个“Hello,world”。 在您阅读之前: 我想:
1.从源文件中构建目标src.so 2.构建谷歌测试库(在test/lib/文件夹中)
3.从runBasicTests文件夹中构建目标tests/ 4.将它们链接在一起

我承认我不是CMake的主人,所以要注意这一点。

文件

现在,假设我们在项目根.

./

的CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(c_homework)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=c11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES
        main.c)

add_executable(homework_run ${SOURCE_FILES})

add_subdirectory(src)
add_subdirectory(test)

target_link_libraries(homework_run src.so)

src/

的CMakeLists.txt

set(SOURCE_FILES
        game/game.c)

add_library(src.so ${SOURCE_FILES})

target_include_directories (src.so PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

游戏/ game.h

#ifndef C_HOMEWORK_GAME_H
#define C_HOMEWORK_GAME_H

#include <stdbool.h>

struct game_t {
    int id, price;
    const char *country_code;
};

bool is_game_available(struct game_t, const char[4]);
int how_many_available(struct game_t*, size_t, const char[4]);

#endif //C_HOMEWORK_GAME_H

游戏/ game.c

#include <string.h>
#include "game.h"

bool is_game_available(struct game_t game, const char country_code[4]) 
{
    return strcmp(game.country_code, country_code) == 0;
}

int how_many_available(struct game_t * games, size_t game_count, const 
char country_code[4]) {
    int available_games = 0;
    for (int i = 0; i < game_count; i++) {
        if (is_game_available(games[i], country_code)) {
            available_games++;
        }
    }
    return available_games;
}

test/

的CMakeLists.txt

project(homework_tests)

add_subdirectory(lib/googletest/googletest)
add_subdirectory(homework_tests)

homework_tests /的CMakeLists.txt

include_directories(${gTest_SOURCE_DIR}/include ${gTest_SOURCE_DIR})

add_executable(runBasicTests
        gtest.cpp)

target_link_libraries(runBasicTests gtest gtest_main)
target_link_libraries(runBasicTests src.so)

homework_tests / gtest.cpp

#include "gtest.h"
#include <game/game.h>

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

TEST(gameTests, gameTest1) {
    struct game_t game{};
    game.country_code = "359";
    game.id = 1;
    game.price = 69;
    EXPECT_EQ(is_game_available(game, "359"), true);
}

homework_tests / gtest.h

#ifndef MYPROJECTNAME_GTEST_H
#define MYPROJECTNAME_GTEST_H

#include "gtest/gtest.h"

#endif //MYPROJECTNAME_GTEST_H

问题是,当我尝试运行测试时,出现链接器错误:

/opt/clion-2018.1/bin/cmake/bin/cmake --build 
/home/denis/CLionProjects/c_homework/cmake-build-debug --target 
runBasicTests -- -j 1

[ 25%] Built target gtest
Scanning dependencies of target src.so
[ 37%] Building C object src/CMakeFiles/src.so.dir/game/game.c.o
[ 50%] Linking C static library libsrc.so.a
[ 50%] **Built target src.so**
[ 75%] Built target gtest_main
[ 87%] Linking CXX executable runBasicTests
CMakeFiles/runBasicTests.dir/gtest.cpp.o: In function 
`gameTests_gameTest1_Test::TestBody()':
/home/denis/CLionProjects/c_homework/test/homework_tests/gtest.cpp:18:

          <---------------   Here   ----------------->   
undefined reference to `is_game_available(game_t, char const*)'
collect2: error: ld returned 1 exit status

test/homework_tests/CMakeFiles/runBasicTests.dir/build.make:98: recipe 
for target 'test/homework_tests/runBasicTests' failed
make[3]: *** [test/homework_tests/runBasicTests] Error 1
CMakeFiles/Makefile2:294: recipe for target 
'test/homework_tests/CMakeFiles/runBasicTests.dir/all' failed
make[2]: *** [test/homework_tests/CMakeFiles/runBasicTests.dir/all] 
Error 2
CMakeFiles/Makefile2:306: recipe for target 
'test/homework_tests/CMakeFiles/runBasicTests.dir/rule' failed
make[1]: *** [test/homework_tests/CMakeFiles/runBasicTests.dir/rule] 
Error 2
Makefile:170: recipe for target 'runBasicTests' failed
make: *** [runBasicTests] Error 2
  • 不需要我的库运行的测试
  • src/文件夹中的目标以及与src.so库的链接也会运行相同的

1 个答案:

答案 0 :(得分:0)

问题是我从C ++代码调用C代码而C ++编译器改变了函数名称(名称修改),这就是我收到错误和undefined reference错误的原因。

解决方案是告诉编译器以下函数声明是外部的&#34; C&#34;代码。

测试/ homework_tests / GTEST

#ifdef __cplusplus
extern "C" {
#endif
    /* Declarations of this file */
    bool is_game_available(struct game_t, const char[4]);
    int how_many_available(struct game_t *, size_t, const char[4]);
#ifdef __cplusplus
}
#endif

解决了这个问题。谢谢大家。 XD