如何用CMake设置动态库文件名并强制添加lib前缀
设置CMake生成指定名称的动态库并适配LuaJIT加载
核心需求拆解
你需要:
- 将当前生成的
libgit2-neovim.so改为libgit2.so - 跨平台强制库文件名带
lib前缀 - 适配LuaJIT的加载规则(
require("demo")仅查找无前缀的库文件)
解决方案
1. 修改库名称并强制添加lib前缀
CMake默认会根据平台添加前缀(Linux/macOS加lib,Windows不加),要跨平台统一带lib前缀并修改库名,有两种方式:
方式一:全局配置+直接指定目标名
# 强制所有共享库添加lib前缀,覆盖平台默认行为 set(CMAKE_SHARED_LIBRARY_PREFIX "lib") # 将库目标命名为git2,最终生成libgit2.so(Linux)/libgit2.dll(Windows) add_library(git2 SHARED ${SRC_FILES})
方式二:仅针对当前目标设置属性
如果不想全局修改前缀,只调整当前库:
add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) # 设置库的输出基础名称为git2 set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "git2") # 强制该库使用lib前缀 set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "lib")
两种方式都能生成你需要的libgit2.so,且跨平台保持lib前缀。
2. 适配LuaJIT加载规则
LuaJIT执行require("git2")时,只会查找git2.so(Linux)或git2.dll(Windows)这类无前缀的文件,因此需要在编译后自动创建适配文件:
# 根据操作系统生成适配LuaJIT的库文件 if(UNIX) # Linux/macOS下创建软链接 add_custom_command( TARGET git2 POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE_NAME:git2> git2.so WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Creating symlink git2.so for LuaJIT loading" ) elseif(WIN32) # Windows下复制并重命名库文件 add_custom_command( TARGET git2 POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:git2> ${CMAKE_BINARY_DIR}/git2.dll COMMENT "Copying libgit2.dll to git2.dll for LuaJIT loading" ) endif()
修改后的完整CMake配置
整合所有修改后的完整配置:
cmake_minimum_required(VERSION 3.22.2) project("git2-neovim") message(STATUS "cmake binary directory: ${CMAKE_BINARY_DIR}") # 输出compile_commands.json供ccls等工具使用 set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # 设置GCC编译选项 set(CMAKE_C_FLAGS_DEBUG "$ENV{CFLAGS} -Wall -g3 -ggdb") set(CMAKE_C_FLAGS_RELEASE "$ENV{CFLAGS} -O3 -Wall") set( SRC_FILES src/libgit2.c ) # 强制跨平台添加lib前缀 set(CMAKE_SHARED_LIBRARY_PREFIX "lib") # 创建名为git2的共享库目标 add_library(git2 SHARED ${SRC_FILES}) find_package(PkgConfig REQUIRED) if (PKG_CONFIG_FOUND) pkg_check_modules(LIBGIT2 REQUIRED libgit2) # 用target_include_directories替代全局include_directories,更规范 target_include_directories(git2 PRIVATE ${LIBGIT2_INCLUDE_DIRS}) target_link_libraries(git2 ${LIBGIT2_LIBRARIES}) endif() # 适配LuaJIT加载 if(UNIX) add_custom_command( TARGET git2 POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE_NAME:git2> git2.so WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Creating symlink git2.so for LuaJIT" ) elseif(WIN32) add_custom_command( TARGET git2 POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:git2> ${CMAKE_BINARY_DIR}/git2.dll COMMENT "Copying to git2.dll for LuaJIT" ) endif()
额外说明
- 改用
target_include_directories并指定PRIVATE是CMake的现代用法,能更清晰地管理依赖的作用范围,避免污染全局。 - 编译完成后,你会在
CMAKE_BINARY_DIR下同时得到libgit2.so(带前缀的库文件)和git2.so(供LuaJIT加载的软链接/副本)。
内容的提问来源于stack exchange,提问作者aszswaz
相关产品推荐
相关产品推荐

