c++ - 从项目 CMakeLists.txt 链接相互依赖的库?
问题描述
我对 CMake 有很大的误解,我无法按照 StackOverflow 上的常见建议来解决。我有以下项目:
# SDL2
add_subdirectory(vendor/SDL2-2.0.16)
set(SDL2_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/vendor/SDL2-2.0.16/include")
set(SDL2_LIBRARY "SDL2")
set(SDL2_LIBDIR "${PROJECT_SOURCE_DIR}/vendor/SDL2-2.0.16")
# ogg
add_subdirectory(vendor/libogg-1.3.5)
set(OGG_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/vendor/libogg-1.3.5/include")
set(OGG_LIBRARY "ogg")
# vorbis
add_subdirectory(vendor/libvorbis-1.3.7)
set(OGG_VORBIS_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/vendor/libvorbis-1.3.7/include")
set(OGG_VORBIS_LIBRARY "vorbis")
# SDL2 Mixer
add_subdirectory(vendor/SDL2_mixer-2.0.4)
set(SDL2_MIXER_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/vendor/SDL2_mixer-2.0.4")
set(SDL2_MIXER_LIBRARY "SDL_mixer")
add_executable(myProject ${MY_PROJECT_SOURCES})
target_include_directories(myProject PRIVATE ${MY_PROJECT_INCLUDE_DIRS} PUBLIC ${SDL2_INCLUDE_DIR} ${SDL2_MIXER_INCLUDE_DIR})
target_link_libraries(myProject PUBLIC ${SDL2_LIBRARY} ${SDL2_MIXER_LIBRARY})
这个想法是提供构建 SDL2 和 SDL2_mixer 所需的所有依赖项。到目前为止,这意味着 ogg 和 vorbis。我为 ogg 创建了一个非常简单的 CMakeLists.txt:
cmake_minimum_required(VERSION 3.2)
project(libogg)
configure_file(include/ogg/config_types.h.in include/ogg/config_types.h @ONLY)
set(OGG_HEADERS
${CMAKE_CURRENT_BINARY_DIR}/include/ogg/config_types.h
include/ogg/ogg.h
include/ogg/os_types.h
)
set(OGG_SOURCES
src/bitwise.c
src/framing.c
src/crctable.h
)
if(WIN32 AND BUILD_SHARED_LIBS)
list(APPEND OGG_SOURCES win32/ogg.def)
endif()
add_library(ogg ${OGG_HEADERS} ${OGG_SOURCES})
target_include_directories(ogg PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
vorbis 也有类似的情况。SDL_mixer 的那个也很简单:
cmake_minimum_required(VERSION 3.2)
project(SDL_mixer VERSION 2.0.4)
set(ENABLE_DEFS "MUSIC_OGG")
set(SRC_C_FILES bla bla bla)
set(SRC_H_FILES bla bla bla)
add_library(SDL_mixer ${SRC_C_FILES} ${SRC_H_FILES})
target_link_libraries(SDL_mixer PUBLIC ${SDL2_LIBRARY} ${OGG_LIBRARY} ${OGG_VORBIS_LIBRARY})
target_include_directories(SDL_mixer PUBLIC ${SDL2_INCLUDE_DIR} ${OGG_INCLUDE_DIR} ${OGG_VORBIS_INCLUDE_DIR})
target_compile_definitions(SDL_mixer PUBLIC "${ENABLE_DEFS}")
但是,不幸的是,我仍然无法链接。奇怪的是,在我的项目中,我的来源可以看到 ogg。但 SDL_mixer 不能:
/usr/bin/cmake -E cmake_link_script CMakeFiles/myProject.dir/link.txt --verbose=1
/bin/c++ -rdynamic MY_SOURCES -o ../bin/myProject -Wl,-rpath:/var/dev/qube/build/vendor/SDL2-2.0.16 vendor/SDL2_mixer-2.0.4/libSDL_mixer.a -lrt vendor/SDL2-2.0.16/libSDL2-2.0.so.0.16.0 vendor/libvorbis-1.3.7/libvorbis.a vendor/libogg-1.3.5/libogg.a -lm
/bin/ld: vendor/SDL2_mixer-2.0.4/libSDL_mixer.a(music_ogg.c.o): in function `OGG_Load':
music_ogg.c:(.text+0x11): undefined reference to `ov_clear'
- 我必须
add_subdirectory()
在 SDL_mixer 项目中添加 ogg 和 vorbis 吗? - 不能与这些库进行静态链接吗?
解决方案
但是,不幸的是,我仍然无法链接。奇怪的是,在我的项目中,我的来源可以看到 ogg。但 SDL_mixer 不能:
我可以看到为什么 ogg 可以看到您的源而 SDL_mixer 不能看到的唯一原因是由于您的链接命令中库的顺序。
vendor/libvorbis-1.3.7/libvorbis.a vendor/libogg-1.3.5/libogg.a
在链接 ogg 对象时,vorbis 符号已经包含在符号表中。
尝试这个:
target_link_libraries(SDL_mixer PUBLIC ${OGG_VORBIS_LIBRARY} ${OGG_LIBRARY} ${SDL2_LIBRARY})
推荐阅读
- javascript - 未应用 JQuery .hide 和 .show
- java - Intellij 中的 Google OR-Tools:UnsatisfiedLinkError
- swift - Swift 5.1 - Mac OS - 文件读取在操场上工作,但在应用程序中不工作
- vbscript - 从 UFT 中的命令提示符读取文本
- javascript - 使用 Flask 填充 Selectize.js 下拉列表
- python - 对 Pandas 数据框中的特定列进行排序
- android - 无需控制台即可在客户端访问 firebase/google 分析数据
- angular - 如何在http get request angular 8中将null更改为空值
- groovy - 我可以自动将 Jira 问题与合流页面链接吗
- vue.js - vue 从资产目录上传图片