🐖

LuaをCMakeでビルド(Visual Studio 2019)

15 min read

はじめに

LuaCMakeでビルドしてみます。
環境はMicrosoft Visual Studio Community 2019を使用します。

バージョンは以下。

Microsoft Visual Studio Community 2019
Version 16.10.3
VisualStudio.16.Release/16.10.3+31424.327
Microsoft .NET Framework
Version 4.8.04084

Luaのバージョンは現時点で最新の5.4.3を使用します。

ここでは、luaインタプリタのexeファイルを作成するまでを目標とします。

プロジェクトの作成

プロジェクトの新規作成からCMakeプロジェクトを選択します。

プロジェクト名はCMakeluaとしました。

作成すると、以下のようなフォルダ、ファイルが作成されます。

>tree /F
フォルダー パスの一覧:  ボリューム Windows
ボリューム シリアル番号は 0281-3DE0 です
C:.
│  CMakeLists.txt
│
├─CMakelua
│      CMakeLists.txt
│      CMakelua.cpp
│      CMakelua.h
│
└─out
    └─build
        └─x64-Debug

ここにLuaのコードを置いてCMakeLists.txtを修正していきます。

*.c, *.h をコピー

https://www.lua.org/ftp/lua-5.4.3.tar.gzを展開して
srcフォルダにある以下の*.c, *.hを
先程作成したプロジェクトのCMakelua\CMakeluaにコピーします。

>dir /B *.c *.h
lapi.c
lauxlib.c
lbaselib.c
lcode.c
lcorolib.c
lctype.c
ldblib.c
ldebug.c
ldo.c
ldump.c
lfunc.c
lgc.c
linit.c
liolib.c
llex.c
lmathlib.c
lmem.c
loadlib.c
lobject.c
lopcodes.c
loslib.c
lparser.c
lstate.c
lstring.c
lstrlib.c
ltable.c
ltablib.c
ltm.c
lua.c
luac.c
lundump.c
lutf8lib.c
lvm.c
lzio.c
lapi.h
lauxlib.h
lcode.h
lctype.h
ldebug.h
ldo.h
lfunc.h
lgc.h
ljumptab.h
llex.h
llimits.h
lmem.h
lobject.h
lopcodes.h
lopnames.h
lparser.h
lprefix.h
lstate.h
lstring.h
ltable.h
ltm.h
lua.h
luaconf.h
lualib.h
lundump.h
lvm.h
lzio.h

コピー後は以下のようになります。

>tree /F
フォルダー パスの一覧:  ボリューム Windows
ボリューム シリアル番号は 0281-3DE0 です
C:.
│  CMakeLists.txt
│
├─CMakelua
│      CMakeLists.txt
│      CMakelua.cpp
│      CMakelua.h
│      lapi.c
│      lapi.h
│      lauxlib.c
│      lauxlib.h
.....省略
│      lzio.c
│      lzio.h
│      Makefile
│
└─out
    └─build

Makefileの内容をCMakeLists.txtに書き直す

src\Makefile を見ると、以下のような記載があります。

src\Makefile

CORE_O=	lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o
LIB_O=	lauxlib.o lbaselib.o lcorolib.o ldblib.o liolib.o lmathlib.o loadlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o linit.o
BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)

LUA_T=	lua
LUA_O=	lua.o

LUAC_T=	luac
LUAC_O=	luac.o

ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
ALL_A= $(LUA_A)

<省略>

o:	$(ALL_O)

<省略>
# DO NOT DELETE

lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
 lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
 ltable.h lundump.h lvm.h
<省略>
lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
 llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
 ltable.h lvm.h ljumptab.h
lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
 lobject.h ltm.h lzio.h

ざっくり説明すると、luaのビルドの流れは以下のようになっています。

graph TD
    id1([コンパイルを行い*.oファイルを作成])
    id2([*.oファイルをリンクしluaインタプリタを作成])
    
    id1 --> id2

まず、src\Makefile内で行っていたlapi.oなどを作成するようにします。

src\Makefileの以下のような記載がありますが

lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
 lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
 ltable.h lundump.h lvm.h

これををCMakeでは

add_library(lapi STATIC lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h lvm.h)

のように書いてみました。
add_libraryを使用します。全部書くと以下のようになります。

CMakelua\CMakeLists.txt
add_library(lapi STATIC lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h lvm.h)
add_library(lauxlib STATIC lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h)
add_library(lbaselib STATIC lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lcode STATIC lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h lstring.h ltable.h lvm.h)
add_library(lcorolib STATIC lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lctype STATIC lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h)
add_library(ldblib STATIC ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(ldebug STATIC ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h)
add_library(ldo STATIC ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h ltable.h lundump.h lvm.h)
add_library(ldump STATIC ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h lmem.h lundump.h)
add_library(lfunc STATIC lfunc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h)
add_library(lgc STATIC lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h)
add_library(linit STATIC linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h)
add_library(liolib STATIC liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(llex STATIC llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h lstring.h ltable.h)
add_library(lmathlib STATIC lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lmem STATIC lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h)
add_library(loadlib STATIC loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lobject STATIC lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h)
add_library(lopcodes STATIC lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h)
add_library(loslib STATIC loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lparser STATIC lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h lstring.h lgc.h ltable.h)
add_library(lstate STATIC lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h)
add_library(lstring STATIC lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h)
add_library(lstrlib STATIC lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(ltable STATIC ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h)
add_library(ltablib STATIC ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(ltm STATIC ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h)
add_library(lua STATIC lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(luac STATIC luac.c lprefix.h lua.h luaconf.h lauxlib.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h lopcodes.h lopnames.h lundump.h)
add_library(lundump STATIC lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h)
add_library(lutf8lib STATIC lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lvm STATIC lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h ljumptab.h)
add_library(lzio STATIC lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h lzio.h)

リンク

リンクして、exeファイルを作成します。
以下のように記載してみました。
exeファイル名はwinluaとしました。

add_executable(winlua "lua.c")
target_link_libraries(winlua lua lapi lcode lctype ldebug ldo ldump lfunc lgc llex lmem lobject lopcodes lparser lstate lstring ltable ltm lundump lvm lzio lauxlib lbaselib lcorolib ldblib liolib lmathlib loadlib loslib lstrlib ltablib lutf8lib linit)

add_executabletarget_link_librariesを使用します。

ビルド、実行

winlua.exeを選択して、ビルド、実行(以下の緑色の三角)を押しビルドを行います。

実行できました。

ちゃんと動いているようです。

Lua 5.4.3  Copyright (C) 1994-2021 Lua.org, PUC-Rio
> for i = 1, 5 do print("hello") end
hello
hello
hello
hello
hello
>

CMakelua\CMakeLists.txt全体

CMakelua\CMakeLists.txtの中身は以下のようになりました。

CMakelua\CMakeLists.txt
# CMakeList.txt : CMakeProject1lua の CMake プロジェクト。ソースを含めて、次を定義します:
# プロジェクト専用ロジックはこちらです。
#
cmake_minimum_required (VERSION 3.8)

# ソースをこのプロジェクトの実行可能ファイルに追加します。
add_executable(winlua "lua.c")
target_link_libraries(winlua lua lapi lcode lctype ldebug ldo ldump lfunc lgc llex lmem lobject lopcodes lparser lstate lstring ltable ltm lundump lvm lzio lauxlib lbaselib lcorolib ldblib liolib lmathlib loadlib loslib lstrlib ltablib lutf8lib linit)

# TODO: テストを追加し、必要な場合は、ターゲットをインストールします。
add_library(lapi STATIC lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h lvm.h)
add_library(lauxlib STATIC lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h)
add_library(lbaselib STATIC lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lcode STATIC lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h lstring.h ltable.h lvm.h)
add_library(lcorolib STATIC lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lctype STATIC lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h)
add_library(ldblib STATIC ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(ldebug STATIC ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h)
add_library(ldo STATIC ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h ltable.h lundump.h lvm.h)
add_library(ldump STATIC ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h lmem.h lundump.h)
add_library(lfunc STATIC lfunc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h)
add_library(lgc STATIC lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h)
add_library(linit STATIC linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h)
add_library(liolib STATIC liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(llex STATIC llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h lstring.h ltable.h)
add_library(lmathlib STATIC lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lmem STATIC lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h)
add_library(loadlib STATIC loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lobject STATIC lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h)
add_library(lopcodes STATIC lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h)
add_library(loslib STATIC loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lparser STATIC lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h lstring.h lgc.h ltable.h)
add_library(lstate STATIC lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h)
add_library(lstring STATIC lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h)
add_library(lstrlib STATIC lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(ltable STATIC ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h)
add_library(ltablib STATIC ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(ltm STATIC ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h)
add_library(lua STATIC lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(luac STATIC luac.c lprefix.h lua.h luaconf.h lauxlib.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h lopcodes.h lopnames.h lundump.h)
add_library(lundump STATIC lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h)
add_library(lutf8lib STATIC lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h)
add_library(lvm STATIC lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h ljumptab.h)
add_library(lzio STATIC lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h lzio.h)

まとめ

ここではluaインタプリタのビルド、実行までを行ってみました。
luaをライブラリとして、他のプログラムにリンク、ということも
今度やってみたいと思います。

Discussion

ログインするとコメントできます