这个lua 来自于 skynet/tree/master/3rd/lua
新建 uselua 目录, 把 lua 文件夹拷贝到 uselua 目录下
~/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()
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} )
~/cpp/uselua $ cat main.c
这个c 程序,调用 test.lua , 取出 width 和 length 两个变量
#include
#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;
}
demo1 是 demo1.c 生成的lua动态库
~/cpp/uselua $ cat bin/test.lua
width = 10
length = 20
local m = require("demo1")
print(m.foo())
是c语言创建的 lua 动态库, 供 test.lua 调用
#define LUA_LIB
#include
#include
#include
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