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

如何让CMake生成的Makefile在Windows下生成.so后缀共享库

如何让CMake在Windows下生成.so后缀的共享库而非.dll?

现有跨平台项目,主程序通过dlopen()动态加载硬编码文件名libfunc.so的共享库。原手写Makefile可在Linux和Windows平台统一生成libfunc.so,但迁移到CMake构建后,Windows下默认生成libfunc.dll,导致程序因找不到指定文件运行失败(手动重命名.dll为.so后可正常运行)。以下是两种可行的CMake配置方案:

方案1:直接指定输出文件名(推荐)

通过设置共享库目标的属性,强制输出文件名为libfunc.so,跨平台生效:

修改后的CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(hello_world)

add_library(func SHARED func.c)

# 强制设置库的输出名称和后缀
set_target_properties(func PROPERTIES
    OUTPUT_NAME "libfunc"  # 覆盖默认的"func",设置基础名为libfunc
    SUFFIX ".so"           # 强制使用.so后缀,替代Windows默认的.dll
)

add_executable(a.out main.c)

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
  include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR})
endif()

说明

  • Linux下CMake原本就会生成libfunc.so,此配置对Linux无影响,仅修改Windows平台的输出规则
  • 生成的Windows导入库会变为libfunc.lib,不影响主程序动态加载逻辑

方案2:构建后重命名文件

若不想修改库的原生生成规则,可添加自定义命令,在构建完成后自动将.dll复制并重命名为.so:

修改后的CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(hello_world)

add_library(func SHARED func.c)

add_executable(a.out main.c)

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
  include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR})
  
  # 构建完成后将dll复制并重命名为so
  add_custom_command(TARGET func POST_BUILD
      COMMAND ${CMAKE_COMMAND} -E copy_if_different
          $<TARGET_FILE:func>          # 源文件:生成的func.dll
          $<TARGET_FILE_DIR:func>/libfunc.so  # 目标文件:同目录下的libfunc.so
  )
endif()

说明

  • POST_BUILD确保命令在共享库构建完成后执行
  • $<TARGET_FILE:func>和$<TARGET_FILE_DIR:func>是CMake的生成器表达式,自动适配Debug/Release等不同构建目录
  • 仅在Windows平台执行重命名操作,Linux下保持原有输出

验证效果

两种方案均实现:

  • Linux平台:生成libfunc.so和a.out
  • Windows平台:生成libfunc.so(同时保留原生func.dll和func.lib,不干扰运行)和a.exe
  • 主程序无需修改代码,可直接通过dlopen("libfunc.so")成功加载共享库

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:51:32