разделение проекта на библиотеку и приложение - PullRequest
2 голосов
/ 21 ноября 2011

Я использую 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 в корневом каталоге будет просто помощником для создания библиотеки и графического интерфейса за один шаг.

Проблема в том, что для сборки MsiQtWizard мне нужен путь включения в msi и статические двоичные библиотеки. Я пытался сделать что-то подобное в конце MIS / CMakelists.txt:

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

и в списках MsiQtWizard / CMake:

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

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

Мое намерение состоит в том, что MsiQtWizard будет искать msi, если varaible не был предварительно установлен (чтобы вы могли использовать эти cmakelists как автономные). При создании MSI я хочу сохранить включаемый путь (и более поздние двоичные местоположения) и передать его в MsiQtWizard - но значение исчезает, как только я возвращаюсь в свои корневые cmakelists.

Так вот, что я пытался. Теперь у меня вопрос: как бы я правильно разделил свой проект на библиотеку и (позднее несколько) приложение и мог ли я сделать это так, чтобы я мог также создавать их независимо?

Или, более конкретно: как я могу передать значения из узла CMakelist в корневой CMakeList (как я пытался с MSI_INCLUDE_DIR)?

1 Ответ

6 голосов
/ 21 ноября 2011

Если вы строите библиотеку - лучше полностью отделить ее от сборки приложения. В противном случае вы связываете вашу библиотеку с вашим приложением с 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)

Так и должно быть.

EDIT:

Если вы действительно хотите упаковать свои приложения в свою библиотеку (возможно, некоторые примеры приложений), то вы можете сделать что-то вроде этого:

В вашем корне 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...