2015-12-08 84 views
0

我正在組織我的「C開發策略」並在靜態和共享庫中分發一些代碼。使用共享庫版本的CMake最佳實踐

靜態庫是好的,但我發現文檔中共享庫的一個「缺口」:如何在「find_library」上指定SOVERSION。

在這一刻我建庫是這樣的:

cmake_minimum_required (VERSION 2.8.11) 

set (INSTALL_BIN_DIR "" CACHE PATH "full binary path") 
set (INSTALL_LIB_DIR "$ENV{HOME}/embedded/llib/lib" CACHE PATH "full binary path") 
set (INSTALL_INCLUDE_DIR "$ENV{HOME}/embedded/llib/include" CACHE PATH "full include path") 
set (SRC_DIR "src" CACHE PATH "Source files path") 
set (H_DIR "include" CACHE PATH "Source files path") 

set (C_FILES) 
list (
    APPEND C_FILES 
    ${SRC_DIR}/cJSON.c 
    ) 

set (H_FILES) 
list (
    APPEND H_FILES 
    ${H_DIR}/cJSON.h 
    ) 

# Define Project name 
project (cJSON) 

# Create a library called "cJSON" which includes the source and header files. 
add_library (cJSON SHARED "${C_FILES}") 

#set_target_properties(cJSON PROPERTIES 
# PUBLIC_HEADER "include/cJSON.h") 

include_directories (include) 
# Make sure the compiler can find include files for our Hello library 
# when other libraries or executables link to Hello 
#target_include_directories (cJSON PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 

set_target_properties (cJSON 
         PROPERTIES 
          VERSION 1.0 SOVERSION 1 
          PUBLIC_HEADER "${H_FILES}" 
        ) 

install(TARGETS cJSON 
# IMPORTANT: Add the foo library to the "export-set" 
    EXPORT cJSONTargets 
    LIBRARY 
    RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin 
    LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT shlib 
    PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}" COMPONENT dev 
) 

運行cmake的,make和make install它導致:

lrwxrwxrwx 1 takaite takaite 13 Dez 7 11:52 libcJSON.so -> libcJSON.so.1 
lrwxrwxrwx 1 takaite takaite 15 Dez 7 11:52 libcJSON.so.1 -> libcJSON.so.1.0 
-rw-r--r-- 1 takaite takaite 27194 Dez 7 15:03 libcJSON.so.1.0 

而在另一個庫,我包括這方式:

cmake_minimum_required (VERSION 2.8.11) 

set (INSTALL_BIN_DIR "" CACHE PATH "full binary path") 
set (INSTALL_LIB_DIR "$ENV{HOME}/embedded/llib/lib" CACHE PATH "full binary path") 
set (INSTALL_INCLUDE_DIR "$ENV{HOME}/embedded/llib/include" CACHE PATH "full include path") 
set (SRC_DIR "src" CACHE PATH "Source files path") 
set (H_DIR "include" CACHE PATH "Source files path") 

set (C_FILES) 
list (
    APPEND C_FILES 
    ${SRC_DIR}/dict.c 
    ) 

set (H_FILES) 
list (
    APPEND H_FILES 
    ${H_DIR}/dict.h 
    ) 


# Define Project name 
project (dict) 

set (CMAKE_FIND_LIBRARY_SUFFIXES_BKP ${CMAKE_FIND_LIBRARY_SUFFIXES}) 
# Set lib version to be used 
set (CMAKE_FIND_LIBRARY_SUFFIXES ".so.1") 

find_library (
    CJSON_LIB 
    NAMES cJSON 
    PATHS ${INSTALL_LIB_DIR} 
    ) 
set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_BKP}) 

message ("cJSON_lib: ${CJSON_LIB}") 

# Create a library called "cJSON" which includes the source and header files. 
add_library (dict SHARED "${C_FILES}" ${CJSON_LIB}) 

include_directories (${H_DIR} ${INSTALL_INCLUDE_DIR}) 
# Make sure the compiler can find include files for our Hello library 
# when other libraries or executables link to Hello 
#target_include_directories (cJSON PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 

set_target_properties (dict 
         PROPERTIES 
          VERSION 1.0 SOVERSION 1 
          PUBLIC_HEADER "${H_FILES}" 
        ) 

install(TARGETS dict 
# IMPORTANT: Add the foo library to the "export-set" 
    EXPORT DictTargets 
    LIBRARY 
    RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin 
    LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT shlib 
    PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}" COMPONENT dev 
) 

我不敢相信這是正確的做法。任何人都能讓我看到更好的方式嗎?

回答

2

對於庫的搜索特定soversion可以使用精確文件名中NAMES選項find_library

find_library (
    CJSON_LIB 
    NAMES libcJSON.so.1 
    PATHS ${INSTALL_LIB_DIR} 
    ) 

從文檔find_library

給予names選項每個庫名首先被視爲庫文件名,然後考慮平臺特定的前綴(例如lib)和後綴(例如.so)。因此可以直接指定庫文件名,例如libfoo.a。這可以用來在類UNIX系統上定位靜態庫。


。注意,不同soversion S中的相同的庫的被假定爲ABI 兼容彼此。因此很少需要搜索圖書館的特定範圍。

變化在庫,引進ABI incopatibility應該改變圖書館的版本陪同。例如:libcJSON2.so。所以你不能意外地發現不兼容庫使用find_library