本文介绍了使用共享库版本的CMake最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm organizing my "development policies in C" and distributing some codes in static and shared libs.

静态库是可以的,但是我发现了空白关于文档中的共享库:如何在 find_library上指定SOVERSION。

Static libs are ok, but I found a "gap" about shared libraries in documentation: How to specify the SOVERSION on "find_library".

此刻,我以这种方式构建库:

At this moment I'm building libraries this way:

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
  )

运行cma ke,make和make install结果如下:

Running cmake, make and make install it results in:

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

在另一个库中,我包括这种方式:

And in another library, I'm including this way:

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
  )

我不敢相信这是正确的方法做吧。有人可以向我展示一种更好的方法吗?

I can't believe this is the right way to do it. Could any one show me a better way?

推荐答案

对于特定于库的搜索,可以使用 precise NAMES 选项中的 find_library 中的文件名:

For search specific soversion of library you can use precise filename in NAMES option for find_library:

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

从:






这可用于在类似UNIX的系统上定位静态库。假定同一库的不同 soversion 相互兼容。

库中的更改(引入ABI 不兼容)应与更改库的更改同时进行。 版本。例如: libcJSON2.so 。因此,您不能使用 find_library 偶然找到不兼容库。

Changes in the library, which introduce ABI incopatibility should be accompanied with changing library's version. E.g: libcJSON2.so. So you cannot accidentally find incompatible library using find_library.

这篇关于使用共享库版本的CMake最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 06:27