【问题标题】:Building library with cmake使用 cmake 构建库
【发布时间】:2023-04-07 03:49:01
【问题描述】:

很抱歉打扰大家,但是我在 cmake 编译时遇到了一点问题。

我有一个用于构建测试可执行文件的 CMakeLists.txt 文件和一个共享库。它们都依赖于另一个库 (SFML)。

我在带有 MinGW 的窗口上使用 cmake。

我知道我正在构建的库的名称与 sfml 的名称有点混淆,但它应该是 SFML 包装器,所以我没有找到更好的名称!

这里是 CMakeLists.txt

cmake_minimum_required(VERSION 2.6)
project(projectName)

set(EXECUTABLE_NAME testSFML)
set(LIBRARY_NAME    SFMLwindow)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin/)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include /
${CMAKE_CURRENT_SOURCE_DIR}/../../include
)

link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/)

file(
    GLOB_RECURSE
    SRC_FILES
    src/*
)

file(
    GLOB_RECURSE
    INCLUDE_FILES
    include/*
)

add_executable(
${EXECUTABLE_NAME}
main.cpp
${SRC_FILES}
${INCLUDE_FILES}
)

target_link_libraries(
    ${EXECUTABLE_NAME}
    sfml-main
    sfml-system
    sfml-window
)


add_library(
${LIBRARY_NAME}
SHARED
${SRC_FILES}
)

我在终端得到了什么:

"C:\MinGW\bin\mingw32-make.exe" 
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/iksemel/docs/WorkBench/programming/projets/TestSFML/cmake
Linking CXX shared library libSFMLwindow.dll
Creating library file: libSFMLwindow.dll.a
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x59):undefined reference to `_imp___ZN2sf9VideoModeC1Ejjj'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0xda): undefined reference to `_imp___ZN2sf6WindowC1ENS_9VideoModeERKSsjRKNS_15ContextSettingsE'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x163): undefined reference to `_imp___ZN2sf6Window5closeEv'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x1bd): undefined reference to `_imp___ZN2sf6Window9pollEventERNS_5EventE'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x1d8): undefined reference to `_imp___ZN2sf6Window7displayEv'
collect2: ld a retourné 1 code d'état d'exécution
mingw32-make.exe[2]: *** [libSFMLwindow.dll] Error 1
mingw32-make.exe[1]: *** [CMakeFiles/SFMLwindow.dir/all] Error 2
mingw32-make.exe: *** [all] Error 2

如果有人知道发生了什么,我将不胜感激!

【问题讨论】:

    标签: c++ build cmake shared sfml


    【解决方案1】:

    猜测一下,您的SFMLwindow 库需要链接到部分或全部 sfml-main、sfml-system、sfml-window。

    您可以尝试将 CMakeLists.txt 的结尾更改为:

    add_library(
        ${LIBRARY_NAME}
        SHARED
        ${SRC_FILES}
        ${INCLUDE_FILES}
    )
    
    add_executable(
        ${EXECUTABLE_NAME}
        main.cpp
    )
    
    target_link_libraries(
        ${LIBRARY_NAME}
        sfml-main
        sfml-system
        sfml-window
    )
    
    target_link_libraries(
        ${EXECUTABLE_NAME}
        ${LIBRARY_NAME}
    )
    


    顺便说一句,file(GLOB_RECURSE... 通常不被视为收集来源列表的一种方式。来自file 的文档:

    我们不建议使用 GLOB 从源代码树中收集源文件列表。如果在添加或删除源时没有 CMakeLists.txt 文件发生更改,则生成的构建系统无法知道何时要求 CMake 重新生成。


    此外,在这种情况下,find_library 应优先于 link_directories。来自link_directories 的文档:

    请注意,很少需要此命令。 find_package() 和 find_library() 返回的库位置是绝对路径。将这些绝对库文件路径直接传递给 target_link_libraries() 命令。 CMake 将确保链接器找到它们。

    【讨论】:

    • 感谢您的帮助,我编辑了我的 CMakeLists.txt,但它似乎还没有工作。但奇怪的是,如果我只构建可执行文件,它工作正常,只有在构建库时我才会遇到这个问题。 .o 文件似乎是按应有的方式创建的。我的 CmakeLists.txt 现在:pastebin.com/hLux8Lvi
    • 我发现了问题!您对链接问题的看法是正确的,但要纠正它,我不得不使用 2 个 target_link_libraries。一个用于可执行文件,另一个用于库。我遇到的另一个问题是命令顺序。 target_link_libraries 似乎必须出现在 add_executable 和 add_library 之后。这是我当前的 cmake,再次感谢您提供有关 cmake 的一般信息并帮助我! pastebin.com/ErgbGir0
    • 好的 - 很高兴它有效。我们的解决方案之间的主要区别在于您将源代码编译到库 exe 中。这对于小型项目来说是可以的,但如果你有很多源文件,那就麻烦了。通常,您只需将源代码编译一次到库中,然后将该库链接到测试 exe。使用 CMake,如果您指定 lib A 依赖于 lib B,而 exe Z 依赖于 lib A,那么它也会自动将 lib B 添加为 Z 的依赖项。这就是为什么我只指定${LIBRARY_NAME} 作为${EXECUTABLE_NAME} 的依赖项。不过没什么大不了的:-)
    • 再次感谢您的体验!我现在清楚地了解您要我做什么,我必须承认您的解决方案非常有效!我根据你编辑了我的 CMakeLists.txt:pastebin.com/xL5FATsL
    猜你喜欢
    • 1970-01-01
    • 2022-01-07
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    • 2019-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多