You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux环境下CMake中为无SONAME的共享库创建导入库目标并实现安装后正确链接的方案

Solution for Importing a SONAME-less Shared Library in CMake with Correct Runtime Linking After Installation

Let's break down how to properly set up the imported foo library target so your bar executable works both during development and after installation. The core issues with your previous attempts were missing library installation steps, incorrect path handling, and not configuring runtime search paths (RPATH).

Step 1: Create the Imported Library Target Correctly

First, define the imported foo target with its absolute path, and mark it as global so it's visible across your project:

add_library(foo SHARED IMPORTED GLOBAL)
set_target_properties(foo PROPERTIES
    # Use the absolute path to avoid CMake converting it to a relative path in internal builds
    IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/foo.so"
)

This avoids the relative path problem from your first attempt because we're explicitly using an absolute path for the source library.

Step 2: Install the Precompiled foo.so

Your original install command only handles the bar executable—you need to copy foo.so to the installation's lib directory too, so it's available where bar expects it:

install(FILES "${CMAKE_SOURCE_DIR}/foo.so"
    DESTINATION lib
    PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
)

Step 3: Configure Runtime Search Path (RPATH) for bar

To ensure bar can find foo.so both during development (in your build directory) and after installation, set both build and install RPATH properties:

set_target_properties(bar PROPERTIES
    # For running bar directly from the build directory: point to the original foo.so location
    BUILD_RPATH "${CMAKE_SOURCE_DIR}"
    # For installed bar: use a relative RPATH to find the lib directory (assuming bar is in bin/ and foo.so in lib/)
    INSTALL_RPATH "$ORIGIN/../lib"
    # Ensure CMake uses the specified INSTALL_RPATH instead of relying on system paths
    INSTALL_RPATH_USE_LINK_PATH TRUE
)

The $ORIGIN variable is a special token understood by the dynamic linker—it refers to the directory where the bar executable is located. So $ORIGIN/../lib tells the linker to look in the lib directory one level above bar's install location (perfect if you're installing bar to bin/ and foo.so to lib/).

Finally, link your executable to the imported target as intended:

target_link_libraries(bar PRIVATE foo)

Why Your Previous Attempts Failed

  1. Method 1: CMake converts absolute paths to relative paths in internal builds, which breaks runtime linking after installation (the relative path no longer points to foo.so). You also didn't install foo.so to the target location.
  2. Method 2: IMPORTED_NO_SONAME ON tells CMake to use -lfoo for linking, but the linker expects libraries named libfoo.so when using -l flags—your library is named foo.so, so this fails.
  3. Method 3: Setting IMPORTED_SONAME doesn't fix the root issue because your library doesn't have an embedded SONAME, and you still didn't handle installation of foo.so or configure RPATH for the installed executable.

Testing the Setup

  1. Build in ${CMAKE_SOURCE_DIR}/build as usual:
    cd build
    cmake ..
    make
    
    Running ./bar from the build directory should work, thanks to the BUILD_RPATH pointing to the original foo.so.
  2. Install to an external location:
    make install DESTDIR=/path/to/installation
    
    Running /path/to/installation/bin/bar should now find /path/to/installation/lib/foo.so via the configured INSTALL_RPATH.

内容的提问来源于stack exchange,提问作者gnaggnoyil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 15:37:31