今天呢,想說來看一下lua好了。Lua是一個在許多遊戲中當作scripting language的程式語言,為這些遊戲提供了不小的擴展性。首先,lua可以讓遊戲在不重新編譯的狀態下更有彈性的更改參數;其次,lua提供了一個讓玩者自訂遊戲的管道(像是製作新道具等)。
提供自訂能力的lua必須由另一隻程式來驅動。也就是,我可以做出一隻C語言的程式,讓該程式與lua程式庫連結,然後載入並執行lua的程式碼。
於是,我的第一隻lua相關的程式長這樣:
#include <lua.h> #include <lualib.h> #include <stdio.h> #include <stdlib.h> void* allocator(void* ud, void* ptr, size_t osize, size_t nsize) { if (nsize == 0) { free(ptr); return NULL; } else { return realloc(ptr, nsize); } } int main() { lua_State* state = lua_newstate(allocator, NULL); const lua_Number* version = lua_version(NULL); printf("Version: %f\n", *version); lua_close(state); return 0; }
接著來編譯:
gcc -I${HOME}/applications/lua-5.2.1/include\ -L${HOME}/applications/lua-5.2.1/lib/\ -std=c99 -llua -lm a.c
Fedora 18只提供lua 5.1,而我想要使用傳說中的_ENV,所以只好自行製作lua 5.2囉。(據說有位人士自行製作了lua 5.2,把系統提供的lua 5.1,然後發生了慘不忍睹的事情...)
令人難過(且驚訝)的是編譯並不成功:
#錯誤訊息 /tmp/cc4PrIDU.o: In function `main': a.c:(.text+0x5a): undefined reference to `lua_newstate' a.c:(.text+0x68): undefined reference to `lua_version' a.c:(.text+0x97): undefined reference to `lua_close' collect2: error: ld returned 1 exit status
利用gcc -I${HOME}/applications/lua-5.2.1/include -L${HOME}/applications/lua-5.2.1/lib/ -std=c99 -llua -lm a.c -Wl,--verbose
得知linker有找到我自製的liblua.a:
GNU ld version 2.23.51.0.1-3.fc18 20120806 Supported emulations: elf_x86_64 elf32_x86_64 elf_i386 #中略 attempt to open /home/略/applications/lua-5.2.1/lib//liblua.so failed attempt to open /home/略/applications/lua-5.2.1/lib//liblua.a succeeded #後略 found ld-linux-x86-64.so.2 at /lib64/ld-linux-x86-64.so.2 /tmp/ccitISUF.o: In function `main': a.c:(.text+0x5a): undefined reference to `lua_newstate' a.c:(.text+0x68): undefined reference to `lua_version' a.c:(.text+0x97): undefined reference to `lua_close' collect2: error: ld returned 1 exit status
而且該liblua.a裡面也有這三個symbol:
$ objdump -x liblua.a | grep -P "(lua_newstate|lua_version|lua_close)" 0000000000000330 g F .text 000000000000001e lua_version 00000000000002d0 g F .text 00000000000002a0 lua_newstate 0000000000000000 *UND* 0000000000000000 lua_version 00000000000006a0 g F .text 0000000000000010 lua_close 00000000000003d1 R_X86_64_32S lua_newstate 0000000000000454 R_X86_64_PC32 lua_version-0x0000000000000004 0000000000000000 *UND* 0000000000000000 lua_newstate 0000000000000000 *UND* 0000000000000000 lua_version 0000000000001f09 R_X86_64_PC32 lua_newstate-0x0000000000000004 0000000000001f40 R_X86_64_PC32 lua_version-0x0000000000000004 0000000000001f4a R_X86_64_PC32 lua_version-0x0000000000000004 0000000000000000 *UND* 0000000000000000 lua_close 0000000000000184 R_X86_64_PC32 lua_close-0x0000000000000004
至少這個archive裡面有object提供這些symbol...那為什麼會找不到呢?順序嗎?有聽說過呢!試試看好了:
$ #之前:gcc -I${HOME}/applications/lua-5.2.1/include\ $ # -L${HOME}/applications/lua-5.2.1/lib/ -std=c99\ $ # -llua -lm a.c $ gcc -I${HOME}/applications/lua-5.2.1/include\ > -L${HOME}/applications/lua-5.2.1/lib/\ > -std=c99 a.c -llua -lm $ ls a.out a.out $ ./a.out Version: 502.000000
算是誤打誤撞找到了解答。順序真的很重要呢!
沒有留言:
張貼留言