2017-12-02 35 views
0

다른 CMake 프로젝트가이 라이브러리를 쉽게 포함 할 수 있도록 합리적인 라이브러리 구조와 CMake 파일을 만들려고합니다. 비슷한 질문을 많이 발견했지만 그 중 아무 문제가 내 정확한 문제를 해결하지 못하는 것 같습니다.CMake로 C++ 라이브러리 만들기

/*MyLibrary/ 
├── CMakeLists.txt (including lib subdirectories) 
├── external/ 
│ └── googletest/ 
├── lib/ 
│ ├── common/ 
│ │ ├── CMakeList.txt (creates static lib common) 
│ │ ├── include/common/*.h 
│ │ └── src/*.cpp 
│ ├── cipher/ 
│ │ ├── CMakeList.txt (creates static lib cipher) 
│ │ ├── include/cipher/*.h 
│ │ └── src/*.cpp 
└── test/ 
    ├── main.cpp (code for executing google test) 
    ├── CMakeLists.txt (creates unittest executable) 
    ├── common/*Test.cpp 
    └── cipher/*Test.cpp 
*/ 

가 지금은 비슷한 디렉토리 구조의 프로젝트를 만들려하지만 중 하나와 동일한 이름을 가진 해당 프로젝트에 정적 라이브러리를 생성 할 때 문제가 발생합니다
내 현재의 구조는 다음과 같다 MyLibrary (예 : common)의 정적 라이브러리
프로젝트 CMakeLists에서 add_subdirectory(external/MyLibrary)을 사용하여 프로젝트에 라이브러리를 포함시킬 생각 이었지만 정적 라이브러리의 이름이 콜라이드 (colide)되기 때문에 실패합니다.
라이브러리 이름을 변경하여이 문제를 해결할 때도 (실제로 우아한 솔루션이라고 생각하지는 않습니다) 라이브러리와 프로젝트가 모두 googletest에 의존하기 때문에 googletest 충돌로 끝납니다.

쉽게 해결할 수있는 방법이 있습니까? 내가 libMyLibrary.a라고 모든 하위 라이브러리에서 하나의 정적 라이브러리를 생성하고 해당 라이브러리 (preffered 옵션을 포함 할 것 MyLibrary에서

  • 을,하지만 난 어떻게 달성하는 단서가없는 : 나는 2 posibilities의 생각 그것은
  • ) CMake에서 라이브러리의 사용자를 강제로 설치하고 내가 갈 것 프로젝트 서브 모듈 (마지막 옵션으로 라이브러리)

를 해결하기 위해 다른 합리적인 방법이 있나요 포함되지 않습니다 내 라이브러리는 대부분의 CMake 프로젝트와 호환 될 수 있습니까? 그렇지 않다면 언급 된 옵션 중 적어도 하나를 어떻게 얻을 수 있습니까? 즉

:
라이브러리가 다른 CMake 프로젝트에 포함하기 쉬운, 그래서 나는 도서관에 대한 CMake 파일을 만들 수 있습니까?
googletest와 같은 중복 의존성을 어떻게 처리 할 수 ​​있습니까?

+0

단일 정적 라이브러리 옵션의 경우 다음과 같이 작동합니다. https://cmake.org/Wiki/CMake/Tutorials/Object_Library 가장 좋은 옵션이 아닌 것은 확실하지만 완료했습니다. 하지만 왜 googletest에 의존하는 라이브러리 두 개가 문제가되어야하는지 잘 모르겠습니다. – zzxyz

+0

몇 차례 질문을 읽었지만 여전히 문제가 무엇인지 이해하지 못했습니다. 명확히하십시오. – RCYR

+0

@zzxyz, 감사합니다. – ProXicT

답변

1

라이브러리가 다른 CMake 프로젝트에 쉽게 포함될 수 있도록 라이브러리 용 CMake 파일을 어떻게 만들 수 있습니까?

그러한 목적을위한 보편적 인 접근법은 없습니다.

프로젝트를 add_subdirectory()으로 다른 프로젝트에 포함 시키면 프로젝트의 내부를 다른 프로젝트로 "열어"놓습니다. 라이브러리의 대상을 링크 할 준비가되어있는 이점을 제외하고이 접근법은 단점도 가지고 있습니다. 타겟의 충돌, 캐싱 된 변수 충돌은 다른 문제와 함께 두통이 될 것입니다.

프로젝트를 add_subdirectory으로 다른 프로젝트에 포함 시키려면 대상에 "일반"이름을 사용하지 마십시오. 예 : common 대신 <my_project_name>_common을 사용하십시오.

이름을 바꿀 수없는 대상 (예 : gtest)입니다.프로젝트가 작동하려면 그 대상이 정말 필요하지 않은 경우이를 해제에 대한 옵션을 만들 :

option(<my_project_name>_TESTING "Enable testing" ON) 
if(<my_project_name>_TESTING) 
    add_subdirectory(external/googletest) 
endif() 

이 목표의 이름 충돌에 대한 비슷한 질문에도 my answer를 참조하십시오.

+0

답변 주셔서 감사합니다.하지만 내 질문에는 답이 없습니다. 'add_subdirectory()'를 사용하여 라이브러리를 포함하는 것이 좋지 않은 경우 어떻게하면 더 좋은 방법일까요? 'libmyawesomelibrary.a'라고하는 단일 정적 라이브러리를 만들어 내 프로젝트에만 링크하는 것이 좋은 생각입니까? 그렇다면 어떻게 프로젝트를 컴파일 할 수 있도록 라이브러리 헤더를 공유 할 수 있습니까? – ProXicT

+0

또 다시, 다른 용도로 프로젝트를 전달하는 가장 좋은 방법은 없습니다. 더 "근본적인"것은 프로젝트를 설치하고'find_package()'호출을 통해 그것을 사용하는 것입니다. 이 접근법은 [CMake 문서] (https://cmake.org/cmake/help/v3.9/manual/cmake-packages.7.html)에 설명되어 있습니다. 그러나 이것은 당신의 프로젝트를 위해 "config"스크립트를 작성해야합니다. 'add_subdirectory'를 이용한 접근법은 구현하고 사용하는 것이 더 간단합니다. Googletest는 테스트를 위해이 방법을 권장합니다. 당신은이 접근 방식을 선택하고 특정 문제에 직면했습니다. 내 대답은 그 문제들로 무엇을해야 하는지를 설명합니다. – Tsyvarev

+0

조금 다른 답변을 기대했지만, 실제로 내 질문에 답한 것은 맞습니다. 다음에 나는 실제로 내가 무엇을 요구하는지에 더주의를 기울일 것이다. – ProXicT