繁体   English   中英

CMake 用于 C++/Qt 项目中的外部库

[英]CMake for external library in C++/Qt project

我正在尝试构建一个小型 C++/Qt 测试程序来读取各种编码的文件,我正在尝试使用 Google 的紧凑编码检测 (CED) 库: https://github.com/google/compact_enc_det有很多类似的问题,但它们似乎都不起作用或反映我的问题。

CED 作为一个独立项目构建得很好,但我正在努力将它作为一个外部库合并到我的项目中。 我习惯了 QMake,在 QtCreator 中工作,但这只适用于 CMake 所以我开始环顾四周,但我有点迷路(QMake 在这方面似乎更简单)。

我设法让我的 C++/Qt 项目在 QtCreator 下与 CMake 一起工作,并且还设法构建和测试 CED(CMake 然后生成一个库:libced.a)。

这是我的小(工作)CMakeLists 文件:

cmake_minimum_required(VERSION 3.1.0)

project(FileTestCMakeCED)

set(CMAKE_AUTOMOC ON)

find_package(Qt5 COMPONENTS Core Widgets REQUIRED)

set(FileTest_src
    ${CMAKE_CURRENT_LIST_DIR}/src/mainwindow.cpp
    ${CMAKE_CURRENT_LIST_DIR}/src/main.cpp
)

add_executable(${PROJECT_NAME} ${FileTest_src})

# Use the Widgets module from Qt 5
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)

我没有粘贴CED的CMakeLists,它有点长,它在GitHub页面上: https://github.com/google/compact_enc_det/blob/master/CMakeLists.txt

我想要么将 CED 用作 static 库(但我尝试了很多方法,但都没有用),要么合并源代码,以便在需要时将它们与我的项目一起编译(我尝试将 CED 作为外部项目链接到我的源代码树,但如果更容易的话,我可以将它移动到同一源代码树中)。

我尝试过的一件有前途的事情是:

include_directories(../compact_enc_det)
add_library(ced STATIC IMPORTED)
set_target_properties(ced PROPERTIES IMPORTED_LOCATION ../compact_enc_det/lib/libced.a)
...
target_link_libraries(${PROJECT_NAME} Qt5::Widgets ced)

但是我得到一个“ no rule to make target.../libced.a ”错误,即使我只想使用预编译库。

我唯一设法开始工作的是从谷歌制作的 CED 项目开始并将我的源代码粘贴到那里,并让 CED 的 CMakeLists 为我的程序生成一个额外的可执行文件,但这与我想要的相反代码和项目结构。 如果我尝试相反的方法(将 CED 包括到我的项目中),我总是会遇到 CED 的源和包含的路径问题。

有人可以启发我解决此类问题的最佳做法吗? 另外,正如我所说,我是 CMake 的新手,因此我们将不胜感激。 如果重要的话,我正在拨打 Debian Stretch。

非常感谢,

一种快速的解决方案是提供libced.a库的完整路径:

target_link_libraries(${PROJECT_NAME} Qt5::Widgets /path/to/libced.a)

这种方法的缺点是您的CMakeLists.txt变得特定于您正在使用的计算机。 如果分发代码,其他人将无法在不更改源代码CMakeLists.txt情况下配置其构建。

通常,外部库使用find_package()位于CMake中。 为了使此功能起作用,您尝试链接的包必须在CMake可以找到它的位置提供<package>Config.cmakeFind<package>.cmake文件。 这些文件已经存在于CMake安装中的许多流行软件包中(例如,在/ usr / lib / cmake下查找)。 但是,如果只是从CMake开始,编写自己的脚本可能不是一个简单的解决方案,因为在这些文件中,您尝试编写一个脚本,该脚本执行许多与系统有关的检查以定位包并设置可以在构建中进一步使用的适当变量处理。 您可以在链接的文档页面上了解更多信息。

另一种解决方案是使用find_library() ,您可以在其中为所需库的位置提供提示或环境变量。 如果找不到该库,则可以打印一条消息或错误,要求用户设置特定的提示变量,您的CMakeLists.txt可用于查找该库。 例如,在您的CMakeLists.txt您可以执行

find_library(CED_LIBRARY ced HINTS ${CED_ROOT})
if( ${CED_LIBRARY} STREQUAL "CED_LIBRARY-NOTFOUND")
    message("Please set CED_LIBRARY variable to location of libced")
endif()

[使用两个小补丁编辑的代码]

上面的代码片段指示CMake查找ced库的文件路径,并将该路径存储在CED_LIBRARY变量中。 如果找不到文件,它将在该变量中存储CED_LIBRARY-NOTFOUND 如果找到该库,则可以使用进行链接

target_link_libraries(${PROJECT_NAME} Qt5::Widgets ${CED_LIBRARY})

find_library()非常聪明,可以自己尝试各种前缀和后缀,因此您无需编写libced 例如,在Windows上,它可能会尝试找到libced.dll ;对于Unix上的共享库,它将搜索libced.so等。

自问题发布以来已经有很长时间了,但我将这个问题留作参考。 我有一篇博客文章逐步描述了您(或其他任何人)正在尝试做的事情。 请在此处查看: https://michae9.wordpress.com/2022/09/01/shared-lib-to-be-used-by-client-programs-with-cmake/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM