【发布时间】:2021-09-13 21:40:21
【问题描述】:
我在 linux 系统上安装的 c++ 包中的库名称冲突时遇到问题。这两个包都使用 cpack 内置到可安装的 apt 包中。安装了两个软件包(A 和 B)。
请注意,虽然我可以控制这些包,因此我可以更改 CMake 等,但它们将被编译成 debian 包并作为系统库安装,而不是安装在 /usr/local/ 下。
每个包都有自己的utils 模块。
每个模块都安装了父项目的命名空间(所以A::utils和B::utils),库.so文件位于项目名称的子文件夹中,而不是直接在/usr/lib中 - 所以/usr/lib/A/libutils.so和/usr/lib/B/libutils.so .
作为安装后脚本,将带有项目名称(A 或 B)的文件添加到包含已安装库的路径(例如 /usr/lib/A)到库路径的 /etc/ld.so.conf.d .
除了utils项目A还有一个库foo,它依赖于A::utils
我有第三个项目C,它有一个依赖于A::foo 的可执行文件,但是(据我所知)不根本没有使用B。
在构建 C 时遇到错误,指出存在未定义的引用。通过进一步调查,我确定当C 构建并且A::foo 必须解析utils 时,它会发现B::utils 而不是A::utils 导致错误。我希望得到一些解释为什么会发生这种情况/如何解决它?我的理解是命名空间(除了将库放在子文件夹中以使文件本身不会冲突)将解决库命名冲突的问题。
以下是其中一个 CMakeLists 的安装部分的示例
set(PROJECT_NAME A)
set(component utils)
add_library(${component} SHARED
src/UtilsExample.cpp
)
add_library(${PROJECT_NAME}::${component} ALIAS ${component})
#... stuff with the libraries and whatnot
install(TARGETS ${component} EXPORT ${component}Targets
COMPONENT ${component}
LIBRARY DESTINATION lib/${PROJECT_NAME}
ARCHIVE DESTINATION lib/${PROJECT_NAME}
RUNTIME DESTINATION bin
)
install(EXPORT ${component}Targets
FILE "${PROJECT_NAME}-${component}Targets.cmake"
NAMESPACE ${PROJECT_NAME}::
DESTINATION lib/cmake/${PROJECT_NAME}
COMPONENT ${component}
)
为确保库名称是唯一的,我是否需要在项目名称之前加上类似的名称?所以图书馆会被命名为A_utils?这似乎会使外部项目的别名变得很奇怪,A::A_utils
【问题讨论】: