자체 작성 Makefile을 사용하여 컴파일하는 데 사용한 라이브러리를 작성했지만 이제는 cmake로 전환하려고합니다. 나무는 다음과 같습니다 (관련없는 파일을 모두 제거했습니다).
.
├── include
│ ├── animation.h
│ ├── buffers.h
│ ├── ...
│ ├── vertex.h
│ └── world.h
└── src
├── animation.cpp
├── buffers.cpp
├── ...
├── vertex.cpp
└── world.cpp
그래서 내가하려는 것은 소스를 공유 라이브러리로 컴파일 한 다음 헤더 파일로 설치하는 것입니다.
내가 찾은 대부분의 예제는 일부 공유 라이브러리로 컴파일 실행 파일을 찾지 만 평범한 공유 라이브러리는 결코 없습니다. 누군가가 cmake를 사용하는 매우 간단한 라이브러리를 말해 줄 수 있다면 도움이 될 것이므로 이것을 예제로 사용할 수 있습니다.
답변
항상 최소 필수 버전을 지정하십시오. cmake
cmake_minimum_required(VERSION 3.9)
프로젝트를 선언해야합니다. cmake
이 필수이며 편리 변수를 정의 것이라고 PROJECT_NAME
, PROJECT_VERSION
그리고 PROJECT_DESCRIPTION
(3.9 cmake이 후자의 변수 필요로) :
project(mylib VERSION 1.0.1 DESCRIPTION "mylib description")
새 라이브러리 대상을 선언하십시오. 의 사용을 피하십시오 file(GLOB ...)
. 이 기능은 컴파일 과정에 익숙하지 않습니다. 게으른 경우 다음의 복사-붙여 넣기 출력 ls -1 sources/*.cpp
:
add_library(mylib SHARED
sources/animation.cpp
sources/buffers.cpp
[...]
)
VERSION
속성 설정 (선택 사항이지만 좋은 습관 임) :
set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION})
SOVERSION
의 주요 수를 설정할 수도 있습니다 VERSION
. 에 libmylib.so.1
대한 심볼릭 링크가됩니다 libmylib.so.1.0.0
.
set_target_properties(mylib PROPERTIES SOVERSION 1)
라이브러리의 공개 API를 선언하십시오. 이 API는 타사 응용 프로그램 용으로 설치됩니다. include/
디렉토리를 배치하는 것과 같이 프로젝트 트리에서 격리하는 것이 좋습니다 . 개인 헤더는 설치하지 않아야하며 소스 파일과 함께 배치하는 것이 좋습니다.
set_target_properties(mylib PROPERTIES PUBLIC_HEADER include/mylib.h)
하위 디렉토리로 작업하는 경우와 같은 상대 경로를 포함하는 것이 매우 편리하지 않습니다 "../include/mylib.h"
. 따라서 포함 된 디렉토리에서 최상위 디렉토리를 전달하십시오.
target_include_directories(mylib PRIVATE .)
또는
target_include_directories(mylib PRIVATE include)
target_include_directories(mylib PRIVATE src)
라이브러리의 설치 규칙을 작성하십시오. CMAKE_INSTALL_*DIR
다음에 정의 된 변수를 사용하는 것이 좋습니다 GNUInstallDirs
.
include(GNUInstallDirs)
설치할 파일을 선언하십시오.
install(TARGETS mylib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
pkg-config
파일을 내보낼 수도 있습니다 . 이 파일을 사용하면 타사 응용 프로그램에서 라이브러리를 쉽게 가져올 수 있습니다.
- Makefile로, 참조
pkg-config
- Autotools로, 참조
PKG_CHECK_MODULES
- cmake와 함께, 참조
pkg_check_modules
이름이 지정된 템플릿 파일을 만듭니다 mylib.pc.in
(자세한 내용은 pc (5) 맨 페이지 참조).
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
Version: @PROJECT_VERSION@
Requires:
Libs: -L${libdir} -lmylib
Cflags: -I${includedir}
에서 매크로 CMakeLists.txt
를 확장하는 규칙을 추가 하십시오 @
( @ONLY
cmake에게 형식의 변수를 확장하지 않도록 요청하십시오 ${VAR}
).
configure_file(mylib.pc.in mylib.pc @ONLY)
마지막으로 생성 된 파일을 설치하십시오.
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
cmake EXPORT
기능을 사용할 수도 있습니다 . 그러나이 기능은 호환되며 cmake
사용하기가 어렵습니다.
마지막으로 전체 CMakeLists.txt
가 다음과 같아야합니다.
cmake_minimum_required(VERSION 3.9)
project(mylib VERSION 1.0.1 DESCRIPTION "mylib description")
include(GNUInstallDirs)
add_library(mylib SHARED src/mylib.c)
set_target_properties(mylib PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 1
PUBLIC_HEADER api/mylib.h)
configure_file(mylib.pc.in mylib.pc @ONLY)
target_include_directories(mylib PRIVATE .)
install(TARGETS mylib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
답변
이 최소 CMakeLists.txt
파일은 간단한 공유 라이브러리를 컴파일합니다.
cmake_minimum_required(VERSION 2.8)
project (test)
set(CMAKE_BUILD_TYPE Release)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(test SHARED src/test.cpp)
그러나 CMake를 사용하여 다른 대상으로 파일을 복사 한 경험이 없습니다. COPY / INSTALL 서명이있는 파일 명령이 유용 할 것 같습니다.
답변
이 작업을 직접 수행하는 방법을 배우려고하는데 다음과 같이 라이브러리를 설치할 수 있습니다.
cmake_minimum_required(VERSION 2.4.0)
project(mycustomlib)
# Find source files
file(GLOB SOURCES src/*.cpp)
# Include header files
include_directories(include)
# Create shared library
add_library(${PROJECT_NAME} SHARED ${SOURCES})
# Install library
install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME})
# Install library headers
file(GLOB HEADERS include/*.h)
install(FILES ${HEADERS} DESTINATION include/${PROJECT_NAME})
답변
첫째, 이것은 내가 사용하는 디렉토리 레이아웃입니다.
.
├── include
│ ├── class1.hpp
│ ├── ...
│ └── class2.hpp
└── src
├── class1.cpp
├── ...
└── class2.cpp
며칠 후에 이것을 살펴본 후에 이것은 현대 CMake 덕분에 이것을 좋아하는 가장 좋은 방법입니다.
cmake_minimum_required(VERSION 3.5)
project(mylib VERSION 1.0.0 LANGUAGES CXX)
set(DEFAULT_BUILD_TYPE "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.")
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
include(GNUInstallDirs)
set(SOURCE_FILES src/class1.cpp src/class2.cpp)
add_library(${PROJECT_NAME} ...)
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE src)
set_target_properties(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 1)
install(TARGETS ${PROJECT_NAME} EXPORT MyLibConfig
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
install(EXPORT MyLibConfig DESTINATION share/MyLib/cmake)
export(TARGETS ${PROJECT_NAME} FILE MyLibConfig.cmake)
CMake를 실행하고 라이브러리를 설치 한 후 Find ***. cmake 파일을 사용할 필요가 없으며 다음과 같이 사용할 수 있습니다.
find_package(MyLib REQUIRED)
#No need to perform include_directories(...)
target_link_libraries(${TARGET} mylib)
그것이 표준 디렉토리에 설치되어 있으면 발견되며 다른 것을 할 필요가 없습니다. 비표준 경로에 설치되어 있으면 CMake에 MyLibConfig.cmake를 찾을 위치를 알려주십시오.
cmake -DMyLib_DIR=/non/standard/install/path ..
나는 이것이 나를 도와 준만큼 모두에게 도움이되기를 바랍니다. 이 작업을 수행하는 오래된 방법은 상당히 번거로 웠습니다.