어쨌든 CMAKE_MODULE_PATH를 지정 해야하는 경우 find_package ()는 어떻게 사용됩니까?
CMake를 사용하여 크로스 플랫폼 빌드 시스템을 사용하려고합니다. 이제 소프트웨어에는 몇 가지 종속성이 있습니다. 직접 컴파일하여 시스템에 설치했습니다.
설치된 예제 파일들 :
-- Installing: /usr/local/share/SomeLib/SomeDir/somefile
-- Installing: /usr/local/share/SomeLib/SomeDir/someotherfile
-- Installing: /usr/local/lib/SomeLib/somesharedlibrary
-- Installing: /usr/local/lib/SomeLib/cmake/FindSomeLib.cmake
-- Installing: /usr/local/lib/SomeLib/cmake/HelperFile.cmake
이제 CMake는 파일 find_package()을 열고 Find*.cmake시스템의 라이브러리를 검색하고 SomeLib_FOUND등의 변수를 정의합니다 .
내 CMakeLists.txt에는 다음과 같은 내용이 포함되어 있습니다.
set(CMAKE_MODULE_PATH "/usr/local/lib/SomeLib/cmake/;${CMAKE_MODULE_PATH}")
find_package(SomeLib REQUIRED)
애프터 CMake 검색 첫 번째 명령을 정의 Find*.cmake하고 내가의 디렉토리에 추가 SomeLib어디에 FindSomeLib.cmake찾을 수 있습니다, 그래서 find_package()예상대로 작동합니다.
그러나 이것이 find_package()존재 하는 이유 중 하나는 비 플랫폼 플랫폼 하드 코딩 된 경로에서 벗어나기 때문에 이상합니다.
이것은 보통 어떻게 이루어 집니까? cmake/디렉토리를 SomeLib프로젝트에 복사 하고 CMAKE_MODULE_PATH상대적으로 설정해야 합니까?
명령 find_package에는 Module모드와 Config모드의 두 가지 모드가 있습니다. Module실제로 Config모드 가 필요할 때 모드 를 사용하려고 합니다.
모듈 모드
Find<package>.cmake프로젝트 내에있는 파일 . 이 같은:
CMakeLists.txt
cmake/FindFoo.cmake
cmake/FindBoo.cmake
CMakeLists.txt 함유량:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
find_package(Foo REQUIRED) # FOO_INCLUDE_DIR, FOO_LIBRARIES
find_package(Boo REQUIRED) # BOO_INCLUDE_DIR, BOO_LIBRARIES
include_directories("${FOO_INCLUDE_DIR}")
include_directories("${BOO_INCLUDE_DIR}")
add_executable(Bar Bar.hpp Bar.cpp)
target_link_libraries(Bar ${FOO_LIBRARIES} ${BOO_LIBRARIES})
참고 CMAKE_MODULE_PATH높은 우선 순위가 있고 표준 다시 작성해야 할 때 유용 할 수있다 Find<package>.cmake파일.
구성 모드 (설치)
<package>Config.cmake파일은 외부에 있으며 install다른 프로젝트의 명령에 의해 생성됩니다 ( Foo예 :).
foo 도서관:
> cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(Foo)
add_library(foo Foo.hpp Foo.cpp)
install(FILES Foo.hpp DESTINATION include)
install(TARGETS foo DESTINATION lib)
install(FILES FooConfig.cmake DESTINATION lib/cmake/Foo)
구성 파일의 단순화 된 버전 :
> cat FooConfig.cmake
add_library(foo STATIC IMPORTED)
find_library(FOO_LIBRARY_PATH foo HINTS "${CMAKE_CURRENT_LIST_DIR}/../../")
set_target_properties(foo PROPERTIES IMPORTED_LOCATION "${FOO_LIBRARY_PATH}")
기본적으로 프로젝트는 CMAKE_INSTALL_PREFIX디렉토리에 설치됩니다 .
> cmake -H. -B_builds
> cmake --build _builds --target install
-- Install configuration: ""
-- Installing: /usr/local/include/Foo.hpp
-- Installing: /usr/local/lib/libfoo.a
-- Installing: /usr/local/lib/cmake/Foo/FooConfig.cmake
구성 모드 (사용)
Use find_package(... CONFIG) to include FooConfig.cmake with imported target foo:
> cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(Boo)
# import library target `foo`
find_package(Foo CONFIG REQUIRED)
add_executable(boo Boo.cpp Boo.hpp)
target_link_libraries(boo foo)
> cmake -H. -B_builds -DCMAKE_VERBOSE_MAKEFILE=ON
> cmake --build _builds
Linking CXX executable Boo
/usr/bin/c++ ... -o Boo /usr/local/lib/libfoo.a
Note that imported target is highly configurable. See my answer.
Update
If you are running cmake to generate SomeLib yourself (say as part of a superbuild), consider using the User Package Registry. This requires no hard-coded paths and is cross-platform. On Windows (including mingw64) it works via the registry. If you examine how the list of installation prefixes is constructed by the CONFIG mode of the find_packages() command, you'll see that the User Package Registry is one of elements.
Brief how-to
Associate the targets of SomeLib that you need outside of that external project by adding them to an export set in the CMakeLists.txt files where they are created:
add_library(thingInSomeLib ...)
install(TARGETS thingInSomeLib Export SomeLib-export DESTINATION lib)
Create a XXXConfig.cmake file for SomeLib in its ${CMAKE_CURRENT_BUILD_DIR} and store this location in the User Package Registry by adding two calls to export() to the CMakeLists.txt associated with SomeLib:
export(EXPORT SomeLib-export NAMESPACE SomeLib:: FILE SomeLibConfig.cmake) # Create SomeLibConfig.cmake
export(PACKAGE SomeLib) # Store location of SomeLibConfig.cmake
Issue your find_package(SomeLib REQUIRED) commmand in the CMakeLists.txt file of the project that depends on SomeLib without the "non-cross-platform hard coded paths" tinkering with the CMAKE_MODULE_PATH.
When it might be the right approach
This approach is probably best suited for situations where you'll never use your software downstream of the build directory (e.g., you're cross-compiling and never install anything on your machine, or you're building the software just to run tests in the build directory), since it creates a link to a .cmake file in your "build" output, which may be temporary.
But if you're never actually installing SomeLib in your workflow, calling EXPORT(PACKAGE <name>) allows you to avoid the hard-coded path. And, of course, if you are installing SomeLib, you probably know your platform, CMAKE_MODULE_PATH, etc, so @user2288008's excellent answer will have you covered.
You don't need to specify the module path per se. CMake ships with its own set of built-in find_package scripts, and their location is in the default CMAKE_MODULE_PATH.
The more normal use case for dependent projects that have been CMakeified would be to use CMake's external_project command and then include the Use[Project].cmake file from the subproject. If you just need the Find[Project].cmake script, copy it out of the subproject and into your own project's source code, and then you won't need to augment the CMAKE_MODULE_PATH in order to find the subproject at the system level.
How is this usually done? Should I copy the
cmake/directory of SomeLib into my project and set the CMAKE_MODULE_PATH relatively?
If you don't trust CMake to have that module, then - yes, do that - sort of: Copy the find_SomeLib.cmake and its dependencies into your cmake/ directory. That's what I do as a fallback. It's an ugly solution though.
Note that the FindFoo.cmake modules are each a sort of a bridge between platform-dependence and platform-independence - they look in various platform-specific places to obtain paths in variables whose names is platform-independent.
'Programming' 카테고리의 다른 글
| 선언이 아닌 경우 배열 초기화 구문 (0) | 2020.06.22 |
|---|---|
| 브라우저 간 테스트 : 한 대의 컴퓨터에있는 모든 주요 브라우저 (0) | 2020.06.22 |
| 자바 스크립트 변수 이름에서 {중괄호}는 무엇을 의미합니까? (0) | 2020.06.22 |
| 기본 양식 HTTP 메소드는 무엇입니까? (0) | 2020.06.22 |
| 잘 설계된 Android 애플리케이션의 오픈 소스 예? (0) | 2020.06.22 |