2013-05-10 42 views
1

我有一個作爲我的項目的一部分構建和鏈接的庫。我想提供設施,可選擇將系統庫安裝在系統中(或$ {CMAKE_INSTALL_PREFIX}設置的任何位置)。否則,默認情況下,項目的最終構建產品將靜態鏈接到庫,前者將被安裝,但庫二進制文件將保留在構建目錄中。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開關來欺騙CMake以避免安裝FOO相關文件。

對於FOO庫目標,命令必須通過以下方式修改:

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

EXCLUDE_FROM_ALL被添加到ADD_LIBRARY防止庫從建築,當你運行一個普通make。通過添加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逐字拷貝到相應的二進制DIR自定義命令。而不是直接使用當前源目錄中的頭文件,INSTALL(FILES ...命令會從二進制目錄中選取複製的頭文件。二進制目錄中標題的路徑收集在變量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依賴加入到觸發頭文件的複製。當您運行make install.foo時,對FOO_LIBRARY的目標級別依賴關係會觸發庫的構建。然而

該解決方案具有以下缺點:

  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會做正確的事情呢。

  2. 一旦運行make install.foo隨後make install命令也將安裝所有FOO相關文件,因爲內置FOO庫和頭文件的二進制目錄中。

+0

謝謝@sakra。這是否會導致FOO_LIBRARY在默認情況下自動構建,如果有make目標與它鏈接的話,就會自動生成一個「make」 – Jeet 2013-05-11 20:15:49

+0

是的。使用'TARGET_LINK_LIBRARIES'將導致FOO_LIBRARY被構建。 – sakra 2013-05-12 07:44:02

+0

謝謝! (1)的警告將會很好。 – Jeet 2013-05-12 16:43:30

0

檢查this solution是否適合您。

你將不得不使用不同的命令給你說你想使用的,但我認爲它解決了這個問題相當好。

相關問題