【问题标题】:CMake cannot find a static library using relative file pathsCMake 找不到使用相对文件路径的静态库
【发布时间】:2015-05-16 11:16:52
【问题描述】:

我想使用Allegro 库,但我似乎无法让我的测试项目正确链接。确切地说,我收到了cannot find -l<...> 错误,其中<...> 是我使用target_link_libraries 指定的文件。 (详情见下文。)

为了记录,我对构建过程并不是很了解,我通常的做法是“单击一个按钮并希望弹出一个可执行文件,如果没有,请尝试试错。”我在这里发现了很多类似的问题,但似乎问题或解决方案与我所遇到的不同。我希望有一个明确的“这就是你做错的地方,这是你应该做的”。

也就是说,这是我的项目结构:

/include
/lib
/src
    main.cpp
CMakeLists.txt

我从Allegro binary package 复制的include 和lib 目录,lib 是所有.a 文件所在的位置。

这是我的 CMakeLists.txt 所说的:

cmake_minimum_required(VERSION 3.2)
project(AllegroTest)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -static-libgcc -static-libstdc++ -fpermissive")
add_definitions( -DALLEGRO_STATICLINK )

file(GLOB SOURCES src/*.cpp)
set(SOURCE_FILES ${SOURCES})
add_executable(AllegroTest ${SOURCE_FILES})

include_directories(include)

target_link_libraries(AllegroTest
    liballegro-5.0.10-static-mt.a
    liballegro_acodec-5.0.10-static-mt.a
    liballegro_audio-5.0.10-static-mt.a
    libvorbisfile-1.3.2-static-mt.a
    libvorbis-1.3.2-static-mt.a
    liballegro_color-5.0.10-static-mt.a
    liballegro_dialog-5.0.10-static-mt.a
    liballegro_font-5.0.10-static-mt.a
    liballegro_image-5.0.10-static-mt.a
    liballegro_memfile-5.0.10-static-mt.a
    liballegro_physfs-5.0.10-static-mt.a
    liballegro_primitives-5.0.10-static-mt.a
    liballegro_ttf-5.0.10-static-mt.a
    libdumb-0.9.3-static-mt.a
    libFLAC-1.2.1-static-mt.a
    libfreetype-2.4.8-static-mt.a
    libogg-1.2.1-static-mt.a
    libzlib-1.2.5-static-mt.a
    libopenal-1.14-static-mt.a
)

target_link_libraries(AllegroTest
    libgdiplus.a
    libuuid.a
    libkernel32.a
    libwinmm.a
    libpsapi.a
    libopengl32.a
    libglu32.a
    libuser32.a
    libcomdlg32.a
    libgdi32.a
    libshell32.a
    libole32.a
    libadvapi32.a
    libws2_32.a
    libshlwapi.a
)

这些是我得到的错误:

c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find -lallegro-5.0.10-static-mt
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find -lallegro_acodec-5.0.10-static-mt
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find -lallegro_audio-5.0.10-static-mt
<etc.>

我尝试过以各种可以想象的方式指定路径——包括将其与link_directories(lib) 的用法结合起来——但似乎没有任何效果。

的唯一工作是指定绝对路径 (C:/Users/&lt;...&gt;/lib/liballegro-5.0.10-static-mt.a),但我觉得这远非理想的方式。

我在这里犯了什么错误,建议的修复方法是什么?

【问题讨论】:

    标签: c++ linker cmake allegro


    【解决方案1】:

    我推荐的方式 使用绝对路径。我不确定您为什么认为这远非理想;实现起来很简单:

    target_link_libraries(AllegroTest
        ${CMAKE_CURRENT_SOURCE_DIR}/lib/liballegro-5.0.10-static-mt.a
        ${CMAKE_CURRENT_SOURCE_DIR}/lib/liballegro_acodec-5.0.10-static-mt.a
        etc.
    )
    

    【讨论】:

    • 我觉得使用绝对路径,项目将不再是自包含的,而是依赖于它的环境。我想CMAKE_CURRENT_SOURCE_DIR 是一种解决方法,所以感谢您提及这一点。但是,真的没有办法使用真正的相对路径吗?在我看来应该有。
    • 老实说,我希望 link_directories(lib) 能解决这个问题,但不鼓励使用 link_directories - 即使在其 own documentation 中也是如此。找到CMAKE_SOURCE_DIRCMAKE_CURRENT_SOURCE_DIR 的实例很常见——我认为这实际上是一种很好的做法。如果您不确定它们是否将路径视为相对于源根目录或构建根目录,则无需检查文档以查找命令。
    • 至少现在我理解你不愿意,如果你认为你必须从你自己的机器上硬编码绝对路径——这确实应该不惜一切代价避免:)
    • 作为替代方案,您始终可以插入一个附加的find_library call,它将硬编码的${CMAKE_CURRENT_SOURCE_DIR}/lib/... 作为提示,以及用户可自定义的第二个提示。我个人喜欢留出一个环境变量,允许用户为库注入自定义路径,该路径优先于任何硬编码路径。
    • 另外不要忘记清除 cmake 缓存。有时您需要手动完成以修复配置怪癖。
    【解决方案2】:

    我以前做过类似的事情,我做的是这样的:

    link_directories(lib)
    target_link_libraries(my_target
        allegro-5.0.10-static-mt
        allegro_acodec-5.0.10-static-mt
        ...
    )
    

    请注意,没有前导 lib 和尾随 .a

    【讨论】:

    • 我不会反对,因为这应该可以工作,但 docs for link_directories 不鼓励使用它,而是将完整路径传递给 target_link_libraries
    • 这对我不起作用。 (很确定这也是我已经尝试过的方法之一。)
    • @vvye 它确实有效。但是“该命令将仅适用于调用后创建的目标。”。所以把link_directories放在add_executable之前可以解决你的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    • 1970-01-01
    相关资源
    最近更新 更多