cmake 构建 lua 及 嵌入c程序 和 lua脚本相互调用

12 篇文章 1 订阅

这个lua 来自于 skynet/tree/master/3rd/lua

新建 uselua 目录, 把 lua 文件夹拷贝到 uselua 目录下

lua 目录里新建 CMakeLists.txt 

~/cpp/uselua/lua $ cat CMakeLists.txt

ADD_DEFINITIONS(-DLUA_USE_LINUX -std=gnu99)

add_library (lualib STATIC lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c ltm.c lundump.c lvm.c lzio.c lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c lutf8lib.c)
set_target_properties(lualib PROPERTIES OUTPUT_NAME "lua") # rename the library output name

link_directories (${LUA_BINARY_DIR})
add_executable (lua lua.c)
target_link_libraries (lua lualib dl readline)
if(UNIX)
        target_link_libraries( lua m )
endif()

SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-E")

link_directories (${LUA_BINARY_DIR})
add_executable (luac luac.c)
target_link_libraries (luac lualib dl readline)
if(UNIX)
        target_link_libraries( luac m )
endif()

 

uselua 目录下 的 CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
 
project(uselua)
 
set(SYS_LIBS lualib dl)
if(APPLE)
	list(APPEND SYS_LIBS -lm -lpthread)
    ADD_DEFINITIONS(
        -DMACOS -g -Wunused-variable -Wunused-parameter -Wunused-function -Wunused
        -Wno-deprecated -Wwrite-strings
    )
elseif(UNIX)
	list(APPEND SYS_LIBS -lm -lpthread)
    ADD_DEFINITIONS(
        -DUNIX -g -fPIC -Wunused-variable -Wunused-parameter -Wunused-function -Wunused
        -Wno-deprecated -Wwrite-strings 
    )
else()
	list(APPEND SYS_LIBS wsock32 ws2_32)
    ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -DHAVE_STRUCT_TIMESPEC)
endif()
 
 
set(BIN_DIR ${PROJECT_SOURCE_DIR}/bin)
 
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BIN_DIR} )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BIN_DIR} )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BIN_DIR} )
 
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
    string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
    set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${BIN_DIR} )
    set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${BIN_DIR} )
    set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${BIN_DIR} )
    message(STATUS CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG})
endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )
 
include_directories(${PROJECT_SOURCE_DIR}/lua)
include_directories(${PROJECT_SOURCE_DIR})

ADD_LIBRARY(demo1 SHARED demo1.c)
set_target_properties(demo1 PROPERTIES PREFIX "")

add_subdirectory(lua)

SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-E")
add_executable(uselua main.c)
target_link_libraries(uselua ${SYS_LIBS} )

 

main.c

~/cpp/uselua $ cat main.c 

这个c 程序,调用  test.lua , 取出 width 和 length 两个变量


#include <stdio.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

int main(void) {
    printf("Hello World\n");

    lua_State *L = luaL_newstate();
    luaL_openlibs(L);

    if(luaL_loadfile(L, "test.lua") || lua_pcall(L, 0,0,0)){
        printf("error %s\n", lua_tostring(L,-1));
        return -1;
    }
    lua_getglobal(L,"width");
    lua_getglobal(L,"length");
    printf("width = %lld\n", lua_tointeger(L,-2));
    printf("length = %lld\n", lua_tointeger(L,-1));
    lua_close(L);

    return 0;
}

 

uselua的 bin 目录下的 test.lua

demo1 是 demo1.c 生成的lua动态库

~/cpp/uselua $ cat bin/test.lua 


width = 10
length = 20

local m = require("demo1")

print(m.foo())

 

demo1.c     uselua 目录下

是c语言创建的 lua 动态库, 供 test.lua 调用

#define LUA_LIB
 
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
 
static int foo(lua_State *L)
{
    lua_pushnumber(L, 1);
    return 1;
}
 
static const struct luaL_Reg modulename[] = {
    {"foo", foo},
    {NULL,NULL},
};
 
LUAMOD_API int
luaopen_demo1(lua_State *L)
{
    luaL_newlib(L,modulename);
    return 1;
}

 

把 atomic.h  和 spinlock.h 从 skynet 拷贝到本demo根目录

 

构建

mkdir build
cd build
cmake ..
make

 

执行

~/cpp/uselua/bin $ ls
demo1.so  liblua.a  lua  luac  test.lua  uselua

~/cpp/uselua/bin $ ./lua test.lua 
1.0

~/cpp/uselua/bin $ ./uselua 
Hello World
1.0
width = 10
length = 20

 

注意

SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-E")

这个链接器参数非常重要,没有的话会提示

~/cpp/uselua/bin/lua: error loading module 'demo1' from file './demo1.so':
	./demo1.so: undefined symbol: lua_pushnumber
stack traceback:
	[C]: in ?
	[C]: in function 'require'
	test.lua:11: in main chunk
	[C]: in ?
-E
--export-dynamic
--no-export-dynamic
When creating a dynamically linked executable, using the -E option or the --export-dynamic option causes the linker to add all symbols to the dynamic symbol table. The dynamic symbol table is the set of symbols which are visible from dynamic objects at run time.
If you do not use either of these options (or use the --no-export-dynamic option to restore the default behavior), the dynamic symbol table will normally contain only those symbols which are referenced by some dynamic object mentioned in the link.
If you use dlopen to load a dynamic object which needs to refer back to the symbols defined by the program, rather than some other dynamic object, then you will probably need to use this option when linking the program itself.
You can also use the dynamic list to control what symbols should be added to the dynamic symbol table if the output format supports it. See the description of `--dynamic-list'.
Note that this option is specific to ELF targeted ports. PE targets support a similar function to export all symbols from a DLL or EXE; see the description of `--export-all-symbols' below.

创建动态链接的可执行文件时,使用-E选项或--export-dynamic选项会使链接程序将所有符号添加到动态符号表中。动态符号表是在运行时从动态对象可见的符号集。
如果您不使用这两个选项中的任何一个(或使用该--no-export-dynamic选项恢复默认行为),则动态符号表通常仅包含链接中提到的某些动态对象引用的那些符号。
如果dlopen用于加载需要引用程序定义的符号的动态对象,而不是其他一些动态对象,则在链接程序本身时,可能需要使用此选项。
如果输出格式支持动态列表,还可以使用动态列表来控制应将哪些符号添加到动态符号表中。请参阅的说明--dynamic-list。

 

ADD_DEFINITIONS(-DLUA_USE_LINUX -std=gnu99)

如果不定义LUA_USE_LINUX,会提示

error error loading module 'demo1' from file './demo1.so':
	dynamic libraries not enabled; check your Lua installation

 

完整的工程代码

useloa.zip

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,针对你的问题,我可以给你提供一个示例Android CMake构建脚本,用于生成动态库并应用第三方动态库和静态库。请注意,以下示例假设你已经具备一定的Android CMake构建经验,了解如何编写CMakeLists.txt文件,并且已经安装并配置好了必要的工具链。 首先,我们需要在CMakeLists.txt文件中添加以下内容,以指定要构建的动态库和相关的第三方库: ``` # 指定要构建的动态库名称 set(TARGET_LIB my_dynamic_lib) # 添加动态库源文件 add_library(${TARGET_LIB} SHARED src/main/cpp/my_dynamic_lib.cpp ) # 添加第三方动态库 add_library(third_party_lib SHARED IMPORTED) set_target_properties(third_party_lib PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libthird_party_lib.so) # 添加第三方静态库 add_library(third_party_static_lib STATIC IMPORTED) set_target_properties(third_party_static_lib PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libthird_party_static_lib.a) # 链接动态库及第三方库 target_link_libraries(${TARGET_LIB} third_party_lib third_party_static_lib) ``` 上述代码中,我们首先定义了要构建的动态库名称为`my_dynamic_lib`。然后,我们添加了动态库的源文件`src/main/cpp/my_dynamic_lib.cpp`。接着,我们添加了第三方动态库`libthird_party_lib.so`和第三方静态库`libthird_party_static_lib.a`。其中,我们通过`set_target_properties`命令设置了这两个库的路径,这里假设这两个库已经被放置在了`src/main/jniLibs/${ANDROID_ABI}/`目录下。 最后,我们通过`target_link_libraries`命令将动态库和第三方库链接起来。 希望这个示例能够帮助到你。如果你还有其他问题或疑问,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值