将项目拆分为库和应用程序

Jon*_*anK 2 c++ cmake

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

现在我不知道如何在cmake中做这个子项目.我的第一次尝试是使用add_subdirectory命令:

cmake_minimum_required(VERSION 2.8)

add_subdirectory(MSI)

message("Building MsiQtWizard with: ${MSI_INCLUDE_DIR}")
add_subdirectory(MsiQtWizard)
Run Code Online (Sandbox Code Playgroud)

所以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}")
Run Code Online (Sandbox Code Playgroud)

并在MsiQtWizard/CMakelists中:

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

#MSI
find_path(MSI_INCLUDE_DIR REQUIRED msi/Image.hpp
            PATH_SUFFIXES MSI/include include)
Run Code Online (Sandbox Code Playgroud)

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

那就是我尝试过的.我的问题现在是:我如何正确地将我的项目拆分成一个库和一个(后来的多个)应用程序,我能以一种我可以独立构建它的方式来实现吗?

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

Tom*_*Tom 7

如果您构建一个库 - 最好将它与应用程序构建完全分开.否则,您将您的库与您的应用程序耦合cmake,在我看来,这会破坏构建库的目的.

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

project (MSILibrary)
ADD_LIBRARY(MSILibrary  src/MSI1.cpp src/MSI2.cpp)
install (TARGETS MSILibrary DESTINATION lib)
Run Code Online (Sandbox Code Playgroud)

其中src包含您的库代码.然后,您可以makesudo 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)
Run Code Online (Sandbox Code Playgroud)

现在你需要做的就是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)
Run Code Online (Sandbox Code Playgroud)

那应该是它.

编辑:

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

在您的根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 )
Run Code Online (Sandbox Code Playgroud)

您的图书馆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)
Run Code Online (Sandbox Code Playgroud)