'삽질記'에 해당되는 글 1건

  1. 2011.01.30 [삽질記] luabind를 사용하여 루아에서 C++ 코드 호출하기

[삽질記] luabind를 사용하여 루아에서 C++ 코드 호출하기

luabind는 C++와 루아를 바인딩할 때 도움을 주는 라이브러리이다. 여기서는 luabind에 대한 자세한 설명은 생략하고 luabind 문서에 있는 hello world 프로그램을 작동시키기까지 겪은 일을 정리해 보겠다.

* 목표 : http://www.rasterbar.com/products/luabind/docs.html의 5.1 Hello world를 실행하기
* 환경 : ubuntu 10.10 x86_64(Live)


1. luabind 설치
문서에는 bjam을 사용하여 직접 빌드하는 방법이 나와 있지만 귀찮으니 시냅틱 패키지 관리자를 사용하여 설치하기로 하였다.

기본 저장소(main)에는 luabind가 없고 저장소 설정에서 universe 저장소를 체크해야 luabind를 찾을 수 있다
.


luabind로 찾으면 libluabind-dbg, libluabind-dev, libluabind-doc, libluabind-examples, libluabind0.9.0이라는 패키지들이 검색되는데, 모두 설치하였다(의존성이 있는 boost나 lua 관련 패키지들도 모두 설치).

설치가 끝나고 lua를 실행해보니, 'lua'가 없단다.--;
ubuntu@ubuntu:~$ lua
The program 'lua' can be found in the following packages:
 * lua5.1
 * lua40
Try: sudo apt-get install <selected package>
ubuntu@ubuntu:~$

luabind를 설치하면 알아서 깔릴 줄 알았더니 아니었다.


2. lua 설치
역시 시냅틱으로 lua를 설치했다(lua5.1과 lua5.1-doc 설치).
설치 후 lua를 실행시켜 보니, 이번에는 lua shell이 떴다.
ubuntu@ubuntu:~$ lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>


3. Hello world 코드 작성 및 컴파일
이제 문서에 나온 Hello world 코드를 작성해야 하는데, 아까 깐 패키지 중에 libluabind-examples라는 이름이 왠지 수상하여 살펴보니, 예제 코드가 포함되어 있었다. 이로써 타이핑할 수고는 덜 수 있었다.
ubuntu@ubuntu:~$ dpkg -L libluabind-examples
...
/usr/share/doc/libluabind-examples/examples/hello_world
/usr/share/doc/libluabind-examples/examples/hello_world/hello_world.cpp
/usr/share/doc/libluabind-examples/examples/hello_world/README
/usr/share/doc/libluabind-examples/examples/hello_world/Makefile
...
ubuntu@ubuntu:~$

퍼미션 문제가 있으니 Hello world 코드를 홈 디렉터리로 복사하고 make를 실행하였다.
ubuntu@ubuntu:~/hello_world$ make
g++ -shared hello_world.cpp -o hello_world.so -I/sw/include -L/sw/lib \
    -I/usr/include/lua5.1 -I/usr/include/boost \
    -llua5.1 -lluabind
/usr/bin/ld: /tmp/ccBd0u3H.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/tmp/ccBd0u3H.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [helloworld_test] Error 1
ubuntu@ubuntu:~/hello_world$

예상대로(--;) 실패한다. 친절한(?) 에러 메시지를 따라서 Makefile에 -fPIC를 추가하고 다시 make를 실행했다.
all: helloworld_test

# if using fink on darwin
# you need these additional flags
CPPFLAGS = -I/sw/include -L/sw/lib -fPIC

helloworld_test: hello_world.cpp
        $(CXX) -shared hello_world.cpp -o hello_world.so $(CPPFLAGS) \
        -I/usr/include/lua5.1 -I/usr/include/boost \
        -llua5.1 -lluabind

clean:
        rm -f helloworld *.o *~


이번에는 성공했다. hello_world.so라는 파일(shared library)이 생겼다.


4. lua shell에서 Hello world 불러오기
lua shell을 실행한 후, 문서에 나온대로 따라해 봤다
(문서에는 'hello_world.dll'가 나와 있지만 리눅스이므로 'hello_world.so'를 사용했다.)
ubuntu@ubuntu:~/hello_world$ lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> loadlib('hello_world.so', 'init')()
stdin:1: attempt to call global 'loadlib' (a nil value)
stack traceback:
    stdin:1: in main chunk
    [C]: ?
>

역시나 바로 되는 일은 없다. --;
여기가 가장 고생한 부분이다. 여기 저기 검색하며 뒤져보다가 최근 버전의 lua에서는 loadlib() 대신 package.loadlib()를 쓰는 것으로 바뀌었다는 내용을 보았다(링크는 잊어버렸다).

어쨌든 package.loadlib()로 바꿔서 시도해봤다.
> package.loadlib('hello_world.so', 'init')()
stdin:1: attempt to call a nil value
stack traceback:
    stdin:1: in main chunk
    [C]: ?
>

또 안된다. --; 대신 에러 메시지는 달라졌다. 여기 저기 뒤져봤지만, 해결책은 찾지 못했다.
거의 포기하려다가 혹시나 하는 마음으로 so 파일의 경로에 './'를 추가해 봤다.
> package.loadlib('./hello_world.so', 'init')()
> greet()
hello world!
>

드디어 성공이다! 이거 하나 띄우려고 며칠을 고생했던가... 젠장, 문서에 몇 글자만 고쳐져 있었으면 이렇게 고생을 안 했을텐데.. 루아에 대해 전혀 모른 상태여서 더 어려운 점도 있었다.

어쨌든 이번 일로 얻은 교훈은 있다.

교훈
* 문서를 참조할 때는 그대로 믿지 말라.
* 오래 방치된 문서는 누군가를 삽질의 세계로 인도할 수 있다.


(추가)
이 글을 쓰면서 examples/hello_world/README 파일을 열어 보았더니, 거기에는 다음과 같은 내용이 있는 게 아닌가! 이 파일을 열어 보았다면 한 번의 삽질은 줄일 수 있었을 텐데, 가까운 곳을 찾지는 않고 먼 곳을 뒤지고 있었던 것이다.
ubuntu@ubuntu:~/hello_world$ cat README
this example will build an extension module as a shared library, use
loadlib() from within the lua interpreter to load the library, it will
then export a function named greet() which you can call.

> loadlib('./hello_world.so', 'init')()
> greet()
Hello world!
>


교훈 추가
* 패키지나 소스를 사용하기 전에 첨부된 README 파일은 꼭 읽어보자.

prev 1 next