Linux CMake使用共享库版本的最佳实践

Linux CMake使用共享库版本的最佳实践,linux,cmake,Linux,Cmake,我正在用C语言组织我的开发策略,并在静态库和共享库中分发一些代码 静态lib还可以,但我在文档中发现了一个关于共享库的漏洞:如何指定find_库的版本 此时此刻,我正以这种方式构建图书馆: 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 P

我正在用C语言组织我的开发策略,并在静态库和共享库中分发一些代码

静态lib还可以,但我在文档中发现了一个关于共享库的漏洞:如何指定find_库的版本

此时此刻,我正以这种方式构建图书馆:

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_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
  )
运行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}/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_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
  )

我不敢相信这是正确的方法。有谁能告诉我更好的方法吗?

对于特定于搜索的库版本,您可以使用“查找库”的“名称中的精确文件名”选项:

从以下文件中:

赋予“名称”选项的每个库名称首先被视为库文件名,然后与平台特定的前缀(如lib)和后缀(如so)一起考虑。因此,可以直接指定libfoo.a之类的库文件名。这可用于在类UNIX系统上定位静态库

请注意,同一库的不同版本被假定为彼此ABI兼容。因此,很少需要搜索库的特定版本

库中引入ABI不兼容的更改应该伴随着库版本的更改。例如:libcJSON2.so。因此,您不能使用find_library意外地找到不兼容的库