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

如何用CMake将可执行文件链接到ExternalProject构建的共享库?

问题:CMake链接ExternalProject构建的LuaJIT共享库失败

我尝试构建依赖LuaJIT(通过Makefile构建的第三方共享库)的可执行文件,使用CMake的ExternalProject集成,但链接时出现未定义引用错误。

我的CMakeLists.txt:

cmake_minimum_required(VERSION 3.28)
project(untitled2 LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 17)

include(ExternalProject)

set(LUAJIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/LuaJIT)
set(LUAJIT_INSTALL_DIR ${CMAKE_BINARY_DIR}/luajit)

# this is to avoid having a leading space in the quotes
if(CMAKE_C_FLAGS)
    set(LUAJIT_CFLAGS "${CMAKE_C_FLAGS} -DLUAJIT_ENABLE_LUA52COMPAT")
else ()
    set(LUAJIT_CFLAGS "-DLUAJIT_ENABLE_LUA52COMPAT")
endif()

ExternalProject_Add(
        luajit_proj
        PREFIX        ${LUAJIT_INSTALL_DIR}
        SOURCE_DIR    ${LUAJIT_SOURCE_DIR}

        CONFIGURE_COMMAND ""          # LuaJIT does not have a CMake configure step

        BUILD_COMMAND   make -C ${LUAJIT_SOURCE_DIR} install CC=${CMAKE_C_COMPILER} PREFIX=${LUAJIT_INSTALL_DIR} CFLAGS=${LUAJIT_CFLAGS} SHARED=1

        INSTALL_COMMAND   ""          # the `make install` step already did it
        UPDATE_DISCONNECTED 1
)

set(LUAJIT_LIB_PATH ${LUAJIT_INSTALL_DIR}/lib)
set(LUAJIT_INCLUDE_PATH ${LUAJIT_INSTALL_DIR}/include)

# main executable
add_executable(untitled2 main.cpp)

add_dependencies(untitled2 luajit_proj)
target_include_directories(untitled2 PRIVATE ${LUAJIT_INCLUDE_PATH})

target_link_libraries(untitled2 PRIVATE ${LUAJIT_LIB_PATH}/libluajit-5.1.so)

main.cpp代码:

#include <iostream>
#include <luajit-2.1/lua.h>
#include <luajit-2.1/lualib.h>
#include <luajit-2.1/lauxlib.h>

int main() {
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    return 0;
}

错误信息:

main.cpp:(.text+0xd): undefined reference to `luaL_newstate()'
/usr/bin/ld: main.cpp:(.text+0x1d): undefined reference to `luaL_openlibs(lua_State*)'
collect2: error: ld returned 1 exit status

LuaJIT已正常构建,头文件在builddir/luajit/include/luajit-2.1,共享库在builddir/luajit/lib(含libluajit-5.1.so符号链接),但链接失败,请问如何解决?


解决方案

1. 修复C++调用C库的符号修饰问题

LuaJIT是C语言库,C++会对函数名进行名字修饰,导致链接器无法匹配C语言符号。修改main.cpp,用extern "C"包裹LuaJIT头文件:

#include <iostream>
extern "C" {
#include <luajit-2.1/lua.h>
#include <luajit-2.1/lualib.h>
#include <luajit-2.1/lauxlib.h>
}

int main() {
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    return 0;
}

2. 优化CMake链接方式

直接指定.so文件路径不够稳妥,建议先设置链接目录,再通过库名链接:

# 替换原target_link_libraries行
target_link_directories(untitled2 PRIVATE ${LUAJIT_LIB_PATH})
target_link_libraries(untitled2 PRIVATE luajit-5.1)

或用find_library定位库,更符合CMake规范:

find_library(LUAJIT_LIB NAMES luajit-5.1 PATHS ${LUAJIT_LIB_PATH} NO_DEFAULT_PATH)
target_link_libraries(untitled2 PRIVATE ${LUAJIT_LIB})

3. 核对库的实际安装路径

LuaJIT的make install可能将库安装到架构相关子目录(如lib/x86_64-linux-gnu),检查${LUAJIT_INSTALL_DIR}/lib下的实际结构,调整LUAJIT_LIB_PATH:

# 示例:如果库在lib/x86_64-linux-gnu下
set(LUAJIT_LIB_PATH ${LUAJIT_INSTALL_DIR}/lib/x86_64-linux-gnu)

4. 配置运行时库路径(可选)

运行可执行文件时可能找不到共享库,通过设置INSTALL_RPATH让运行时定位到库:

set_target_properties(untitled2 PROPERTIES
    INSTALL_RPATH ${LUAJIT_LIB_PATH}
    BUILD_WITH_INSTALL_RPATH ON
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 12:12:26