CMake 将库链接到一个库中

Posted

技术标签:

【中文标题】CMake 将库链接到一个库中【英文标题】:CMake linking libraries into one single library 【发布时间】:2019-11-15 15:55:57 【问题描述】:

我使用 CMake 将一个框架编译成三个不同的 .lib 文件和一个 .sln 文件。该项目的结构是这样的

UeiDaqFramework
|-CMakeLists.txt
|-build
|    |-Framework_static.sln
|    | - other cmake files and stuff
|-UeiDaqCore
|    |-CMakeLists.txt
|    |-source code for this subproject
|-UeiSimuDriver
|    |-CMakeLists.txt
|    |-source code for this subproject
|-UeiPDNADriver
|    |-CMakeLists.txt
|    |-source code for this subproject
|
|-Output
    |-UeiDaqCore.lib
    |-UeiSimuDriver.lib
    |-UeiPDNADriver.lib

我的测试代码在其包含文件中需要一个 Framework_static.lib 而不是 .sln 文件,我不知道如何使用 cmake 组合三个现有的 .lib 文件。我确实尝试通过将所有源文件构建到一个库中来遵循CMake - combine multiple libraries into one 答案的建议,但我是 CMake 的新手,但它不起作用。这是我项目顶层目录中的 CmakeLists.txt 文件。

cmake_minimum_required(VERSION 3.13.0 FATAL_ERROR)

set(CMAKE_SYSTEM_VERSION  CACHE TYPE INTERNAL FORCE)

project(Framework_static_vc15)

################################################################################
# Set target arch type if empty. Visual studio solution generator provides it.
################################################################################
if(NOT CMAKE_VS_PLATFORM_NAME)
    set(CMAKE_VS_PLATFORM_NAME "x64")
endif()
message("$CMAKE_VS_PLATFORM_NAME architecture in use")

if(NOT ("$CMAKE_VS_PLATFORM_NAME" STREQUAL "Win32"))
    message(FATAL_ERROR "$CMAKE_VS_PLATFORM_NAME arch is not supported!")
endif()

################################################################################
# Global configuration types
################################################################################
set(CMAKE_CONFIGURATION_TYPES
    "Debug"
    "Release"
    CACHE STRING "" FORCE
)

################################################################################
# Global compiler options
################################################################################
if(MSVC)
    # remove default flags provided with CMake for MSVC
    set(CMAKE_CXX_FLAGS "")
    set(CMAKE_CXX_FLAGS_DEBUG "")
    set(CMAKE_CXX_FLAGS_RELEASE "")
endif()

################################################################################
# Global linker options
################################################################################
if(MSVC)
    # remove default flags provided with CMake for MSVC
    set(CMAKE_EXE_LINKER_FLAGS "")
    set(CMAKE_MODULE_LINKER_FLAGS "")
    set(CMAKE_SHARED_LINKER_FLAGS "")
    set(CMAKE_STATIC_LINKER_FLAGS "")
    set(CMAKE_EXE_LINKER_FLAGS_DEBUG "$CMAKE_EXE_LINKER_FLAGS")
    set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "$CMAKE_MODULE_LINKER_FLAGS")
    set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "$CMAKE_SHARED_LINKER_FLAGS")
    set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "$CMAKE_STATIC_LINKER_FLAGS")
    set(CMAKE_EXE_LINKER_FLAGS_RELEASE "$CMAKE_EXE_LINKER_FLAGS")
    set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "$CMAKE_MODULE_LINKER_FLAGS")
    set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "$CMAKE_SHARED_LINKER_FLAGS")
    set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "$CMAKE_STATIC_LINKER_FLAGS")
endif()

################################################################################
# Nuget packages function stub.
################################################################################
function(use_package TARGET PACKAGE VERSION)
    message(WARNING "No implementation of use_package. Create yours.")
endfunction()

################################################################################
# Common utils
################################################################################
include(CMake/Utils.cmake)

################################################################################
# Additional Global Settings(add specific info there)
################################################################################
include(CMake/GlobalSettingsInclude.cmake OPTIONAL)

################################################################################
# Use solution folders feature
################################################################################
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

################################################################################
# Sub-projects
################################################################################
add_subdirectory(Source/UeiDaqCore)
add_subdirectory(Source/UeiPDNADriver)
add_subdirectory(Source/UeiSimuDriver)

这些 CMakeLists.txt 文件由生成器自动生成,该生成器采用 Visual Studio .sln 文件并将其转换为 .txt 树。如果有人感兴趣,这里是转换器的链接。 https://cmakeconverter.readthedocs.io/en/develop/intro.html

我不确定是否只需要重写*** .txt 文件,或者是否需要重写所有 CMakeLists.txt 文件。任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

我假设共享库的构建位于子目录中,因为您的 CMakeLists.txt 不包含任何 add_library 命令。

要获得包含所有源的静态库,您必须

    收集所有来源 添加构建静态库的命令

对于1.将以下内容添加到每个子目录/CMakeLists.txt

set(SOURCES         # This creates a list of sources called SOURCES
    myFileA.cpp     # This adds an item to the list
    myFileB.cpp
    $SOURCES      # This adds all items of existing list SOURCES to the current list
    PARENT_SCOPE    # This makes SOURCES visible in the parent CMakeLists.txt
)

对于2.添加静态库

add_library(myTestLib_static.c STATIC $SOURCES)

【讨论】:

啊。我会试一试

以上是关于CMake 将库链接到一个库中的主要内容,如果未能解决你的问题,请参考以下文章

将库链接到 cmake 项目中的所有目标

如何正确地将库与 cmake 链接?

CMake项目结构:如何正确地将库合并在一起并将它们包含在多个可执行文件中

库中的 CMake 链接目录

如何将库集成到我的库中

NDK 与 cmake 的链接库