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

Ubuntu下使用CMake编译共享库时出现链接器错误

Ubuntu下CMake构建共享库出现链接器错误

我在Ubuntu系统上使用CMake和GCC(G++)构建共享库时,每次都会出现链接器错误。编译静态库可正常构建,Windows系统下静态库和共享库均能正常编译。

链接器错误信息

usr/bin/ld: Dependencies/GLAD/libGLAD.a(gl.c.o): warning: relocation against glad_glNamedFramebufferReadBuffer' in read-only section .text'
/usr/bin/ld: CMakeFiles/Soul-Byte-Engine-Core-Window-Manager-obj.dir/Sources/WindowManager.cpp.o: relocation R_X86_64_PC32 against symbol `_ZSt4cout@@GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Soul-Byte-Engine-Core-Window-Manager.dir/build.make:89: libSoul-Byte-Engine-Core-Window-Manager.so] Error 1
make[1]: *** [CMakeFiles/Makefile2:164: CMakeFiles/Soul-Byte-Engine-Core-Window-Manager.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

我的CMakeLists.txt内容

cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)

project(Soul-Byte-Engine-Core-Window-Manager VERSION 1.0.0 LANGUAGES CXX)

option(BUILD_WINDOW_MANAGER_AS_STATIC "" OFF)
option(BUILD_WINDOW_MANAGER_WITH_GLFW_SOURCES "" OFF)
option(INCLUDE_LOGGING_SYSTEM_SUPPORT "" OFF)

string(TIMESTAMP BuildDate "%Y-%m-%d")

set(BUILT_BY "Unknown" CACHE STRING "The name of build author")

get_directory_property(hasParent PARENT_DIRECTORY)

if(hasParent)
    set(WINDOW_MANAGER_MAJOR_VERSION  PARENT_SCOPE)
    set(WINDOW_MANAGER_MINOR_VERSION  PARENT_SCOPE)
    set(WINDOW_MANAGER_PATCH_VERSION  PARENT_SCOPE)
else()
    set(WINDOW_MANAGER_MAJOR_VERSION 1)
    set(WINDOW_MANAGER_MINOR_VERSION 0)
    set(WINDOW_MANAGER_PATCH_VERSION 0)
endif()

include_directories(Include)

add_library(${PROJECT_NAME}-obj
    OBJECT 
    Sources/WindowManager.cpp
    Sources/META.cpp
    Include/WindowManager/WindowManager.hpp
    Include/WindowManager/META.hpp
)

add_subdirectory(Dependencies/GLAD)
target_include_directories(${PROJECT_NAME}-obj PUBLIC Dependencies/GLAD/include)

if(BUILD_WINDOW_MANAGER_AS_STATIC)
    add_library(${PROJECT_NAME} 
        STATIC 
        $<TARGET_OBJECTS:${PROJECT_NAME}-obj>
    )
else()
    if(WIN32)
        set ( CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
    endif()
    add_library(${PROJECT_NAME}
        SHARED
        $<TARGET_OBJECTS:${PROJECT_NAME}-obj>
    )
endif()

if(WIN32)
    if(NOT BUILD_WINDOW_MANAGER_WITH_GLFW_SOURCES)
        message(WARNING "When using Windows OS Window Manager will be built with GLFW sources regardless of options !")
        set(BUILD_WINDOW_MANAGER_WITH_GLFW_SOURCES ON)
    endif()
endif()

if(BUILD_WINDOW_MANAGER_WITH_GLFW_SOURCES)
    set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
    set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
    set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
    set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
    add_subdirectory(Dependencies/GLFW)
    target_include_directories(${PROJECT_NAME}-obj PUBLIC Dependencies/GLFW/include)
else()
    find_package(glfw3 REQUIRED)
    target_include_directories(${PROJECT_NAME}-obj PUBLIC ${GLFW_INCLUDE_DIRS})
endif()

include_directories(${CMAKE_CURRENT_BINARY_DIR}/META)

if(CMAKE_SIZEOF_VOID_P EQUAL 8)
    set(BUILT_FOR "${CMAKE_SYSTEM_NAME} x86_64")
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
    set(BUILT_FOR "${CMAKE_SYSTEM_NAME} x86")
endif()

configure_file(
    "META/BuildInfo.h.in"
    "${CMAKE_CURRENT_BINARY_DIR}/META/BuildInfo.h"
)

target_link_libraries(${PROJECT_NAME} GLAD glfw)

解决方案

1. 为OBJECT目标添加-fPIC编译选项

Ubuntu下构建共享库要求所有参与链接的目标文件都使用位置无关代码(PIC),但CMake默认不会为OBJECT目标启用该选项。在定义${PROJECT_NAME}-obj库后添加以下代码:

target_compile_options(${PROJECT_NAME}-obj PRIVATE -fPIC)

2. 确保依赖库GLAD也编译为PIC

GLAD静态库同样需要PIC才能被共享库链接。在add_subdirectory(Dependencies/GLAD)之前,全局启用位置无关代码编译:

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

该设置会让后续所有构建的目标(包括GLAD)自动使用-fPIC编译。

3. 优化后的关键CMake代码片段

修改后的OBJECT库定义和GLAD构建部分:

add_library(${PROJECT_NAME}-obj
    OBJECT 
    Sources/WindowManager.cpp
    Sources/META.cpp
    Include/WindowManager/WindowManager.hpp
    Include/WindowManager/META.hpp
)
# 添加PIC编译选项
target_compile_options(${PROJECT_NAME}-obj PRIVATE -fPIC)

# 全局启用PIC,确保依赖库也符合要求
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_subdirectory(Dependencies/GLAD)
target_include_directories(${PROJECT_NAME}-obj PUBLIC Dependencies/GLAD/include)

完成以上修改后,重新运行CMake和make即可正常构建共享库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:17:00