【问题标题】:CMake issues with trying to include my source files尝试包含我的源文件的 CMake 问题
【发布时间】:2015-05-09 14:09:00
【问题描述】:

我正在尝试在 Linux 上使用 CLion IDE,并且正在迁移我的 SFML 应用程序。它坚持我使用我目前遇到问题的 CMake。

cmake_minimum_required(VERSION 2.6)
project(SFML2)


include_directories("${PROJECT_BINARY_DIR} src/")
include_directories("${YOUR_DIRECTORY} src")

# Define sources and executable
set(EXECUTABLE_NAME "SFML")
add_executable(${EXECUTABLE_NAME} src/SFML.cpp)


# Detect and add SFML
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules"      
${CMAKE_MODULE_PATH})

find_package(SFML 2 REQUIRED system window graphics network audio)
target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES})

# Install target
install(TARGETS ${EXECUTABLE_NAME} DESTINATION bin)


# CPack packaging
include(InstallRequiredSystemLibraries)

但是我不断收到构建错误

CMakeFiles/SFML.dir/src/SFML.cpp.o: In function `main':
SFML.cpp:(.text+0xca): undefined reference to `Game::Game()'
SFML.cpp:(.text+0xd9): undefined reference to `Game::run()'
CMakeFiles/SFML.dir/src/SFML.cpp.o: In function `Game::~Game()':
SFML.cpp:(.text._ZN4GameD2Ev[_ZN4GameD5Ev]+0xa2): undefined reference to `Player::~Player()'
SFML.cpp:(.text._ZN4GameD2Ev[_ZN4GameD5Ev]+0xb4): undefined reference to `Player::~Player()'
SFML.cpp:(.text._ZN4GameD2Ev[_ZN4GameD5Ev]+0x18b): undefined reference to `Player::~Player()'
SFML.cpp:(.text._ZN4GameD2Ev[_ZN4GameD5Ev]+0x1a2): undefined reference to `Player::~Player()'
collect2: error: ld returned 1 exit status
CMakeFiles/SFML.dir/build.make:90: recipe for target 'SFML' failed
make[2]: *** [SFML] Error 1
CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/SFML.dir/all' failed
make[1]: *** [CMakeFiles/SFML.dir/all] Error 2
Makefile:136: recipe for target 'all' failed
make: *** [all] Error 2

游戏参考与 SFML.cpp 位于同一位置,这是启动所有内容的位置。

这目前在 Eclipse CDT 中没有问题

【问题讨论】:

    标签: c++ cmake sfml clion


    【解决方案1】:

    两个建议

    我不确定您打算如何处理包含路径。我的猜测是,这是一些实验的遗留物。您已经告诉 CMake 查看 2 个目录,这两个目录中都有一个空格。因为你可能没有包含空格的目录,所以我认为可以安全地删除它。

    include_directories("${PROJECT_BINARY_DIR} src/")
    include_directories("${YOUR_DIRECTORY} src")
    

    我不确定这些变量是在哪里定义的,但也许你的意思是这个

    include_directories(src)
    

    其次,CMake 可以使用通配符,但这不是推荐的方法。您应该在add_exectuable() 调用中明确列出所有源代码文件,即。

     add_exectuable(${EXECUTABLE_NAME}
          src/SFML.cpp
          src/SFML.h
          src/other.cpp
          src/other.h
         # and so on
     )
    

    不需要添加头文件,但如果您使用 Visual Studio 编译它会更好。

    【讨论】:

    • 但他的错误来自链接器...如果整个项目(用户部分)仅包含一个源文件,我认为如果此源用于构建正常,则 Player 无法未定义在迁移到 CLion/cmake 之前...
    • 他的错误来自链接器,但唯一的区别是在他拥有一个源文件之前,以及在他拥有相同的源文件以及src 文件夹中所有其他未提及的名称之后。所以肯定有他需要的源代码来自src
    【解决方案2】:

    只是为可能偶然发现此问题的任何其他人提供的更新。我将这几行编辑到我的代码中

    # Define sources and executable
    set(EXECUTABLE_NAME "SFML")
    
    file(GLOB SRC
        "src/*.h"
        "src/*.cpp"
    )
    
    add_executable(${EXECUTABLE_NAME} ${SRC})
    

    现在似乎可以工作,任何人都可以确认这是否是正确的方法吗?

    【讨论】:

    • file(GLOB 的 cmake 文档表明这不是正确的方法:“我们不建议使用 GLOB 从源代码树中收集源文件列表。如果没有 CMakeLists.txt 文件更改当添加或删除源时,生成的构建系统无法知道何时要求 CMake 重新生成。” - 虽然我在几个项目中见过它,并且在实践中它工作得很好(当添加新文件后,一个简单的 make 不足以构建项目时,只有开发人员偶尔会感到惊讶)。
    • 也许这样您在目标中包含多个源文件?并且链接错误消失了...
    猜你喜欢
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多