동일한 CMake 프로젝트 내에서 빌드되지 않은 외부 공유 라이브러리에 실행 파일을 연결하도록 CMake를 얻는 방법은 무엇입니까?
그냥 target_link_libraries(GLBall ${CMAKE_BINARY_DIR}/res/mylib.so)
하면 오류가 발생합니다.
make[2]: *** No rule to make target `res/mylib.so', needed by `GLBall'. Stop.
make[1]: *** [CMakeFiles/GLBall.dir/all] Error 2
make: *** [all] Error 2
(GLBall is the executable)
라이브러리를 바이너리 dir에 복사 한 후 bin/res
.
나는 사용해 보았다 find_library(RESULT mylib.so PATHS ${CMAKE_BINARY_DIR}/res)
어느와 함께 실패합니다 RESULT-NOTFOUND
.
답변
먼저 라이브러리 검색 경로를 설정하십시오.
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/res)
그리고 그냥
TARGET_LINK_LIBRARIES(GLBall mylib)
답변
arrowdodger의 대답은 정확하고 많은 경우 선호됩니다. 나는 그의 대답에 대안을 추가하고 싶습니다.
링크 디렉토리 대신 “가져온”라이브러리 대상을 추가 할 수 있습니다. 다음과 같은 것 :
# Your-external "mylib", add GLOBAL if the imported library is located in directories above the current.
add_library( mylib SHARED IMPORTED )
# You can define two import-locations: one for debug and one for release.
set_target_properties( mylib PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/res/mylib.so )
그런 다음이 라이브러리가 프로젝트에서 빌드 된 것처럼 연결합니다.
TARGET_LINK_LIBRARIES(GLBall mylib)
이러한 접근 방식은 약간의 유연성을 제공합니다. add_library () 명령 및 가져온 라이브러리와 관련된 많은 대상 속성을 살펴보십시오 .
이것이 “업데이트 된 libs 버전”으로 문제를 해결할 수 있을지 모르겠습니다.
답변
나는 당신이 foo 라는 라이브러리에 연결하고 싶다고 가정합니다. 파일 이름은 일반적으로 link foo.dll
또는 libfoo.so
.
1. 도서관 찾기 도서관
을 찾아야합니다. 라이브러리의 경로를 알고 있더라도 이것은 좋은 생각입니다. 라이브러리가 사라지거나 새 이름이 있으면 CMake에서 오류가 발생합니다. 이를 통해 오류를 조기에 발견하고 문제의 원인을 사용자 (자신이 직접)에게 분명히 알릴 수 있습니다.
라이브러리 foo 를 찾고 FOO_LIB
사용중인 경로를 저장 하려면
find_library(FOO_LIB foo)
CMake는 실제 파일 이름이 어떻게되는지 스스로 알아낼 것입니다. 이 같은 일반적인 장소 확인 /usr/lib
, /usr/lib64
및의 경로를 PATH
.
도서관의 위치를 이미 알고 있습니다. CMAKE_PREFIX_PATH
CMake를 호출 할 때에 추가하면 CMake도 전달 된 경로에서 라이브러리를 찾습니다.
힌트 나 경로 접미사를 추가해야하는 경우가 있습니다. 자세한 내용은 설명서를 참조하십시오.
https://cmake.org/cmake/help/latest/command/find_library.html
2. 라이브러리 연결
1.에서 전체 라이브러리 이름이 FOO_LIB
. 이것을 사용하여 라이브러리를 대상에 연결합니다 GLBall
.
target_link_libraries(GLBall PRIVATE "${FOO_LIB}")
당신은 추가해야 PRIVATE
, PUBLIC
또는 INTERFACE
대상, 참조 후 문서 :
https://cmake.org/cmake/help/latest/command/target_link_libraries.html
이러한 가시성 지정자 중 하나를 추가하지 않으면 CMake 버전 및 정책 세트에 따라 PRIVATE
또는 처럼 작동합니다 PUBLIC
.
3. 포함 추가 (이 단계는 필수가 아닐 수 있음)
헤더 파일도 포함하려면 find_path
유사 항목을 사용 find_library
하고 헤더 파일을 검색합니다. 그런 다음이와 디렉토리를 포함 추가 target_include_directories
비슷합니다 target_link_libraries
.
선적 서류 비치:
https://cmake.org/cmake/help/latest/command/find_path.html
및
https://cmake.org/cmake/help/latest/command/target_include_directories.html
외부 소프트웨어에 사용할 수있는 경우 find_library
및 find_path
으로 대체 할 수 있습니다 find_package
.
답변
또 다른 대안은 Appstore로 작업하는 경우 “Entitlements”가 필요하므로 Apple-Framework와 연결해야합니다.
작업에 인 타이틀먼트의 경우 (예 : 게임 센터) 당신은 필요 에 “바이너리를 라이브러리와 연결”-buildstep을 가지고 다음 “GameKit.framework”로 연결합니다. CMake는 “낮은 수준”의 라이브러리를 명령 줄에 “주입”하므로 Xcode는 실제로 그것에 대해 알지 못하므로 Capabilities 화면에서 GameKit을 활성화 하지 않습니다 .
CMake를 사용하고 “Link with Binaries”빌드 단계를 갖는 한 가지 방법은 CMake로 xcodeproj를 생성 한 다음 ‘sed’를 사용하여 ‘검색 및 교체’하고 XCode가 좋아하는 방식으로 GameKit을 추가하는 것입니다.
스크립트는 다음과 같습니다 (Xcode 6.3.1의 경우).
s#\/\* Begin PBXBuildFile section \*\/#\/\* Begin PBXBuildFile section \*\/\
26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks \*\/ = {isa = PBXBuildFile; fileRef = 26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/; };#g
s#\/\* Begin PBXFileReference section \*\/#\/\* Begin PBXFileReference section \*\/\
26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System\/Library\/Frameworks\/GameKit.framework; sourceTree = SDKROOT; };#g
s#\/\* End PBXFileReference section \*\/#\/\* End PBXFileReference section \*\/\
\
\/\* Begin PBXFrameworksBuildPhase section \*\/\
26B12A9F1C10543B00A9A2BA \/\* Frameworks \*\/ = {\
isa = PBXFrameworksBuildPhase;\
buildActionMask = 2147483647;\
files = (\
26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks xxx\*\/,\
);\
runOnlyForDeploymentPostprocessing = 0;\
};\
\/\* End PBXFrameworksBuildPhase section \*\/\
#g
s#\/\* CMake PostBuild Rules \*\/,#\/\* CMake PostBuild Rules \*\/,\
26B12A9F1C10543B00A9A2BA \/\* Frameworks xxx\*\/,#g
s#\/\* Products \*\/,#\/\* Products \*\/,\
26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/,#g
이것을 “gamecenter.sed”에 저장하고 다음과 같이 “적용”합니다 (xcodeproj를 변경합니다!).
sed -i.pbxprojbak -f gamecenter.sed myproject.xcodeproj/project.pbxproj
필요에 맞게 스크립트 명령을 변경해야 할 수도 있습니다.
경고 : 프로젝트 형식이 변경 될 수 있으므로 다른 Xcode 버전으로 중단 될 수 있습니다. (하드 코딩 된) 고유 번호는 실제로 고유하지 않을 수 있으며 일반적으로 다른 사람들의 솔루션이 더 좋습니다. 따라서 Appstore +를 지원할 필요가없는 경우 권한 (및 자동화 된 빌드),이 작업을 수행하지 마십시오.
이것은 CMake 버그입니다. http://cmake.org/Bug/view.php?id=14185 및 http://gitlab.kitware.com/cmake/cmake/issues/14185 참조