2012-12-01 2 views
7

C++ - project, 즉 foo은 cmake에서 관리합니다. -lfoo으로 라이브러리에 링크 할 수있는 프로그램을 만들 수 있도록 하나의 라이브러리 libfoo.a (전체 소스 트리에서 생성 된 모든 클래스/메소드/함수 포함)을 하나 만들고자합니다.cmake로 전체 프로젝트에서 하나의 정적 라이브러리를 만듭니다.

이제 장난감을 예로 들어 보겠습니다. 그러면 prolbem이 명확 해집니다. 디렉토리 foo (프로젝트의 루트)은 ab 디렉토리를 포함합니다. , b_sourceslibfoo.a를 구축 한 후 foo_sources 만 방법을 포함하고 a_sources : 나에게 놀람이었다

add_subdirectory(a) 
add_subdirectory(b) 
add_library(foo <foo_sources> 
target_link_libraries(foo A B) 

가 : 루트 디렉토리

# a/CMakeLists.txt 
add_library(A <a_sources>) 
# b/CMakeLists.txt 
add_library(B <b_sources>) 

그리고 하나 CMakeLists.txt을 : 두 CmakeLists.txt이 생성됩니다 제외됩니다. 실행 파일을 만들 때 같은 프로젝트로 실행 파일을 빌드하는 경우에는 괜찮습니다. 실행 파일을 만드는 동안 과 b이 연결되어야하는 cmake "guesses"가 foo에 링크되어 있어야합니다. 그러나 실행 파일이 라이브러리 "foo"을 사용하는 "외부"프로젝트의 경우 -lfoo -la -lb과 연결되어야합니다. 이제는 많은 하위 디렉토리가있는 프로젝트를 상상해보십시오 - 어떻게 처리해야합니까? 그래서 질문은 "어떻게 하나의 라이브러리를 만들고 cmake를 사용하여 전체 프로젝트에서 메소드를 모으는가?"입니다.

인터넷 검색은 상대적으로 최근에 임베디드되었습니다 (2.8.8에 등장) OBJECT library 기회가되었습니다. 그것을 사용하는 좋은 예는 here입니다. 이제 위의 문제는 다음과 같이 해결할 수 있습니다.

# a/CMakeLists.txt 
add_library(A OBJECT <a_sources>) 
# b/CMakeLists.txt 
add_library(B OBJECT <b_sources>) 
# foo/CMakeLists.txt 
add_subdirectory(a) 
add_subdirectory(b) 
add_library(foo <foo_sources> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>) 

문제는 해결되었지만, 불행히도 그렇지는 않습니다.

종속성 체인이 2보다 긴 경우 (예 : fooB에 따라 달라짐) A에 따라 달라 지므로 문제가 여전히 남아 있습니다.

개체 라이브러리에는 개체 파일로 컴파일되는 소스 (및 헤더) 만 포함될 수 있습니다.

개체 라이브러리, 수입 수출, 설치, 또는 링크 할 수 없습니다.

(따옴표 같은 link에서 발췌)

내가 add_library(), add_library(... OBJECT ..)이 성공하지 fooAB을 연결하려고 target_link_library()의 여러 조합을 시도했습니다 (cmake-과정에서 오류가 발생했습니다.)

나는 무언가를 간단하게 잃어 버렸음에 틀림 없습니다. 도와주세요, 고마워요! 프로젝트가 리눅스에서 유지 관리되는 것이 중요한지 잘 모르겠습니다.

답변

3

나는 당신이 "의존한다"라는 말에서 엉망이되고 있다고 생각합니다.foo 라이브러리를 만들고 있는데 두 부분이 AB 인 경우 AB에 종속되는지 여부는 중요하지 않습니다. 라이브러리는 둘 다 포함해야합니다. 표시된 CMake 코드는 foo을 적절히 구축합니다.

0

그래, 나는 @Pete Becker @를 지원합니다. 그러나 그 라이브러리들도 $<TARGET_OBJECTS:A>$<TARGET_OBJECTS:B>은 사실 라이브러리가 아니라 오히려 cmake 내부 객체 목록이라고합니다. 객체 모듈의 컴파일 간에는 자동 생성 소스를 제외하고는 아무런 종속성이 없으므로 순서와 병렬로 수행 할 수 있습니다.

당신의 의도가 더 정확하다고 생각하면 하나의 객체 라이브러리 아래에 여러 개의 TARGET_OBJECTS이 모여있을 것입니다. add_library(B OBJECT b.cpp $<TARGET_OBJECTS:A>)을 쓸 수 없다는 것은 정말 나빴습니다. 그러나 당신은 항상 자신에 의해이 구현할 수 있습니다

add_library(A OBJECT a.cpp) 
set(A_OBJECTS $<TARGET_OBJECTS:A>) 

add_library(B OBJECT b.cpp) 
set(B_OBJECTS $<TARGET_OBJECTS:B> ${A_OBJECTS}) 

add_library(foo ${B_OBJECTS}) 

즉 그냥 당신이 라이브러리, 실행 또는 그 _OBJECTS 맛이 다른 개체 라이브러리의 일부로서 그 개체 라이브러리를 포함 할 때마다 _OBJECTS이 그들을 사용하는 특별한 변수를 만들 수 있습니다.

관련 문제