CMake - 如何链接到我与项目一起打包的外部库
CMake - How Can I link to an external library that I have packed with my project?
如何链接到我与项目一起打包的外部库?
以下是我的项目的设置方式:
我有一个名为App的文件夹,这就是我的主要.cpp所在的位置。
C:RaphsrcApp
main.cpp
我还有一个名为"ExternalLibrary"的文件夹,这是我捆绑Qt库的地方,我需要在我的项目中使用:
C:RaphsrcExternalLibraryPlatformWindowsQt5.6VS2013_64bit
它包含3个文件夹:
**bin**
moc.exe
rcc.exe
uic.exe
......
bunch of Qt dll files
**include**
bunch of Qt header files
**lib**
bunch of Qt lib files
我需要设置 Cmake 来做三件事:
链接到我动态打包在"外部库"中的Qt库。
每次我在项目中添加Qt类或资源时.exe自动执行moc.exe,uic.exe,rcc。我也不需要任何生成的moc_myClassname.cpp显示在项目中。
我希望所有Qt dll最终都位于可执行文件所在的bin文件夹中,例如:
C:\Raph\build\Raph\Windows\x64\Debug\bin
拉夫.exe + 所有必要的 Qt Dll
(1)您可以通过以下方式找到Qt库:
find_package(Qt5Core [...] 5.6 REQUIRED)
add_executable(someExe file1.cpp)
target_link_libraries(someExe Qt5::Core)
请注意,您应该保留 Qt 的原始目录结构,也包含 Qt cmake 脚本,例如 lib/cmake/Qt5/Qt5Config.cmake
时包含特定目录,则可以(在搜索Qt之前):
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "./your/path")
例如,这可以是您提供的目录。
(2)您可以使用cmake的自动功能。只需添加
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
在 cmake 脚本的开头。CMake 还支持 AUTOUIC
和 AUTORCC
。我还没有尝试过它们,但可能工作相似。
(3) 例如,您可以向项目添加一个自定义目标,用于复制 dll。生成该目标时,将复制所有 dll。您可以从 Qt 查找脚本定义的目标(如 Qt5::Core
)获取的 dll 路径。
get_target_property(LOC_R Qt5::Core LOCATION_RELEASE)
get_target_property(LOC_D Qt5::Core LOCATION_DEBUG)
但是,还应扫描这些目标的依赖项(它们所依赖的其他 dll)。您可以编写一个宏来扫描相应的dll的整个目标列表并将它们添加到列表中,我们称这些RELEASE_DLLS
和DEBUG_DLLS
:
macro(copydlls RELEASE_DLLS DEBUG_DLLS MODULELIST)
foreach(ELEMENT ${${MODULELIST}})
get_target_property(LOC_R ${ELEMENT} LOCATION_RELEASE)
get_target_property(LOC_D ${ELEMENT} LOCATION_DEBUG)
list(APPEND ${RELEASE_DLLS} ${LOC_R})
list(APPEND ${DEBUG_DLLS} ${LOC_D})
get_target_property(DEPENDENCIES_RELEASE ${ELEMENT} IMPORTED_LINK_DEPENDENT_LIBRARIES_RELEASE)
foreach(DEPENDENCY ${DEPENDENCIES_RELEASE})
if(TARGET ${DEPENDENCY})
get_target_property(LOC_R ${DEPENDENCY} LOCATION_RELEASE)
if(${LOC_R} MATCHES ".dll$")
list(APPEND ${RELEASE_DLLS} ${LOC_R})
endif()
endif()
endforeach()
get_target_property(DEPENDENCIES_DEBUG ${ELEMENT} IMPORTED_LINK_DEPENDENT_LIBRARIES_DEBUG)
foreach(DEPENDENCY ${DEPENDENCIES_DEBUG})
if(TARGET ${DEPENDENCY})
get_target_property(LOC_D ${DEPENDENCY} LOCATION_DEBUG)
if(${LOC_D} MATCHES ".dll$")
list(APPEND ${DEBUG_DLLS} ${LOC_D})
endif()
endif()
endforeach()
get_target_property(DEPENDENCIES_RELEASE ${ELEMENT} IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE)
foreach(DEPENDENCY ${DEPENDENCIES_RELEASE})
if(TARGET ${DEPENDENCY})
get_target_property(LOC_R ${DEPENDENCY} LOCATION_RELEASE)
if(${LOC_R} MATCHES ".dll$")
list(APPEND ${RELEASE_DLLS} ${LOC_R})
endif()
endif()
endforeach()
get_target_property(DEPENDENCIES_DEBUG ${ELEMENT} IMPORTED_LINK_INTERFACE_LIBRARIES_DEBUG)
foreach(DEPENDENCY ${DEPENDENCIES_DEBUG})
if(TARGET ${DEPENDENCY})
get_target_property(LOC_D ${DEPENDENCY} LOCATION_DEBUG)
if(${LOC_D} MATCHES ".dll$")
list(APPEND ${DEBUG_DLLS} ${LOC_D})
endif()
endif()
endforeach()
endforeach()
endmacro()
然后,您可以通过使用以下方式调用此宏来获取列表中的所有 Qt dll:
IF(MSVC)
set(QT_MODULES "Qt5::Core" "Qt5::Gui" "Qt5::Widgets")
set(RELEASE_DLLS)
set(DEBUG_DLLS)
copydlls(RELEASE_DLLS DEBUG_DLLS QT_MODULES)
ENDIF(MSVC)
检索到该信息后,可以通过以下方式创建自定义目标。假设您在列表中的所有 dll 路径都RELEASE_DLLS
和 DEBUG_DLLS
以及您的可执行文件名称作为 TARGETS
中的列表。然后你可以做这样的事情:
if(MSVC)
set(COPY_COMMAND_RELEASE "-E copy_if_different ")
set(COPY_COMMAND_DEBUG "-E copy_if_different ")
list(REMOVE_DUPLICATES RELEASE_DLLS)
list(REMOVE_DUPLICATES DEBUG_DLLS)
foreach(DLL ${RELEASE_DLLS})
string(CONCAT COPY_COMMAND_RELEASE "${COPY_COMMAND_RELEASE} "${DLL}" ")
endforeach()
foreach(DLL ${DEBUG_DLLS})
string(CONCAT COPY_COMMAND_DEBUG "${COPY_COMMAND_DEBUG} "${DLL}" ")
endforeach()
string(CONCAT COPY_COMMAND_RELEASE ${COPY_COMMAND_RELEASE} ""${CMAKE_CURRENT_BINARY_DIR}/Release" ")
string(CONCAT COPY_COMMAND_DEBUG ${COPY_COMMAND_DEBUG} ""${CMAKE_CURRENT_BINARY_DIR}/Debug" ")
add_custom_target(COPY_DLLS)
foreach(EXECUTABLE ${TARGETS})
add_custom_command(TARGET COPY_DLLS PRE_BUILD COMMAND ${CMAKE_COMMAND} ${COPY_COMMAND_RELEASE} COMMENT "Copying dlls to executable directory...")
add_custom_command(TARGET COPY_DLLS PRE_BUILD COMMAND ${CMAKE_COMMAND} ${COPY_COMMAND_DEBUG} COMMENT "Copying dlls to executable directory...")
endforeach()
endif()
如果您希望每次构建其他目标时都执行此目标,则可以执行以下操作:
foreach(EXECUTABLE ${TARGETS})
add_dependencies(${EXECUTABLE} COPY_DLLS)
endforeach()
不要担心您还必须将platforms
目录从plugins
复制到可执行文件文件夹,例如将其添加到复制 dll 目标:
add_custom_command(TARGET COPY_DLLS PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory ${PATH_QT_ROOT}/plugins/platforms ${CMAKE_CURRENT_BINARY_DIR}/Debug/platforms
COMMAND ${CMAKE_COMMAND} -E copy_directory ${PATH_QT_ROOT}/plugins/platforms ${CMAKE_CURRENT_BINARY_DIR}/Release/platforms
COMMENT "Copying Qt platforms to executable directory...")
- 将 OpenCV 与 CMAKE 中的项目一起构建为第三方库的正确方法
- 您是否必须随项目一起交付原型文件?
- Catch2 单元测试未与 CMake 项目一起运行
- 如何将"new"公共项目对话框与 wxwidget 一起使用?
- CMake 项目结构:如何正确地将库合并在一起并将它们包含在多个可执行文件中
- 如何将 Clang 静态分析器与 Cortex-M 项目一起使用?
- 将两个数组组合在一起,形成每个项目的一对
- QT项目在配置文件上崩溃,与发布和调试器一起运行
- 如何将cacert.pem与vs2015 curl项目一起包含,因此无需指定Cainfo curl选项
- 如何连接两个文件夹/项目的生成文件,这两个文件夹/项目必须一起运行且独立运行
- 在代码块中一起编译两个项目
- "namespaced" CMake 中包含路径,并且C++项目在将项目集成在一起时是否有好处?
- 使用Java和C 一起使用Android项目
- Visual Studio,将项目链接在一起并进行测试
- CMake - 如何链接到我与项目一起打包的外部库
- 无论如何,我可以在visualstudio2005上与visualstudio2015一起运行一个已经编码的项目吗
- 与Cygwin一起编译一个C++项目
- 如何将 Google 测试与通过自动工具构建的项目一起使用
- 将项目属性与qt中的事件一起传递到主窗口
- 我如何让zxing与我的iPhone项目一起工作