【问题标题】:splitting a project into a library and a application将项目拆分为库和应用程序
【发布时间】:2011-11-21 10:37:26
【问题描述】:

我正在为我的项目使用 cmake。不,我想将一些部分拆分为一个库并将其用于 2 个不同的应用程序。

现在我不知道如何在 cmake 中执行此子项目。我的第一次尝试是使用 add_subdirectory 命令:

cmake_minimum_required(VERSION 2.8)

add_subdirectory(MSI)

message("Building MsiQtWizard with: ${MSI_INCLUDE_DIR}")
add_subdirectory(MsiQtWizard)

所以 MSI 将是我的图书馆。 MSI 文件夹内是另一个 cmakelists,它基本上是用于构建库的独立列表。我想我可以让 MsiQtWizard 项目也成为一个独立的 cmakelists,所以理论上我可以构建 MSI 并使用该库来构建 MsiQtWizard(和其他项目)。

根目录中的 cmakelists 只是一步构建库和 GUI 的助手。

问题是,为了构建 MsiQtWizard,我需要 msi 的包含路径和静态库二进制文件。我试图在 MIS/CMakelists.txt 的末尾做类似的事情:

### Set variables, other scripts may use ###
SET(MSI_INCLUDE_DIR include)
MESSAGE("Include directory is: ${MSI_INCLUDE_DIR}")

在 MsiQtWizard/CMakelists 中:

##### external libraries #####

#MSI
find_path(MSI_INCLUDE_DIR REQUIRED msi/Image.hpp
            PATH_SUFFIXES MSI/include include)

我的意图是,如果先前未设置该变量,则 MsiQtWizard 将搜索 msi(以便您可以将此 cmakelists 用作独立的)。在构建 MSI 时,我想保存包含路径(以及后来的二进制位置)并将其传递给 MsiQtWizard - 但是一旦我回到我的根 cmakelists,该值就消失了。

这就是我所尝试的。我现在的问题是:我如何正确地将我的项目拆分为一个库和一个(后来的多个)应用程序,我能否以一种我也可以独立构建它们的方式来做到这一点?

或者,更具体地说:如何将值从节点 CMakelist 传递到根 CMakeList(就像我尝试使用 MSI_INCLUDE_DIR 一样)?

【问题讨论】:

    标签: c++ cmake


    【解决方案1】:

    如果您要构建一个库 - 最好将其与应用程序构建完全分开。否则,您将使用 cmake 将您的库与您的应用程序耦合,在我看来,这违背了构建库的目的。

    在构建你的库时,你会想要类似的东西

    project (MSILibrary)
    ADD_LIBRARY(MSILibrary  src/MSI1.cpp src/MSI2.cpp)
    install (TARGETS MSILibrary DESTINATION lib)
    

    src 包含您的库代码。然后你可以make 然后sudo make install 你的库到你的标准库位置(例如/usr/lib)。

    然后您可以在任何后续项目中使用您的库。将它们放在一个新目录中并为它们创建一个新的CMakeLists.txt

    你会想要类似的东西,

    #include find modules
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
    
    project (MSI-project-1)
    
    find_package(MSILibrary REQUIRED)
    IF(MSILibrary_FOUND)
      include_directories(${MSILibrary_INCLUDE_DIRS} 
    ENDIF(MSILibrary_FOUND )
    
    
    target_link_libraries (MSI-project-1 ${MSILibrary_LIBRARIES})
    install (TARGETS MSI-project-1 DESTINATION bin)
    

    现在您需要做的就是帮助cmake 找到您的图书馆。 您可以为此包含一个模块。在文件./cmake/Modules/FindMSILibrary.cmake 中输入如下内容:

    # - Try to find MSILibrary library
    # Once done, this will define
    #
    #  MSILibrary_FOUND - system has MSILibrary
    #  MSILibrary_INCLUDE_DIRS - the MSILibrary include directories
    #  MSILibrary_LIBRARIES - link these to use MSILibrary
    
    ## Google this script (I think its fairly standard, but was not bundled with my CMAKE)   - it helps find the macros.
    include(LibFindMacros)
    
    # Dependencies
    libfind_package(MSILibrary)
    
    # Use pkg-config to get hints about paths
    libfind_pkg_check_modules(MSILibrary_PKGCONF MSILibrary)
    
    # Include dir
    find_path(MSILibrary_INCLUDE_DIR
      NAMES MSI.hpp
      PATHS ${MSI_Library_PKGCONF_INCLUDE_DIRS} 
    )
    
    # Finally the library itself
    find_library(MSILibrary_LIBRARY
      NAMES MSILibrary 
      PATHS ${MSILibrary_PKGCONF_LIBRARY_DIRS} 
    )
    
    # Set the include dir variables and the libraries and let libfind_process do the rest.
    # NOTE: Singular variables for this library, plural for libraries this this lib depends on.
    set(MSILibrary_PROCESS_INCLUDES MSILibrary_INCLUDE_DIR MSILibrary_INCLUDE_DIRS)
    set(MSILibrary_PROCESS_LIBS MSILibrary_LIBRARY MSILibrary_LIBRARIES)
    libfind_process(MSILibrary)
    

    应该是这样的。

    编辑:

    如果你真的想用你的库打包你的应用程序(也许是一些示例应用程序),那么你可以这样做:

    在您的根 CMakeLists.txt 中

    cmake_minimum_required (VERSION 2.6)
    project (MSIProject)
    
    # The version number.
    set (MSIProject_VERSION_MAJOR 0)
    set (MSIProject_VERSION_MINOR 1)
    set (MSIProject_PATCH_LEVEL 3 )
    
    # project options
    OPTION( BUILD_SHARED_LIBS "Set to OFF to build static libraries" ON )
    OPTION( BUILD_EXAMPLES "Set to OFF to skip building the examples" ON )
    
    # Put the libaries and binaries that get built into directories at the
    # top of the build tree rather than in hard-to-find leaf
    # directories.
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
    
    
    ##########################################################################
    #  Build the library 
    ##########################################################################
    
    add_subdirectory(MSI-src)
    
    ##################
    #  Build your example Apps if requested
    ############
    
    
    IF( BUILD_EXAMPLES )
      add_subdirectory(example/MSI-project-1)
      add_subdirectory(example/MSI-project-2)
    ENDIF( BUILD_EXAMPLES )
    

    您的库MSI-src/CMakeFiles.txt 将与以前一样,您的example/MSI-project-1/CMakeLists.txt 将类似于

    ## Make the InferData example project
    project (MSI-project-1)
    
    #include MSI library
    include_directories ("${MSILibrary_SOURCE_DIR}/include")
    #include the includes of this project
    include_directories ("${MSI-project-1_SOURCE_DIR}/../include")
    
    #build
    add_executable(MSI-project-1  src/P1.cpp)
    target_link_libraries (MSI-project-1 MSILibrary) #link
    
    install (TARGETS MSI-project-1 DESTINATION bin)
    

    【讨论】:

    • 感谢您的示例。我同意图书馆应该是独立的。但是,由于这是一个非常具体的库,我希望有可能一步构建所有内容,或者换句话说:只有一个解决方案文件(我主要使用 VC 和 Win7)。
    • 我还是不明白。在 MSI_project 我需要 MSI 的包含目录和库文件的路径。您接缝使用 MSILibrary_SOURCE_DIR 但从未定义过并且是空的,因为它接缝。我认为 MSILibrary CMakeLists 最清楚在哪里可以找到它的东西,但我找不到将这些信息传递到我的根 CMakefile 并从那里传递到其他子项目的方法。
    • 好吧,那么相对路径呢?即使我可以在 MSIlibrary 中设置路径,它也是相对的,然后在 MSIproject 中是错误的。我认为我正在尝试做的事情不应该如此罕见,所以我确信 cmake 为它提供了一种干净的方法,没有任何肮脏的技巧 - 但我就是找不到它(甚至可能没有描述,什么我实际上正在寻找)。
    • 我相信MSILibrary_SOURCE_DIR 是在您在库的CMakeFiles.txt 中写入project (MSILibrary) 时设置的。然后在构建项目时链接该项目:target_link_libraries (MSI-project-1 MSILibrary)。我使用相对路径(在项目树中)来查找系统上尚未安装的库包含文件:`include_directories ("${MSILibrary_SOURCE_DIR}/include")`。
    • 为了构建库和两个应用程序,我使用了四个 CMakeLists.txt 文件。一个定义project (MSIProject) 的总体文件。然后调用定义库项目project (MSILibrary) 的库CMakeLists.txt。 CMakeLists.txt 然后依次调用两个应用程序 CMakeLists.txt,每个应用程序定义各自的项目:project (MSI-project-1)project (MSI-project-2)
    猜你喜欢
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    相关资源
    最近更新 更多