1. 개요

 

 이 문서는 ARM 보드에서 루아를 이용하기 위해서 필요한 요소를 설명하기 위해서
 간단한 독립형 루아 인터프린터 샘플 프로그램을 작성하고 시험하는 내용을 기록한 문서입니다.
 
 이 문서에서는 다음과 같은 내용을 다룹니다.

  • 루아 스크립트 라이브러리를 포함하는 C 컴파일 용 Makefile
  • 루아 인터프린터를 포함하는 스크립트를 수행하는 main.c

 2. Lua 버전 , 파일 

  • 5.1.4
  • lua-5.1.4.tar.gz

 
3. 환경

 

    coLinux -   Fedora

 
    작업 디렉토리는
 
            /project/lua/sample_lua_arm/
  
    입니다.

 

  

4. 하부 디렉토리 구성

 다음과 같은 디렉토리 구성을 하였습니다. 
 
 /project/lua/sample_lua_arm/lua_include : LUA 헤더 파일 모음
 /project/lua/sample_lua_arm/lua_lib  : LUA 라이브러리 소스 모음
 /project/lua/sample_lua_arm/lua_samples : 앞으로 진행할 강좌의 소스 들

 
5. 기본 샘플 구성

 

 가장 처음 제시하는 예제는 간단한 간이 LUA 인터프린터 샘플입니다.
 
 소스는 다음 디렉토리에 위치 합니다.
 
 /project/lua/sample_lua_arm/lua_samples/010_hello
 
 이 디렉토리에는 다음과 같은 파일이 있습니다.
 
 Makefile
 main.c


6. Makefile

 

다음에 소개하는 Makefile은 저희 회사에서 사용하는 일반적인 형태를 조금 변형한 것입니다.
 
보통 다음 항목만 수정하면 됩니다. 
 
CROSS_PREFIX :  보드용 gcc 컴파일러의 선두 지정 문자 입니다.      
                                 만약 arm-linux-gcc 와 같은 형태의 크로스 컴파일 환경이라면 
     
                                                CROSS_PREFIX = arm-linux
      
                                  까지만 지정합니다.
   
 TARGET  :             최종적으로 만들어질 실행 파일을 지정합니다.    hello 라는 프로그램을 최종적으로 만든다면 
     
                                                     TARGET     = hello
      
                                  이라고 지정합니다.  
     
 TARGET_NFS :     일반적으로 NFS 파일 시스템으로 보드에서 실행 환경을 갖춘다면
                                   이 변수에 서버에 복사될 NFS 디렉토리 위치를 지정합니다.
     
                                   저희 회사는 /nfs 라는 디렉토리가 사용되므로 다른 프로젝트와 구별하기 위해서
         
                                              TARGET_NFS = /nfs/lua   
      
                                  라고 지정합니다.
     
 C_SRCS  :                TARGET 을 생성하기 위한 소스 파일을 지정합니다.
                                  보통 다음과 같은 형태로 추가 합니다. 
          
                                              C_SRCS += source1.c
                                              C_SRCS += source2.c   
     
 INCLUDES :           참조하는 헤더파일 디렉토리 위치를 INCLUDES 에 추가 합니다. 
                                 다음은 기본으로 참조하도록 지정되어 있습니다.
 
                                               INCLUDES += -I.
                                               INCLUDES += -I/usr/local/include
                                               INCLUDES += -I/usr/$(CROSS_PREFIX)/include
                                               INCLUDES += -I../../include
 
 그 외에도 참조 되는 위치가 있는데 이정도에서 정리 합니다.     

 Makefile은 다음과 같습니다.          
 
 ==[Makefile]====================================================================
 
 CROSS_PREFIX = arm-linux
 
 TARGET     = hello
 TARGET_NFS = /nfs/lua
 
 C_SRCS =
 C_SRCS += main.c
 
 # LUA Support  -- CORE
 C_SRCS += ../../lua_lib/lapi.c
 C_SRCS += ../../lua_lib/lcode.c
 C_SRCS += ../../lua_lib/ldebug.c
 C_SRCS += ../../lua_lib/ldo.c
 C_SRCS += ../../lua_lib/ldump.c
 C_SRCS += ../../lua_lib/lfunc.c
 C_SRCS += ../../lua_lib/lgc.c
 C_SRCS += ../../lua_lib/llex.c
 C_SRCS += ../../lua_lib/lmem.c
 C_SRCS += ../../lua_lib/lobject.c
 C_SRCS += ../../lua_lib/lopcodes.c
 C_SRCS += ../../lua_lib/lparser.c
 C_SRCS += ../../lua_lib/lstate.c
 C_SRCS += ../../lua_lib/lstring.c
 C_SRCS += ../../lua_lib/ltable.c
 C_SRCS += ../../lua_lib/ltm.c
 C_SRCS += ../../lua_lib/lundump.c
 C_SRCS += ../../lua_lib/lvm.c
 C_SRCS += ../../lua_lib/lzio.c
 
 # LUA Support  -- LIB
 C_SRCS += ../../lua_lib/lauxlib.c
 C_SRCS += ../../lua_lib/lbaselib.c
 C_SRCS += ../../lua_lib/ldblib.c
 C_SRCS += ../../lua_lib/liolib.c
 C_SRCS += ../../lua_lib/lmathlib.c
 C_SRCS += ../../lua_lib/loslib.c
 C_SRCS += ../../lua_lib/ltablib.c
 C_SRCS += ../../lua_lib/lstrlib.c
 C_SRCS += ../../lua_lib/loadlib.c
 C_SRCS += ../../lua_lib/linit.c
 
 INCLUDES += -I.
 INCLUDES += -I/usr/local/include
 INCLUDES += -I/usr/$(CROSS_PREFIX)/include
 INCLUDES += -I../../include
 
 INCLUDES += -I../../lua_include
 
 LDFLAGS += -L../../lua_lib/
 LDFLAGS += -L/usr/$(CROSS_PREFIX)/lib
 
 LIBS    = -lm
 
 CFLAGS   += $(INCLUDES)
 CFLAGS   += -Wall -O2 -g
 
 ARFLAGS = rs
 
 #---------------------------------------------------------------------
 CC           = $(CROSS_PREFIX)-gcc
 AR           = $(CROSS_PREFIX)-ar rc
 AR2          = $(CROSS_PREFIX)-ranlib
 RANLIB       = $(CROSS_PREFIX)-ranlib
 LD           = $(CROSS_PREFIX)-ld
 NM           = $(CROSS_PREFIX)-nm
 STRIP        = $(CROSS_PREFIX)-strip
 OBJCOPY      = $(CROSS_PREFIX)-objcopy
 CP = cp
 MV = mv
 #--------------------------------------------------------------------
 
 C_OBJS    = $(C_SRCS:%.c=%.o)
 
 %.o:%.c
  @echo "Compiling $< ..."
  $(CC) -c $(CFLAGS) -o $@ $<
 
 
 all :  $(TARGET)
  cp $(TARGET) $(TARGET_NFS)
 
 $(TARGET) : $(C_OBJS)
  $(CC) $(LDFLAGS) $(C_OBJS) -o $@ $(LIBS)
 
 dep :
  $(CC) -M $(INCLUDES) $(C_SRCS) > .depend
 
 clean:
  rm -f *.bak
  rm -f *.map
  rm -f *.o
  rm -f $(C_OBJS)
  rm -f $(TARGET) core
 
 distclean: clean
  rm -rf .depend
 
 ifeq (.depend,$(wildcard .depend))
 include .depend
 endif
 
 ==[Makefile END ]====================================================================
  

7. 간단한 인터프린터 구현한 main.c

 

 다음은 아주 간단한 LUA 인터프린터 구현 소스입니다.
 
 ==[main.c]====================================================================

 #include <stdio.h>
#include <string.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main( int argc, char **argv ) 
{
    lua_State   *L = NULL;  
    char        buff[256];
    int         error;
        
    L = luaL_newstate();                                            // <---  (1)   
    luaL_openlibs(L);                                               // <---  (2) 
    
    while(1)
    {
        printf("SLUA>>");                                           // <---  (3)
        if( fgets( buff, sizeof( buff ), stdin ) == NULL ) break;   // <---  (4)
            
        error =  luaL_loadbuffer(L,buff,strlen(buff),"line")        // <---  (5)
              || lua_pcall(L,0,0,0);                                // <---  (6)
              
        if( error )                                                 // <---  (7)
        {
            fprintf(stderr,"%s\n", lua_tostring(L,-1));             // <---  (8)
            lua_pop(L,1);                                           // <---  (9)
        }               
    }
    
    lua_close(L);                                                   // <---  (10)
    
    return 0;
}

 ==[main.c END ]====================================================================


7.1 설명

 

 (1) 루아 스크립트를 동작 시키기 위한 구조체를 생성합니다.
     보통 루아 스테이터스 라고 합니다.
  
 (2) 루아 스크립트에서 기본적으로 지원하는 표준 라이브러리를 오픈 합니다.
      최소한의 함수들을 제공하도록 지원하는 것입니다 .
  
 (3) 프로그램을 실행하였을때 입력 받을 준비가 되었음을 표시하는 프롬프트 문자열을 출력 합니다.
 
 (4) 사용자의 표준입력을 buff[] 문자열 버퍼에 받습니다.
 
 (5) 입력된 buff[] 문자열 버퍼의 내용을 루아 구조체로 받아 들입니다. 이 단계에서
     스크립트의 파씽이 이루어 집니다.
    
 (6) 사용자가 입력한 내용을 실제로 수행 시켜주는 부분입니다.
 
 (7)(8)(9) 수행 과정에 에러가 발생하면 error 변수가 0이 아닌 상태가 되므로 이때 해당 내용을
     출력합니다.
    
     에러 상태는 루아 스택( 이후 강좌에서 다룸 )에 남아 있으므로 이를 제거 합니다.
 
 (10) 스크립트가 종료되면 루아 스테이터스를 소멸 시킵니다.
 

8 수행 예

 

 다음은 보드에서 수행한 예 입니다.
 
 [root@falinux nfs]$ ./lua
 SLUA>>print "youngchang is genius!"
 youngchang is genius!
 SLUA>>os.exit(1);
 [root@falinux nfs]$