編譯luacheck Linux版


  最近在寫Visual Studio Code的Lua插件,需要把luacheck集成進去。但是luacheck默認只提供了win32版本,見https://github.com/mpeterv/luacheck/releases,但我的插件不可能只跑在win下啊。看了下README,沒有提到編譯的方法。搜索了一下,發現競然也沒有任何博客、文章提到如何在Linux下編譯,只能自己研究。把源碼clone下來,發現luacheck是純Lua寫的,那win32版本的luacheck.exe是如何來的?最后在build目錄里找到一個makefile:

# Makefile for (cross)compiling luacheck binaries.
# Do not use directly, run scripts/build-binaries.sh instead.

LUA_VERSION= 5.3.5
LFS_VERSION= 1.7.0-2
ARGPARSE_VERSION= 0.6.0-1
LANES_VERSION= 3.10.1-1

LUA_DIR= lua-$(LUA_VERSION)
LFS_DIR= luafilesystem-$(LFS_VERSION)/luafilesystem
ARGPARSE_DIR= argparse-$(ARGPARSE_VERSION)/argparse
LANES_DIR= lanes-$(LANES_VERSION)/lanes

BASE_CC= gcc
BASE_AR= ar rc
BASE_RANLIB= ranlib
BASE_STRIP= strip

CROSS=
CC= $(CROSS)$(BASE_CC)
CFLAGS= -O2 -Wall -Wextra
AR= $(CROSS)$(BASE_AR)
RANLIB= $(CROSS)$(BASE_RANLIB)
STRIP= $(CROSS)$(BASE_STRIP)

SUFFIX=
TARGET= bin/luacheck$(SUFFIX)

LUA_O= $(patsubst %.c,%.o,$(filter-out $(addprefix $(LUA_DIR)/src/,lua.c luac.c print.c),$(wildcard $(LUA_DIR)/src/*.c)))
LUA_A= $(LUA_DIR)/src/liblua.a
LFS_O= $(patsubst %.c,%.o,$(wildcard $(LFS_DIR)/src/*.c))
LFS_A= $(LFS_DIR)/src/lfs.a
LANES_O= $(patsubst %.c,%.o,$(wildcard $(LANES_DIR)/src/*.c))
LANES_A= $(LANES_DIR)/src/lanes.a

default:	$(TARGET)

$(LUA_DIR):
	@echo
	@echo "=== Downloading Lua $(LUA_VERSION) ==="
	@echo
	curl "https://www.lua.org/ftp/$(LUA_DIR).tar.gz" | tar xz

$(LFS_DIR):
	@echo
	@echo "=== Downloading LuaFileSystem $(LFS_VERSION) ==="
	@echo
	luarocks unpack luafilesystem $(LFS_VERSION)

$(ARGPARSE_DIR):
	@echo
	@echo "=== Downloading argparse $(ARGPARSE_VERSION) ==="
	@echo
	luarocks unpack argparse $(ARGPARSE_VERSION)

$(LANES_DIR):
	@echo
	@echo "=== Downloading Lanes $(LANES_VERSION) ==="
	@echo
	luarocks unpack lanes $(LANES_VERSION)

fetch:	$(LUA_DIR) $(LFS_DIR) $(ARGPARSE_DIR) $(LANES_DIR)

$(LUA_O):	CFLAGS+= $(if $(LINUX),-DLUA_USE_POSIX)
$(LUA_A):	$(LUA_O)
$(LFS_O):	CFLAGS+= -I$(LUA_DIR)/src
$(LFS_A):	$(LFS_O)
$(LANES_O):	CFLAGS+= -I$(LUA_DIR)/src
$(LANES_A):	$(LANES_O)

%.a:
	$(AR) $@ $^
	$(RANLIB) $@

bin/luacheck.lua.c: $(LUA_A) $(LFS_A) $(LANES_A)
	cp $(LUA_A) .
	cp $(LFS_A) .
	cp $(ARGPARSE_DIR)/src/argparse.lua .
	cp $(LANES_A) .
	cp $(LANES_DIR)/src/lanes.lua .
	cp -r ../src/luacheck .
	CC="" luastatic bin/luacheck.lua luacheck/*.lua luacheck/*/*.lua luacheck/*/*/*.lua argparse.lua lanes.lua liblua.a lfs.a lanes.a

$(TARGET):	bin/luacheck.lua.c
	$(CC) $(if $(LINUX),-static) -Os $< $(LUA_A) $(LFS_A) $(LANES_A) -I$(LUA_DIR)/src -lm $(if $(LINUX),-lpthread) -o $@
	$(STRIP) $@

clean:
	rm -f $(TARGET) bin/luacheck.lua.c
	rm -f $(LUA_O) $(LUA_A) $(LFS_O) $(LFS_A) $(LANES_O) $(LANES_A)
	rm -f argparse.lua lanes.lua liblua.a lfs.a lanes.a
	rm -rf luacheck

.PHONY: default fetch clean

這個就挺好理解了,先用curl下載依賴(lua 5.3.5等),然后把相關的依賴都編譯成靜態庫(liblua.a、lfs.a、lanes.a等),最后用luastatic把Lua代碼和這些靜態庫混合編譯成一個獨立的可運行文件即可。

根據注釋,找到scripts目錄下的build-binaries.sh腳本,嘗試幾次,就得出了編譯的步驟:

apt install luarocks
luarocks install luastatic
git clone https://github.com/mpeterv/luacheck.git
cd luacheck
./scripts/build-binaries.sh

注意一下,luacheck支持下面幾個平台的編譯:

build "Linux x86-64" LINUX=1
build "Linux x86" LINUX=1 "BASE_CC=gcc -m32" SUFFIX=32
build "Windows x86-64" CROSS=x86_64-w64-mingw32- SUFFIX=.exe
build "Windows x86" CROSS=i686-w64-mingw32- SUFFIX=32.exe

但是必須得安裝對應的編譯器才能編譯,比如在debian9 x64下,只能編譯Linux x86-64,如果想要編譯Linux x86,但要安裝32位庫才能編譯:

apt install gcc-multilib
apt install g++-multilib

如果是在win下,則需要安裝mingw才能編譯。MacOS應該是和Linux一樣,能直接用GCC編譯,不過我沒有mac,測試不了。

編譯生成的文件在build/bin目錄下,是一個獨立的可運行文件。由於是靜態編譯,可以在不同的Linux版本上運行,至少我測試在Debian9和Ubuntu 14.04上是可以的。現在可以把獨立的luacheck集成到插件里去了。

 

PS:我之前一直不知道有luastatic這個工具可以把Lua編譯成獨立的可運行文件,以后有時間看下是什么原理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM