hammackj

So much faster...

alt text

Gave up on my own engine and started to use Unity3d.

Tagged under gamedevunity3droguelike

Slightly Better Astar!

alt text

Clearly this is not right!

Tagged under gamedevc++11roguelikeastar

Drunk AI!

alt text

Clearly this is not right!

Tagged under gamedevc++11roguelike

Woot fake lighting!

alt text

Implemented some fake lighting!

Tagged under gamedevc++11roguelike

C++ 11 and LuaJIT Integration

Last weekend I was trying to integrate LuaJIT into my custom game engine but I was getting this strange lua runtime error:

[hammackj@taco:~/luajit_playground/luajit_static]$ ./static
Hello from Lua
Couldn't load file luatest.lua : luatest.lua:10: dlsym(RTLD_DEFAULT, test_ffi): symbol not found

After a bit of googling I couldn't really find an answer, all the examples I found just worked. So I started to look a little deeper.

[hammackj@taco:~/luajit_playground/luajit_static]$ nm -gU static
0000000100000000 T ____mh_execute_header
0000000100001110 T ____main

By looking at all of the final symbols from the binary I could see my test_ffi function was missing. From here I was fairly certain clang was stripping all of the dead code that wasn't being directly called. Which was causing my problem as I was using the FFI interface to export my C++ wrappers to lua. After a few more hours of googling I found a stackoverflow question about dead code striping that led me to adding this -Wl,-force_load,libstatic.a, to my linker command.

[hammackj@taco:~/luajit_playground/luajit_static]$ nm -gU static
0000000100000000 T ____mh_execute_header
0000000100001110 T ____main
0000000100001c40 T ____test_ffi

The symbol was now being correct "exported" from the static library to the host binary and not bring stripped. The output now worked correctly.

[hammackj@taco:~/luajit_playground/luajit_static]$ ./static
Hello from Lua
Hello from C++

Below is all the source code used. You can also use -Wl,-all_load, which forces all symbols / functions to be imported even if unused. This will dramatically increase the size of the binary.

//Main.cpp
#include <iostream>
#include <luajit-2.0/lua.hpp>

int main(int argc, char const *argv[])
{
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);

    const char *path = "luatest.lua";

    if (luaL_loadfile(L, path) || lua_pcall(L, 0, LUA_MULTRET, 0))
    {
        std::cerr << "Couldn't load file " << path << " : " << lua_tostring(L, -1) << std::endl;
    }

    lua_close(L);

    return 0;
}
//static.hpp
#include <iostream>

extern "C"
{
    void test_ffi();
}
//static.cpp
#include "static.hpp"

void test_ffi()
{
    std::cout << "Hello from C++" << std::endl;
}
-- luatest.lua
print "Hello from Lua"

local ffi = require('ffi')

ffi.cdef([[
void test_ffi();
]])
local C = ffi.C

C.test_ffi()
CC=c++
CFLAGS=-g -Wall -I/usr/local/include -L/usr/local/lib -L. -std=c++11 -pagezero_size 10000 -image_base 100000000
LDFLAGS=-lluajit-5.1 -lstatic -Wl,-force_load,libstatic.a

#-Wl,-all_load

FILES=main.cpp
STATIC_FILES=static.cpp

OUTPUT=static

all: static standalone

static: $(STATIC_FILES)
    $(CC) -MMD -MP -g -std=c++11 -c $(STATIC_FILES) -o static.o
    ar -rcs libstatic.a static.o

standalone: $(static) $(FILES)
    $(CC) $(CFLAGS) -o $(OUTPUT) $(FILES) $(LDFLAGS)

clean:
    rm -rf *.dSYM static *.d *.a *.o

You can find all the source code on my github. Which includes a simple standalone single binary version, the above static library version and a dynamic library version. The code is written for OSX and a brew based install of LuaJIT. I didn't test if this was a issue on gcc or msvc++.

Tagged under gamedevluac++11clang