2013-05-10 1 views
1

프로젝트의 일부로 빌드되고 링크 된 라이브러리가 있습니다. 나는 시스템 전역 (또는 $ {CMAKE_INSTALL_PREFIX}이 설정되어있는 곳)에 라이브러리를 설치하도록 OPTIONALLY 기능을 제공하고자합니다. 그렇지 않으면 기본적으로 프로젝트의 최종 빌드 제품이 정적으로 라이브러리에 링크되고 전자는 설치되지만 라이브러리 바이너리는 빌드 디렉토리에 남아있게됩니다.CMake : 'make install [all]'에서 사용자 지정 설치 대상 제외

에서 다른 단어 :

$ make 
$ make install 

구축하고, 프로그램을 설치하지만,

$ make install.foo 

같은 단지 뭔가 $ {CMAKE_INSTALL_PREFIX}에 라이브러리를 설치합니다, 필요한 경우 먼저 구축하는 것입니다.

나는 지금까지 이런 일이 (실제 스크립트에서 단순화를, 그래서 오류가있을 수 있습니다) :

INCLUDE_DIRECTORIES("${CMAKE_CURRENT_LIST_DIR}") 
SET (FOO_LIBRARY "foo") 

# Following builds library and makes it available to 
# be linked other targets within project by: 
# TARGET_LINK_LIBRARIES(${progname} ${FOO_LIBRARY}) 
ADD_LIBRARY(${FOO_LIBRARY} 
    foo/foo.cpp # and other sources ... 
    ) 

########################################################### 
# Approach #1 
# ----------- 
# Optionally allow users to install it by invoking: 
# 
#  cmake .. -DINSTALL_FOO="yes" 
# 
# This works, but it means that users will have to run 
# cmake again to switch back and forth between the libary 
# installation and non-library installation. 
# 
OPTION(INSTALL_FOO "Install foo" OFF) 
IF (INSTALL_FOO) 
    INSTALL(TARGETS ${FOO_LIBRARY} DESTINATION lib/foo) 
    SET(FOO_HEADERS foo/foo.h) 
    INSTALL(FILES ${FOO_HEADERS} DESTINATION include/foo) 
    UNSET(INSTALL_FOO CACHE) 
ENDIF() 
########################################################### 

########################################################### 
# Approach #2 
# ----------- 
# Optionally allow users to install it by invoking: 
# 
#  make install.foo 
# 
# Unfortunately, this gets installed by "make install", 
# which I want to avoid 
SET(FOO_INSTALL "install.foo") 
ADD_CUSTOM_TARGET(${FOO_INSTALL} 
    COMMAND ${CMAKE_COMMAND} 
     -D COMPONENT=foo 
     -P cmake_install.cmake) 
ADD_DEPENDENCIES(${FOO_INSTALL} ${FOO_LIBRARY}) 
INSTALL(TARGETS ${FOO_LIBRRARY} 
    DESTINATION lib/foo COMPONENT foo) 
SET(FOO_HEADERS foo/foo.h) 
INSTALL(FILES ${FOO_HEADERS} 
    DESTINATION include/foo COMPONENT foo) 
########################################################### 
으로는 작품의 접근 방식 # 1 종류 볼 수 있지만, 필요한 단계는 설치

도서관은 다음과 같습니다

$ cmake .. -DINSTALL_FOO="yes" 
$ make && make install 

그리고, 다시 "정상"에 갈 구축, 사용자는 "그렇지 않으면 라이브러리는 다음에 설치됩니다은"-DINSTALL_FOO "옵션을 사용하지 않고 cmake 다시 ​​실행하는 것을 기억해야한다 설치하십시오. "

두 번째 방법은 "make install.foo"를 실행할 때 작동하지만 "make install"을 실행하면 라이브러리도 설치됩니다. 후자를 피하고 싶습니다.

아무에게도이를 달성하는 방법에 대한 제안이 있습니까?

답변

3

접근법 # 2가 올바른 길을 걷고 있습니다. install 명령의 OPTIONAL 스위치를 사용하여 FOO 관련 파일을 설치하지 않도록 CMake를 속일 수 있습니다. FOO 라이브러리 대상에 대한

, 명령은 다음과 같은 방법으로 수정에있다 : 당신이 일반 make을 실행할 때 EXCLUDE_FROM_ALLADD_LIBRARY에 추가됩니다

SET (FOO_LIBRARY "foo") 
ADD_LIBRARY(${FOO_LIBRARY} EXCLUDE_FROM_ALL 
    foo/foo.cpp 
    ) 
INSTALL(TARGETS ${FOO_LIBRARY} 
    DESTINATION lib/foo COMPONENT foo OPTIONAL) 

이 건물에서 라이브러리를 방지 할 수 있습니다. 스위치를 추가하여 FOO_LIBRARY을 설치하면됩니다. 옵션의 부 FOO_HEADERS의 설치를 만들기

다음과 같이 변경이 필요합니다

SET(FOO_HEADERS foo/foo.h) 
SET(BINARY_FOO_HEADERS "") 
FOREACH (FOO_HEADER ${FOO_HEADERS}) 
    ADD_CUSTOM_COMMAND(
     OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${FOO_HEADER} 
     COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${FOO_HEADER} ${CMAKE_CURRENT_BINARY_DIR}/${FOO_HEADER} 
     DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${FOO_HEADER}) 
    LIST (APPEND BINARY_FOO_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/${FOO_HEADER}) 
ENDFOREACH() 
INSTALL(FILES ${BINARY_FOO_HEADERS} 
    DESTINATION include/foo COMPONENT foo OPTIONAL) 

FOREACH 루프는 해당 바이너리 디렉토리에 FOO_HEADERS 그대로 복사 사용자 정의 명령을 설정합니다. 현재 소스 디렉토리의 헤더를 직접 사용하는 대신 INSTALL(FILES ... 명령은 2 진 dir에서 복사 된 헤더를 선택합니다. 바이너리 디렉토리의 헤더 경로는 변수 BINARY_FOO_HEADERS에 수집됩니다.

마지막으로 FOO_INSTALL 대상은 다음과 같은 방식으로 설정해야합니다 :

SET(FOO_INSTALL "install.foo") 
ADD_CUSTOM_TARGET(${FOO_INSTALL} 
    COMMAND ${CMAKE_COMMAND} 
     -D COMPONENT=foo 
     -P cmake_install.cmake 
    DEPENDS ${BINARY_FOO_HEADERS}) 
ADD_DEPENDENCIES(${FOO_INSTALL} ${FOO_LIBRARY}) 

사용자 정의 FOO_INSTALL은 헤더 파일의 복사를 트리거 할 BINARY_FOO_HEADERS에 대한 종속성으로 추가됩니다. FOO_LIBRARY에 대한 대상 레벨 종속성은 make install.foo을 실행할 때 라이브러리 빌드를 트리거합니다.

  1. CMake 것이 Target "foo" has EXCLUDE_FROM_ALL set and will not be built by default but an install rule has been provided for it. CMake 그러나 어쨌든 옳은 일을 할 것입니다 경고를 구성시 :

    이 솔루션은 그러나 다음과 같은 단점이 있습니다. 당신이 make install.foo을 실행하면 내장 FOO 라이브러리와 헤더 바이너리 디렉토리에 존재하기 때문에

  2. 후속 make install 명령은 모든 FOO 관련 파일을 설치합니다. 당신을 위해

+0

감사합니다. @sakra. 결과적으로 FOO_LIBRARY는 자동으로 만들어지며, 보통 "make"에 링크가되는 타겟이 있다면 자동으로 만들어지게됩니까? – Jeet

+0

예. 'TARGET_LINK_LIBRARIES'를 사용하면 FOO_LIBRARY가 빌드됩니다. – sakra

+0

감사합니다. (1)에 대한 경고를 억제하는 것이 좋을 것입니다. – Jeet

0

확인 this solution 작동합니다.

사용하고 싶다고 말한 명령과 다른 명령을 사용해야하지만 문제를 상당히 잘 해결한다고 생각합니다.

관련 문제