一.目标:以lua5.4.7版本为例,实现用cmake完成对lua的动态库编译
二.详细步骤:
(1)构建项目
2.1 去lua官网下载lua的源码 lua官网The Programming Language Lua
2.2 把下载得到的源码中在src文件夹下的所有源码文件拷贝到我们预编译的目录下
2.3 找到lua.c文件,因为要编译为动态库,把lua的入口main函数注释掉
2.4在当前目录下编写CMakeLists.txt,直接拷贝如下代码到CMakeLists.txt即可。
cmake_minimum_required(VERSION 3.10)
# 项目名称和版本
project(lua VERSION 5.4.7 LANGUAGES C)
# 设置C语言标准
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
# 定义输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# 根据平台添加编译定义
if(WIN32)
add_definitions(-DLUA_BUILD_AS_DLL -DLUA_USE_WINDOWS)
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
# 设置MSVC特定选项
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Od /Zi")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /O2 /Oi /Gy /GL")
else()
# MinGW/GCC特定选项
add_definitions(-D_WIN32_WINNT=0x0600)
# 修复WinMain未定义错误
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mconsole")
endif()
else()
add_definitions(-DLUA_USE_POSIX -DLUA_USE_DLOPEN)
# 设置GCC特定选项
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -O0")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2")
endif()
# Lua库的源文件
set(LUA_LIB_SOURCES
lapi.c
lauxlib.c
lbaselib.c
lcode.c
lcorolib.c
lctype.c
ldblib.c
ldebug.c
ldo.c
ldump.c
lfunc.c
lgc.c
linit.c
liolib.c
llex.c
lmathlib.c
lmem.c
loadlib.c
lobject.c
lopcodes.c
loslib.c
lparser.c
lstate.c
lstring.c
lstrlib.c
ltable.c
ltablib.c
ltm.c
lundump.c
lutf8lib.c
lvm.c
lzio.c
)
# Lua解释器的源文件
set(LUA_INTERPRETER_SOURCES
lua.c
)
# Lua编译器的源文件
set(LUA_COMPILER_SOURCES
luac.c
)
# 创建Lua共享库
add_library(lua SHARED ${LUA_LIB_SOURCES})
# 设置共享库的版本属性和输出名称
set_target_properties(lua PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
EXPORT_NAME lua
OUTPUT_NAME "lua5.4"
PREFIX ""
)
# 为MinGW/GCC设置导入库名称
if(WIN32 AND CMAKE_C_COMPILER_ID MATCHES "GNU")
set_target_properties(lua PROPERTIES
IMPORT_SUFFIX ".dll.a"
IMPORT_PREFIX ""
)
endif()
# 创建Lua解释器可执行文件
add_executable(lua_interpreter ${LUA_INTERPRETER_SOURCES})
set_target_properties(lua_interpreter PROPERTIES OUTPUT_NAME "lua")
target_link_libraries(lua_interpreter lua)
# 创建Lua编译器可执行文件
add_executable(luac ${LUA_COMPILER_SOURCES})
target_link_libraries(luac lua)
# 设置包含目录
target_include_directories(lua PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
# 为可执行文件设置包含目录
target_include_directories(lua_interpreter PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(luac PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
# 平台特定的库链接
if(UNIX AND NOT APPLE)
target_link_libraries(lua m dl)
target_link_libraries(lua_interpreter m dl)
target_link_libraries(luac m dl)
elseif(APPLE)
target_link_libraries(lua m)
target_link_libraries(lua_interpreter m)
target_link_libraries(luac m)
endif()
# 安装规则
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
# 安装目标
install(TARGETS lua lua_interpreter luac
EXPORT luaTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
# 安装头文件
install(FILES
lua.h
luaconf.h
lualib.h
lauxlib.h
lua.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
# 导出目标
install(EXPORT luaTargets
FILE luaTargets.cmake
NAMESPACE lua::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lua
)
# 生成并安装包配置文件
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/luaConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/luaConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lua
)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/luaConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/luaConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/luaConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lua
)
# 如果未指定构建类型,则设置默认构建类型
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "选择构建类型 (Debug 或 Release)" FORCE)
endif()
# 输出配置信息
message(STATUS "构建类型: ${CMAKE_BUILD_TYPE}")
message(STATUS "编译器: ${CMAKE_C_COMPILER_ID}")
message(STATUS "目标架构: ${CMAKE_SYSTEM_PROCESSOR}")
(2)开始编译
在主目录下创建build文件夹,转到该文件夹下,打开cmd指令窗口
2.5 windows下gcc编译命令
//如果需要编译Release版本,DCMAKE_BUILD_TYPE最后一个参数改为Release
cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug
2.6 windows下msvc编译命令
//如果是2019版本的vs换成2019的参数
cmake .. -G "Visual Studio 17 2022"
ps:msvc编译可以直接生成.sin项目文件,用vs打开编译更方便
2.7 开始编译
//开始编译
cmake --build .
2.8 linux上gcc的编译同理,我没测试,打对应cmake的编译指令即可。
2.9 编译可能会报错找不到main函数,不用管,此时动态库已正常生成,如果需要exe,把main函数注释掉的代码启用即可。
三.效果
最终输出目录,dll在bin文件夹下,链接库a/lib在lib文件夹下。