[cmake] 외부 라이브러리에 대한 CMake 링크

동일한 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_PATHCMake를 호출 할 때에 추가하면 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_libraryfind_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=14185http://gitlab.kitware.com/cmake/cmake/issues/14185 참조


답변