aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2025-03-04 01:44:19 -0300
committerHisham Muhammad <hisham@gobolinux.org>2025-03-10 10:51:04 -0300
commit9e162d9e980f7e17c0ea41e0cd29173d01ada330 (patch)
tree8e27b578738537d75031351892edd07b98656ccc
parentf9a8ac22881533281673a2abd59f4fd69feeaa00 (diff)
downloadluarocks-9e162d9e980f7e17c0ea41e0cd29173d01ada330.tar.gz
luarocks-9e162d9e980f7e17c0ea41e0cd29173d01ada330.tar.bz2
luarocks-9e162d9e980f7e17c0ea41e0cd29173d01ada330.zip
[wip] Makefile bootstrap script
-rw-r--r--.gitignore1
-rw-r--r--GNUmakefile203
-rw-r--r--Makefile.vendor147
-rwxr-xr-xbootstrap.tl518
-rw-r--r--src/main.c160
5 files changed, 839 insertions, 190 deletions
diff --git a/.gitignore b/.gitignore
index 35ddbf42..3317a870 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,6 @@
8/*.rock 8/*.rock
9/*.tar.gz 9/*.tar.gz
10/*.zip 10/*.zip
11/src/*.*
12/prefix-* 11/prefix-*
13/dev_* 12/dev_*
14/gh-pages 13/gh-pages
diff --git a/GNUmakefile b/GNUmakefile
index 46be0cc6..cb0f72dd 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,197 +1,22 @@
1MAKEFLAGS += --jobs=1
2 1
3-include config.unix 2CC = gcc
3MKDIR = mkdir
4MYLIBS = -llua -lz -lbz2 -lssl -lcrypto
4 5
5datarootdir = $(prefix)/share 6ZLIB_INCDIR = /usr/include
6bindir = $(prefix)/bin 7BZ2_INCDIR = /usr/include
7INSTALL = install 8OPENSSL_INCDIR = /usr/include
8INSTALL_DATA = $(INSTALL) -m 644
9BINARY_PLATFORM = unix
10 9
11SHEBANG = \#!$(LUA) 10all: luarocks
12luarocksconfdir = $(sysconfdir)/luarocks
13luadir = $(datarootdir)/lua/$(LUA_VERSION)
14builddir = ./build
15buildbinarydir = ./build-binary
16 11
17LUAROCKS_FILES = $(shell find src/luarocks/ -type f -name '*.lua') 12-include Makefile.vendor
18 13
19LUA_ENV_VARS = LUA_PATH LUA_PATH_5_2 LUA_PATH_5_3 LUA_PATH_5_4 LUA_CPATH LUA_CPATH_5_2 LUA_CPATH_5_3 LUA_CPATH_5_4 14luarocks: src/main.c gen/gen.h gen/libraries.h gen/main.h $(VENDOR_LIBS)
15 $(CC) -o luarocks $(MYLIBS) -I. src/main.c $(VENDOR_LIBS)
20 16
21all: build 17clean:
18 rm -rf gen target
22 19
23# ---------------------------------------- 20gen: clean
24# Base build 21 ./bootstrap.tl
25# ----------------------------------------
26 22
27build: config.unix $(builddir)/config-$(LUA_VERSION).lua $(builddir)/luarocks $(builddir)/luarocks-admin
28
29config.unix:
30 @echo Please run the "./configure" script before building.
31 @echo
32 @exit 1
33
34$(builddir)/config-$(LUA_VERSION).lua: config.unix
35 mkdir -p "$(@D)"
36 @printf -- '-- LuaRocks configuration\n\n'\
37 'rocks_trees = {\n'\
38 ' { name = "user", root = home .. "/.luarocks" };\n'\
39 "$$([ "$(rocks_tree)" != "$(HOME)/.luarocks" ] && printf ' { name = "system", root = "'"$(rocks_tree)"'" };\\n')"\
40 '}\n'\
41 'variables = {\n'\
42 "$$([ -n "$(LUA_DIR)" ] && printf ' LUA_DIR = "%s";\\n' "$(LUA_DIR)")"\
43 "$$([ -n "$(LUA_INCDIR)" ] && printf ' LUA_INCDIR = "%s";\\n' "$(LUA_INCDIR)")"\
44 "$$([ -n "$(LUA_BINDIR)" ] && printf ' LUA_BINDIR = "%s";\\n' "$(LUA_BINDIR)")"\
45 "$$([ -n "$(LUA_LIBDIR)" ] && printf ' LUA_LIBDIR = "%s";\\n' "$(LUA_LIBDIR)")"\
46 "$$([ -n "$(LUA_VERSION)" ] && printf ' LUA_VERSION = "%s";\\n' "$(LUA_VERSION)")"\
47 "$$([ -n "$(LUA)" ] && printf ' LUA = "%s";\\n' "$(LUA)")"\
48 '}\n'\
49 > $@
50
51luarocks: config.unix $(builddir)/config-$(LUA_VERSION).lua
52 mkdir -p .luarocks
53 cp $(builddir)/config-$(LUA_VERSION).lua .luarocks/config-$(LUA_VERSION).lua
54 rm -f src/luarocks/core/hardcoded.lua
55 echo "#!/bin/sh" > luarocks
56 echo "unset $(LUA_ENV_VARS)" >> luarocks
57 echo 'LUAROCKS_SYSCONFDIR="$(luarocksconfdir)" LUA_PATH="$(CURDIR)/src/?.lua;;" exec "$(LUA)" "$(CURDIR)/src/bin/luarocks" --project-tree="$(CURDIR)/lua_modules" "$$@"' >> luarocks
58 chmod +rx ./luarocks
59 ./luarocks init
60
61luarocks-admin: config.unix
62 rm -f src/luarocks/core/hardcoded.lua
63 echo "#!/bin/sh" > luarocks-admin
64 echo "unset $(LUA_ENV_VARS)" >> luarocks-admin
65 echo 'LUAROCKS_SYSCONFDIR="$(luarocksconfdir)" LUA_PATH="$(CURDIR)/src/?.lua;;" exec "$(LUA)" "$(CURDIR)/src/bin/luarocks-admin" --project-tree="$(CURDIR)/lua_modules" "$$@"' >> luarocks-admin
66 chmod +rx ./luarocks-admin
67
68$(builddir)/luarocks: src/bin/luarocks config.unix
69 mkdir -p "$(@D)"
70 (printf '$(SHEBANG)\n'\
71 'package.loaded["luarocks.core.hardcoded"] = { '\
72 "$$([ -n "$(FORCE_CONFIG)" ] && printf 'FORCE_CONFIG = true, ')"\
73 'SYSCONFDIR = [[$(luarocksconfdir)]] }\n'\
74 'package.path=[[$(luadir)/?.lua;]] .. package.path\n'\
75 'local list = package.searchers or package.loaders; table.insert(list, 1, function(name) if name:match("^luarocks%%.") then return loadfile([[$(luadir)/]] .. name:gsub([[%%.]], [[/]]) .. [[.lua]]) end end)\n'; \
76 tail -n +2 src/bin/luarocks \
77 )> "$@"
78
79$(builddir)/luarocks-admin: src/bin/luarocks-admin config.unix
80 mkdir -p "$(@D)"
81 (printf '$(SHEBANG)\n'\
82 'package.loaded["luarocks.core.hardcoded"] = { '\
83 "$$([ -n "$(FORCE_CONFIG)" ] && printf 'FORCE_CONFIG = true, ')"\
84 'SYSCONFDIR = [[$(luarocksconfdir)]] }\n'\
85 'package.path=[[$(luadir)/?.lua;]] .. package.path\n'\
86 'local list = package.searchers or package.loaders; table.insert(list, 1, function(name) if name:match("^luarocks%%.") then return loadfile([[$(luadir)/]] .. name:gsub([[%%.]], [[/]]) .. [[.lua]]) end end)\n'; \
87 tail -n +2 src/bin/luarocks-admin \
88 )> "$@"
89
90# ----------------------------------------
91# Base build
92# ----------------------------------------
93
94binary: luarocks $(buildbinarydir)/luarocks.exe $(buildbinarydir)/luarocks-admin.exe
95
96$(buildbinarydir)/luarocks.exe: src/bin/luarocks $(LUAROCKS_FILES)
97 (unset $(LUA_ENV_VARS); \
98 "$(LUA)" binary/all_in_one "$<" "$(LUA_DIR)" "^src/luarocks/admin/" "$(luarocksconfdir)" "$(@D)" "$(FORCE_CONFIG)" $(BINARY_PLATFORM) $(CC) $(NM) $(BINARY_SYSROOT))
99
100$(buildbinarydir)/luarocks-admin.exe: src/bin/luarocks-admin $(LUAROCKS_FILES)
101 (unset $(LUA_ENV_VARS); \
102 "$(LUA)" binary/all_in_one "$<" "$(LUA_DIR)" "^src/luarocks/cmd/" "$(luarocksconfdir)" "$(@D)" "$(FORCE_CONFIG)" $(BINARY_PLATFORM) $(CC) $(NM) $(BINARY_SYSROOT))
103
104# ----------------------------------------
105# Regular install
106# ----------------------------------------
107
108INSTALL_FILES =
109
110install: all install-config
111 mkdir -p '$(DESTDIR)$(bindir)/'
112 $(INSTALL) '$(builddir)/luarocks' '$(DESTDIR)$(bindir)/luarocks'
113 $(INSTALL) '$(builddir)/luarocks-admin' '$(DESTDIR)$(bindir)/luarocks-admin'
114 find src/luarocks/ -type d | while read f; \
115 do \
116 mkdir -p '$(DESTDIR)$(luadir)'/`echo $$f | sed 's,^src/,,'`; \
117 done
118 find src/luarocks/ -type f -name '*.lua' | while read f; \
119 do \
120 $(INSTALL_DATA) "$$f" '$(DESTDIR)$(luadir)'/`echo $$f | sed 's,^src/,,'`; \
121 done
122ifeq (,$(findstring $(LUA_VERSION),"5.3" "5.4"))
123 find src/compat53/ -type d | while read f; \
124 do \
125 mkdir -p '$(DESTDIR)$(luadir)'/`echo $$f | sed 's,^src/,,'`; \
126 done
127 find src/compat53/ -type f -name '*.lua' | while read f; \
128 do \
129 $(INSTALL_DATA) "$$f" '$(DESTDIR)$(luadir)'/`echo $$f | sed 's,^src/,,'`; \
130 done
131endif
132
133install-config:
134 mkdir -p '$(DESTDIR)$(luarocksconfdir)/'
135 $(INSTALL_DATA) '$(builddir)/config-$(LUA_VERSION).lua' '$(DESTDIR)$(luarocksconfdir)/config-$(LUA_VERSION).lua'
136
137uninstall:
138 rm -rf $(DESTDIR)$(bindir)/luarocks \
139 $(DESTDIR)$(bindir)/luarocks-admin \
140 $(DESTDIR)$(luarocksconfdir)/config-$(LUA_VERSION).lua \
141 $(patsubst src/%, $(DESTDIR)$(luadir)/%, $(LUAROCKS_FILES))
142
143# ----------------------------------------
144# Binary install
145# ----------------------------------------
146
147install-binary: binary install-config
148 mkdir -p '$(DESTDIR)$(bindir)/'
149 $(INSTALL) "$(buildbinarydir)/luarocks.exe" "$(DESTDIR)$(bindir)/luarocks"
150 $(INSTALL) "$(buildbinarydir)/luarocks-admin.exe" "$(DESTDIR)$(bindir)/luarocks-admin"
151 mkdir -p '$(DESTDIR)$(luadir)/luarocks/core'
152 for f in src/luarocks/core/*.lua src/luarocks/loader.lua; \
153 do \
154 $(INSTALL_DATA) "$$f" '$(DESTDIR)$(luadir)'/`echo $$f | sed 's,^src/,,'`; \
155 done
156
157# ----------------------------------------
158# Bootstrap install
159# ----------------------------------------
160
161bootstrap: luarocks install-config
162 ./luarocks make --tree="$(DESTDIR)$(rocks_tree)"
163
164# ----------------------------------------
165# Windows binary build
166# ----------------------------------------
167
168windows-binary: windows-binary-32 windows-binary-64
169
170windows-clean: windows-clean-32 windows-clean-64
171
172windows-binary-32: luarocks
173 $(MAKE) -f binary/Makefile.windows windows-binary MINGW_PREFIX=i686-w64-mingw32 OPENSSL_PLATFORM=mingw
174
175windows-clean-32:
176 $(MAKE) -f binary/Makefile.windows windows-clean MINGW_PREFIX=i686-w64-mingw32 OPENSSL_PLATFORM=mingw
177
178windows-binary-64: luarocks
179 $(MAKE) -f binary/Makefile.windows windows-binary MINGW_PREFIX=x86_64-w64-mingw32 OPENSSL_PLATFORM=mingw64
180
181windows-clean-64:
182 $(MAKE) -f binary/Makefile.windows windows-clean MINGW_PREFIX=x86_64-w64-mingw32 OPENSSL_PLATFORM=mingw64
183
184# ----------------------------------------
185# Clean
186# ----------------------------------------
187
188clean: windows-clean
189 rm -rf ./config.unix \
190 ./luarocks \
191 ./luarocks-admin \
192 $(builddir)/ \
193 $(buildbinarydir)/ \
194 ./.luarocks \
195 ./lua_modules
196
197.PHONY: all build install install-config binary install-binary bootstrap clean windows-binary windows-clean
diff --git a/Makefile.vendor b/Makefile.vendor
new file mode 100644
index 00000000..e6c3d2cf
--- /dev/null
+++ b/Makefile.vendor
@@ -0,0 +1,147 @@
1# automatically generated by bootstrap.tl
2
3VENDOR_LIBS = target/libraries/des56.a target/libraries/md5/core.a target/libraries/zlib.a target/libraries/bz2.a target/libraries/lfs.a target/libraries/mime/core.a target/libraries/socket/core.a target/libraries/socket/serial.a target/libraries/socket/unix.a target/libraries/ssl.a target/libraries/miniposix.a
4
5target/objects/md5/vendor/md5/src/compat-5.2.o: vendor/md5/src/compat-5.2.c | target/objects/md5/vendor/md5/src/
6 $(CC) -c -o target/objects/md5/vendor/md5/src/compat-5.2.o vendor/md5/src/compat-5.2.c -I vendor/md5/src/
7target/objects/md5/vendor/md5/src/des56.o: vendor/md5/src/des56.c | target/objects/md5/vendor/md5/src/
8 $(CC) -c -o target/objects/md5/vendor/md5/src/des56.o vendor/md5/src/des56.c -I vendor/md5/src/
9target/objects/md5/vendor/md5/src/ldes56.o: vendor/md5/src/ldes56.c | target/objects/md5/vendor/md5/src/
10 $(CC) -c -o target/objects/md5/vendor/md5/src/ldes56.o vendor/md5/src/ldes56.c -I vendor/md5/src/
11target/libraries/des56.a: target/objects/md5/vendor/md5/src/compat-5.2.o target/objects/md5/vendor/md5/src/des56.o target/objects/md5/vendor/md5/src/ldes56.o | target/libraries/
12 $(AR) rcu target/libraries/des56.a target/objects/md5/vendor/md5/src/compat-5.2.o target/objects/md5/vendor/md5/src/des56.o target/objects/md5/vendor/md5/src/ldes56.o
13
14target/objects/md5/vendor/md5/src/md5.o: vendor/md5/src/md5.c | target/objects/md5/vendor/md5/src/
15 $(CC) -c -o target/objects/md5/vendor/md5/src/md5.o vendor/md5/src/md5.c -I vendor/md5/src/
16target/objects/md5/vendor/md5/src/md5lib.o: vendor/md5/src/md5lib.c | target/objects/md5/vendor/md5/src/
17 $(CC) -c -o target/objects/md5/vendor/md5/src/md5lib.o vendor/md5/src/md5lib.c -I vendor/md5/src/
18target/libraries/md5/core.a: target/objects/md5/vendor/md5/src/compat-5.2.o target/objects/md5/vendor/md5/src/md5.o target/objects/md5/vendor/md5/src/md5lib.o | target/libraries/md5/
19 $(AR) rcu target/libraries/md5/core.a target/objects/md5/vendor/md5/src/compat-5.2.o target/objects/md5/vendor/md5/src/md5.o target/objects/md5/vendor/md5/src/md5lib.o
20
21target/objects/lua-zlib/vendor/lua-zlib/lua_zlib.o: vendor/lua-zlib/lua_zlib.c | target/objects/lua-zlib/vendor/lua-zlib/
22 $(CC) -c -o target/objects/lua-zlib/vendor/lua-zlib/lua_zlib.o vendor/lua-zlib/lua_zlib.c -I vendor/lua-zlib/$(ZLIB_INCDIR) -D LZLIB_COMPAT
23target/libraries/zlib.a: target/objects/lua-zlib/vendor/lua-zlib/lua_zlib.o | target/libraries/
24 $(AR) rcu target/libraries/zlib.a target/objects/lua-zlib/vendor/lua-zlib/lua_zlib.o
25
26target/objects/lua-bz2/vendor/lua-bz2/lbz.o: vendor/lua-bz2/lbz.c | target/objects/lua-bz2/vendor/lua-bz2/
27 $(CC) -c -o target/objects/lua-bz2/vendor/lua-bz2/lbz.o vendor/lua-bz2/lbz.c -I vendor/lua-bz2/$(BZ2_INCDIR) -D COMPAT53_PREFIX=compat53
28target/objects/lua-bz2/vendor/lua-bz2/lbz2_common.o: vendor/lua-bz2/lbz2_common.c | target/objects/lua-bz2/vendor/lua-bz2/
29 $(CC) -c -o target/objects/lua-bz2/vendor/lua-bz2/lbz2_common.o vendor/lua-bz2/lbz2_common.c -I vendor/lua-bz2/$(BZ2_INCDIR) -D COMPAT53_PREFIX=compat53
30target/objects/lua-bz2/vendor/lua-bz2/lbz2_file_reader.o: vendor/lua-bz2/lbz2_file_reader.c | target/objects/lua-bz2/vendor/lua-bz2/
31 $(CC) -c -o target/objects/lua-bz2/vendor/lua-bz2/lbz2_file_reader.o vendor/lua-bz2/lbz2_file_reader.c -I vendor/lua-bz2/$(BZ2_INCDIR) -D COMPAT53_PREFIX=compat53
32target/objects/lua-bz2/vendor/lua-bz2/lbz2_file_writer.o: vendor/lua-bz2/lbz2_file_writer.c | target/objects/lua-bz2/vendor/lua-bz2/
33 $(CC) -c -o target/objects/lua-bz2/vendor/lua-bz2/lbz2_file_writer.o vendor/lua-bz2/lbz2_file_writer.c -I vendor/lua-bz2/$(BZ2_INCDIR) -D COMPAT53_PREFIX=compat53
34target/objects/lua-bz2/vendor/lua-bz2/lbz2_stream.o: vendor/lua-bz2/lbz2_stream.c | target/objects/lua-bz2/vendor/lua-bz2/
35 $(CC) -c -o target/objects/lua-bz2/vendor/lua-bz2/lbz2_stream.o vendor/lua-bz2/lbz2_stream.c -I vendor/lua-bz2/$(BZ2_INCDIR) -D COMPAT53_PREFIX=compat53
36target/objects/lua-bz2/vendor/lua-bz2/compat-5.3.o: vendor/lua-bz2/compat-5.3.c | target/objects/lua-bz2/vendor/lua-bz2/
37 $(CC) -c -o target/objects/lua-bz2/vendor/lua-bz2/compat-5.3.o vendor/lua-bz2/compat-5.3.c -I vendor/lua-bz2/$(BZ2_INCDIR) -D COMPAT53_PREFIX=compat53
38target/libraries/bz2.a: target/objects/lua-bz2/vendor/lua-bz2/lbz.o target/objects/lua-bz2/vendor/lua-bz2/lbz2_common.o target/objects/lua-bz2/vendor/lua-bz2/lbz2_file_reader.o target/objects/lua-bz2/vendor/lua-bz2/lbz2_file_writer.o target/objects/lua-bz2/vendor/lua-bz2/lbz2_stream.o target/objects/lua-bz2/vendor/lua-bz2/compat-5.3.o | target/libraries/
39 $(AR) rcu target/libraries/bz2.a target/objects/lua-bz2/vendor/lua-bz2/lbz.o target/objects/lua-bz2/vendor/lua-bz2/lbz2_common.o target/objects/lua-bz2/vendor/lua-bz2/lbz2_file_reader.o target/objects/lua-bz2/vendor/lua-bz2/lbz2_file_writer.o target/objects/lua-bz2/vendor/lua-bz2/lbz2_stream.o target/objects/lua-bz2/vendor/lua-bz2/compat-5.3.o
40
41target/objects/luafilesystem/vendor/luafilesystem/src/lfs.o: vendor/luafilesystem/src/lfs.c | target/objects/luafilesystem/vendor/luafilesystem/src/
42 $(CC) -c -o target/objects/luafilesystem/vendor/luafilesystem/src/lfs.o vendor/luafilesystem/src/lfs.c
43target/libraries/lfs.a: target/objects/luafilesystem/vendor/luafilesystem/src/lfs.o | target/libraries/
44 $(AR) rcu target/libraries/lfs.a target/objects/luafilesystem/vendor/luafilesystem/src/lfs.o
45
46target/objects/luasocket/vendor/luasocket/src/mime.o: vendor/luasocket/src/mime.c | target/objects/luasocket/vendor/luasocket/src/
47 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/mime.o vendor/luasocket/src/mime.c -D LUASOCKET_DEBUG
48target/objects/luasocket/vendor/luasocket/src/compat.o: vendor/luasocket/src/compat.c | target/objects/luasocket/vendor/luasocket/src/
49 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/compat.o vendor/luasocket/src/compat.c -D LUASOCKET_DEBUG
50target/libraries/mime/core.a: target/objects/luasocket/vendor/luasocket/src/mime.o target/objects/luasocket/vendor/luasocket/src/compat.o | target/libraries/mime/
51 $(AR) rcu target/libraries/mime/core.a target/objects/luasocket/vendor/luasocket/src/mime.o target/objects/luasocket/vendor/luasocket/src/compat.o
52
53target/objects/luasocket/vendor/luasocket/src/luasocket.o: vendor/luasocket/src/luasocket.c | target/objects/luasocket/vendor/luasocket/src/
54 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/luasocket.o vendor/luasocket/src/luasocket.c -D LUASOCKET_DEBUG
55target/objects/luasocket/vendor/luasocket/src/timeout.o: vendor/luasocket/src/timeout.c | target/objects/luasocket/vendor/luasocket/src/
56 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/timeout.o vendor/luasocket/src/timeout.c -D LUASOCKET_DEBUG
57target/objects/luasocket/vendor/luasocket/src/buffer.o: vendor/luasocket/src/buffer.c | target/objects/luasocket/vendor/luasocket/src/
58 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/buffer.o vendor/luasocket/src/buffer.c -D LUASOCKET_DEBUG
59target/objects/luasocket/vendor/luasocket/src/io.o: vendor/luasocket/src/io.c | target/objects/luasocket/vendor/luasocket/src/
60 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/io.o vendor/luasocket/src/io.c -D LUASOCKET_DEBUG
61target/objects/luasocket/vendor/luasocket/src/auxiliar.o: vendor/luasocket/src/auxiliar.c | target/objects/luasocket/vendor/luasocket/src/
62 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/auxiliar.o vendor/luasocket/src/auxiliar.c -D LUASOCKET_DEBUG
63target/objects/luasocket/vendor/luasocket/src/options.o: vendor/luasocket/src/options.c | target/objects/luasocket/vendor/luasocket/src/
64 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/options.o vendor/luasocket/src/options.c -D LUASOCKET_DEBUG
65target/objects/luasocket/vendor/luasocket/src/inet.o: vendor/luasocket/src/inet.c | target/objects/luasocket/vendor/luasocket/src/
66 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/inet.o vendor/luasocket/src/inet.c -D LUASOCKET_DEBUG
67target/objects/luasocket/vendor/luasocket/src/except.o: vendor/luasocket/src/except.c | target/objects/luasocket/vendor/luasocket/src/
68 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/except.o vendor/luasocket/src/except.c -D LUASOCKET_DEBUG
69target/objects/luasocket/vendor/luasocket/src/select.o: vendor/luasocket/src/select.c | target/objects/luasocket/vendor/luasocket/src/
70 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/select.o vendor/luasocket/src/select.c -D LUASOCKET_DEBUG
71target/objects/luasocket/vendor/luasocket/src/tcp.o: vendor/luasocket/src/tcp.c | target/objects/luasocket/vendor/luasocket/src/
72 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/tcp.o vendor/luasocket/src/tcp.c -D LUASOCKET_DEBUG
73target/objects/luasocket/vendor/luasocket/src/udp.o: vendor/luasocket/src/udp.c | target/objects/luasocket/vendor/luasocket/src/
74 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/udp.o vendor/luasocket/src/udp.c -D LUASOCKET_DEBUG
75target/objects/luasocket/vendor/luasocket/src/usocket.o: vendor/luasocket/src/usocket.c | target/objects/luasocket/vendor/luasocket/src/
76 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/usocket.o vendor/luasocket/src/usocket.c -D LUASOCKET_DEBUG
77target/libraries/socket/core.a: target/objects/luasocket/vendor/luasocket/src/luasocket.o target/objects/luasocket/vendor/luasocket/src/timeout.o target/objects/luasocket/vendor/luasocket/src/buffer.o target/objects/luasocket/vendor/luasocket/src/io.o target/objects/luasocket/vendor/luasocket/src/auxiliar.o target/objects/luasocket/vendor/luasocket/src/options.o target/objects/luasocket/vendor/luasocket/src/inet.o target/objects/luasocket/vendor/luasocket/src/except.o target/objects/luasocket/vendor/luasocket/src/select.o target/objects/luasocket/vendor/luasocket/src/tcp.o target/objects/luasocket/vendor/luasocket/src/udp.o target/objects/luasocket/vendor/luasocket/src/compat.o target/objects/luasocket/vendor/luasocket/src/usocket.o | target/libraries/socket/
78 $(AR) rcu target/libraries/socket/core.a target/objects/luasocket/vendor/luasocket/src/luasocket.o target/objects/luasocket/vendor/luasocket/src/timeout.o target/objects/luasocket/vendor/luasocket/src/buffer.o target/objects/luasocket/vendor/luasocket/src/io.o target/objects/luasocket/vendor/luasocket/src/auxiliar.o target/objects/luasocket/vendor/luasocket/src/options.o target/objects/luasocket/vendor/luasocket/src/inet.o target/objects/luasocket/vendor/luasocket/src/except.o target/objects/luasocket/vendor/luasocket/src/select.o target/objects/luasocket/vendor/luasocket/src/tcp.o target/objects/luasocket/vendor/luasocket/src/udp.o target/objects/luasocket/vendor/luasocket/src/compat.o target/objects/luasocket/vendor/luasocket/src/usocket.o
79
80target/objects/luasocket/vendor/luasocket/src/serial.o: vendor/luasocket/src/serial.c | target/objects/luasocket/vendor/luasocket/src/
81 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/serial.o vendor/luasocket/src/serial.c -D LUASOCKET_DEBUG
82target/libraries/socket/serial.a: target/objects/luasocket/vendor/luasocket/src/buffer.o target/objects/luasocket/vendor/luasocket/src/compat.o target/objects/luasocket/vendor/luasocket/src/auxiliar.o target/objects/luasocket/vendor/luasocket/src/options.o target/objects/luasocket/vendor/luasocket/src/timeout.o target/objects/luasocket/vendor/luasocket/src/io.o target/objects/luasocket/vendor/luasocket/src/usocket.o target/objects/luasocket/vendor/luasocket/src/serial.o | target/libraries/socket/
83 $(AR) rcu target/libraries/socket/serial.a target/objects/luasocket/vendor/luasocket/src/buffer.o target/objects/luasocket/vendor/luasocket/src/compat.o target/objects/luasocket/vendor/luasocket/src/auxiliar.o target/objects/luasocket/vendor/luasocket/src/options.o target/objects/luasocket/vendor/luasocket/src/timeout.o target/objects/luasocket/vendor/luasocket/src/io.o target/objects/luasocket/vendor/luasocket/src/usocket.o target/objects/luasocket/vendor/luasocket/src/serial.o
84
85target/objects/luasocket/vendor/luasocket/src/unix.o: vendor/luasocket/src/unix.c | target/objects/luasocket/vendor/luasocket/src/
86 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/unix.o vendor/luasocket/src/unix.c -D LUASOCKET_DEBUG
87target/objects/luasocket/vendor/luasocket/src/unixdgram.o: vendor/luasocket/src/unixdgram.c | target/objects/luasocket/vendor/luasocket/src/
88 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/unixdgram.o vendor/luasocket/src/unixdgram.c -D LUASOCKET_DEBUG
89target/objects/luasocket/vendor/luasocket/src/unixstream.o: vendor/luasocket/src/unixstream.c | target/objects/luasocket/vendor/luasocket/src/
90 $(CC) -c -o target/objects/luasocket/vendor/luasocket/src/unixstream.o vendor/luasocket/src/unixstream.c -D LUASOCKET_DEBUG
91target/libraries/socket/unix.a: target/objects/luasocket/vendor/luasocket/src/buffer.o target/objects/luasocket/vendor/luasocket/src/compat.o target/objects/luasocket/vendor/luasocket/src/auxiliar.o target/objects/luasocket/vendor/luasocket/src/options.o target/objects/luasocket/vendor/luasocket/src/timeout.o target/objects/luasocket/vendor/luasocket/src/io.o target/objects/luasocket/vendor/luasocket/src/usocket.o target/objects/luasocket/vendor/luasocket/src/unix.o target/objects/luasocket/vendor/luasocket/src/unixdgram.o target/objects/luasocket/vendor/luasocket/src/unixstream.o | target/libraries/socket/
92 $(AR) rcu target/libraries/socket/unix.a target/objects/luasocket/vendor/luasocket/src/buffer.o target/objects/luasocket/vendor/luasocket/src/compat.o target/objects/luasocket/vendor/luasocket/src/auxiliar.o target/objects/luasocket/vendor/luasocket/src/options.o target/objects/luasocket/vendor/luasocket/src/timeout.o target/objects/luasocket/vendor/luasocket/src/io.o target/objects/luasocket/vendor/luasocket/src/usocket.o target/objects/luasocket/vendor/luasocket/src/unix.o target/objects/luasocket/vendor/luasocket/src/unixdgram.o target/objects/luasocket/vendor/luasocket/src/unixstream.o
93
94target/objects/luasec/vendor/luasec/src/options.o: vendor/luasec/src/options.c | target/objects/luasec/vendor/luasec/src/
95 $(CC) -c -o target/objects/luasec/vendor/luasec/src/options.o vendor/luasec/src/options.c -I vendor/luasec/$(OPENSSL_INCDIR) -I vendor/luasec/src/ -I vendor/luasec/src/luasocket -D WITH_LUASOCKET -D LUASOCKET_DEBUG
96target/objects/luasec/vendor/luasec/src/config.o: vendor/luasec/src/config.c | target/objects/luasec/vendor/luasec/src/
97 $(CC) -c -o target/objects/luasec/vendor/luasec/src/config.o vendor/luasec/src/config.c -I vendor/luasec/$(OPENSSL_INCDIR) -I vendor/luasec/src/ -I vendor/luasec/src/luasocket -D WITH_LUASOCKET -D LUASOCKET_DEBUG
98target/objects/luasec/vendor/luasec/src/ec.o: vendor/luasec/src/ec.c | target/objects/luasec/vendor/luasec/src/
99 $(CC) -c -o target/objects/luasec/vendor/luasec/src/ec.o vendor/luasec/src/ec.c -I vendor/luasec/$(OPENSSL_INCDIR) -I vendor/luasec/src/ -I vendor/luasec/src/luasocket -D WITH_LUASOCKET -D LUASOCKET_DEBUG
100target/objects/luasec/vendor/luasec/src/x509.o: vendor/luasec/src/x509.c | target/objects/luasec/vendor/luasec/src/
101 $(CC) -c -o target/objects/luasec/vendor/luasec/src/x509.o vendor/luasec/src/x509.c -I vendor/luasec/$(OPENSSL_INCDIR) -I vendor/luasec/src/ -I vendor/luasec/src/luasocket -D WITH_LUASOCKET -D LUASOCKET_DEBUG
102target/objects/luasec/vendor/luasec/src/context.o: vendor/luasec/src/context.c | target/objects/luasec/vendor/luasec/src/
103 $(CC) -c -o target/objects/luasec/vendor/luasec/src/context.o vendor/luasec/src/context.c -I vendor/luasec/$(OPENSSL_INCDIR) -I vendor/luasec/src/ -I vendor/luasec/src/luasocket -D WITH_LUASOCKET -D LUASOCKET_DEBUG
104target/objects/luasec/vendor/luasec/src/ssl.o: vendor/luasec/src/ssl.c | target/objects/luasec/vendor/luasec/src/
105 $(CC) -c -o target/objects/luasec/vendor/luasec/src/ssl.o vendor/luasec/src/ssl.c -I vendor/luasec/$(OPENSSL_INCDIR) -I vendor/luasec/src/ -I vendor/luasec/src/luasocket -D WITH_LUASOCKET -D LUASOCKET_DEBUG
106target/objects/luasec/vendor/luasec/src/luasocket/buffer.o: vendor/luasec/src/luasocket/buffer.c | target/objects/luasec/vendor/luasec/src/luasocket/
107 $(CC) -c -o target/objects/luasec/vendor/luasec/src/luasocket/buffer.o vendor/luasec/src/luasocket/buffer.c -I vendor/luasec/$(OPENSSL_INCDIR) -I vendor/luasec/src/ -I vendor/luasec/src/luasocket -D WITH_LUASOCKET -D LUASOCKET_DEBUG
108target/objects/luasec/vendor/luasec/src/luasocket/io.o: vendor/luasec/src/luasocket/io.c | target/objects/luasec/vendor/luasec/src/luasocket/
109 $(CC) -c -o target/objects/luasec/vendor/luasec/src/luasocket/io.o vendor/luasec/src/luasocket/io.c -I vendor/luasec/$(OPENSSL_INCDIR) -I vendor/luasec/src/ -I vendor/luasec/src/luasocket -D WITH_LUASOCKET -D LUASOCKET_DEBUG
110target/objects/luasec/vendor/luasec/src/luasocket/timeout.o: vendor/luasec/src/luasocket/timeout.c | target/objects/luasec/vendor/luasec/src/luasocket/
111 $(CC) -c -o target/objects/luasec/vendor/luasec/src/luasocket/timeout.o vendor/luasec/src/luasocket/timeout.c -I vendor/luasec/$(OPENSSL_INCDIR) -I vendor/luasec/src/ -I vendor/luasec/src/luasocket -D WITH_LUASOCKET -D LUASOCKET_DEBUG
112target/objects/luasec/vendor/luasec/src/luasocket/usocket.o: vendor/luasec/src/luasocket/usocket.c | target/objects/luasec/vendor/luasec/src/luasocket/
113 $(CC) -c -o target/objects/luasec/vendor/luasec/src/luasocket/usocket.o vendor/luasec/src/luasocket/usocket.c -I vendor/luasec/$(OPENSSL_INCDIR) -I vendor/luasec/src/ -I vendor/luasec/src/luasocket -D WITH_LUASOCKET -D LUASOCKET_DEBUG
114target/libraries/ssl.a: target/objects/luasec/vendor/luasec/src/options.o target/objects/luasec/vendor/luasec/src/config.o target/objects/luasec/vendor/luasec/src/ec.o target/objects/luasec/vendor/luasec/src/x509.o target/objects/luasec/vendor/luasec/src/context.o target/objects/luasec/vendor/luasec/src/ssl.o target/objects/luasec/vendor/luasec/src/luasocket/buffer.o target/objects/luasec/vendor/luasec/src/luasocket/io.o target/objects/luasec/vendor/luasec/src/luasocket/timeout.o target/objects/luasec/vendor/luasec/src/luasocket/usocket.o | target/libraries/
115 $(AR) rcu target/libraries/ssl.a target/objects/luasec/vendor/luasec/src/options.o target/objects/luasec/vendor/luasec/src/config.o target/objects/luasec/vendor/luasec/src/ec.o target/objects/luasec/vendor/luasec/src/x509.o target/objects/luasec/vendor/luasec/src/context.o target/objects/luasec/vendor/luasec/src/ssl.o target/objects/luasec/vendor/luasec/src/luasocket/buffer.o target/objects/luasec/vendor/luasec/src/luasocket/io.o target/objects/luasec/vendor/luasec/src/luasocket/timeout.o target/objects/luasec/vendor/luasec/src/luasocket/usocket.o
116
117target/objects/miniposix/vendor/miniposix/miniposix.o: vendor/miniposix/miniposix.c | target/objects/miniposix/vendor/miniposix/
118 $(CC) -c -o target/objects/miniposix/vendor/miniposix/miniposix.o vendor/miniposix/miniposix.c
119target/libraries/miniposix.a: target/objects/miniposix/vendor/miniposix/miniposix.o | target/libraries/
120 $(AR) rcu target/libraries/miniposix.a target/objects/miniposix/vendor/miniposix/miniposix.o
121
122
123target/libraries/:
124 $(MKDIR) -p target/libraries/
125target/libraries/md5/:
126 $(MKDIR) -p target/libraries/md5/
127target/libraries/mime/:
128 $(MKDIR) -p target/libraries/mime/
129target/libraries/socket/:
130 $(MKDIR) -p target/libraries/socket/
131target/objects/lua-bz2/vendor/lua-bz2/:
132 $(MKDIR) -p target/objects/lua-bz2/vendor/lua-bz2/
133target/objects/lua-zlib/vendor/lua-zlib/:
134 $(MKDIR) -p target/objects/lua-zlib/vendor/lua-zlib/
135target/objects/luafilesystem/vendor/luafilesystem/src/:
136 $(MKDIR) -p target/objects/luafilesystem/vendor/luafilesystem/src/
137target/objects/luasec/vendor/luasec/src/:
138 $(MKDIR) -p target/objects/luasec/vendor/luasec/src/
139target/objects/luasec/vendor/luasec/src/luasocket/:
140 $(MKDIR) -p target/objects/luasec/vendor/luasec/src/luasocket/
141target/objects/luasocket/vendor/luasocket/src/:
142 $(MKDIR) -p target/objects/luasocket/vendor/luasocket/src/
143target/objects/md5/vendor/md5/src/:
144 $(MKDIR) -p target/objects/md5/vendor/md5/src/
145target/objects/miniposix/vendor/miniposix/:
146 $(MKDIR) -p target/objects/miniposix/vendor/miniposix/
147
diff --git a/bootstrap.tl b/bootstrap.tl
new file mode 100755
index 00000000..5017f117
--- /dev/null
+++ b/bootstrap.tl
@@ -0,0 +1,518 @@
1#!/usr/bin/env -S -- tl run
2
3local PLATFORM = arg[1] or "unix"
4
5local lfs = require("lfs")
6
7local dependencies = {
8 "md5",
9 "lua-zlib",
10 "lua-bz2",
11 "luafilesystem",
12 "luasocket",
13 "luasec",
14 "miniposix",
15}
16
17local c_module_exceptions: {string:{string}} = {
18 ["ssl"] = { "ssl.core", "ssl.context", "ssl.x509", "ssl.config" },
19}
20
21local rockspec_locations: {string:string} = {
22 ["md5"] = "vendor/md5/rockspec/md5-1.2-1.rockspec",
23 ["lua-zlib"] = "vendor/lua-zlib/lua-zlib-1.1-0.rockspec",
24 ["lua-bz2"] = "vendor/lua-bz2/lua-bz2-0.2.1-1.rockspec",
25 ["luafilesystem"] = "vendor/luafilesystem/luafilesystem-scm-1.rockspec",
26 ["luasocket"] = "vendor/luasocket/luasocket-scm-3.rockspec",
27 ["luasec"] = "vendor/luasec/luasec-1.3.2-1.rockspec",
28 ["miniposix"] = "vendor/miniposix/miniposix-dev-1.rockspec",
29}
30
31--------------------------------------------------------------------------------
32-- Utilities
33--------------------------------------------------------------------------------
34
35local hexdump: function(string): string
36do
37 local numtab = {}
38 for i = 0, 255 do
39 numtab[string.char(i)] = ("%-3d,"):format(i)
40 end
41 hexdump = function(str: string): string
42 return (str:gsub(".", numtab):gsub(("."):rep(80), "%0\n"))
43 end
44end
45
46local function apply_template(template: string, variables: {string:string}): string
47 return (template:gsub("$%(([^)]*)%)", variables))
48end
49
50local function reindent_c(input: string): string
51 local out = {}
52 local indent = 0
53 local previous_is_blank = true
54 for line in input:gmatch("([^\n]*)") do
55 line = line:match("^[ \t]*(.-)[ \t]*$")
56
57 local is_blank = (#line == 0)
58 local do_print =
59 (not is_blank) or
60 (not previous_is_blank and indent == 0)
61
62 if line:match("^[})]") then
63 indent = indent - 1
64 if indent < 0 then indent = 0 end
65 end
66 if do_print then
67 table.insert(out, string.rep(" ", indent))
68 table.insert(out, line)
69 table.insert(out, "\n")
70 end
71 if line:match("[{(]$") then
72 indent = indent + 1
73 end
74
75 previous_is_blank = is_blank
76 end
77 return table.concat(out)
78end
79
80local function sortedpairs<K, V>(tbl: {K: V}): function(): (K, V)
81 local keys = {}
82 for k, _ in pairs(tbl) do
83 table.insert(keys, k)
84 end
85 table.sort(keys, function(a: K, b: K): boolean
86 if a is integer and not b is integer then
87 return true
88 elseif not a is integer and b is integer then
89 return false
90 end
91 return (a as integer) < (b as integer)
92 end)
93 local i = 1
94 return function(): (K, V)
95 local key = keys[i]
96 i = i + 1
97 return key, tbl[key]
98 end
99end
100
101local function mkdir_p(dirname: string)
102 local a, b = dirname:match("(.*)/(.*)")
103 if a and b then
104 mkdir_p(a)
105 end
106 lfs.mkdir(dirname)
107end
108
109local function dirname(filename: string): string
110 return (filename:gsub("[^/]*$", ""))
111end
112
113local function write_template(filename: string, template: string, variables: {string:string})
114 local fd = assert(io.open(filename, "wb"))
115 local text = apply_template(template, variables)
116 if filename:match("%.[ch]$") then
117 text = reindent_c(text)
118 end
119 fd:write(text)
120 fd:close()
121end
122
123local function find_files(dir_name: string): (function(): string)
124 local iter_stack: {lfs.DirObj} = {}
125 local dir_stack: {string} = { dir_name }
126 local iter, dd = lfs.dir(dir_name)
127 return function(): string
128 while true do
129 local s = iter(dd)
130 if s ~= "." and s ~= ".." then
131 if not s then
132 if #iter_stack == 0 then
133 return nil
134 end
135 table.remove(dir_stack)
136 dd = table.remove(iter_stack)
137 else
138 local d = dir_stack[#dir_stack]
139 local pathname = d .. "/" .. s, "mode"
140 if lfs.attributes(pathname, "mode") ~= "directory" then
141 return pathname
142 else
143 table.insert(iter_stack, dd)
144 iter, dd = lfs.dir(pathname)
145 table.insert(dir_stack, pathname)
146 end
147 end
148 end
149 end
150 end
151end
152
153--------------------------------------------------------------------------------
154-- Collect data based on rockspecs in vendor/
155--------------------------------------------------------------------------------
156
157local record BuildEntry
158 sources: {string}
159 incdirs: {string}
160 defines: {string}
161end
162
163local record Data
164 record LuaEntry
165 dep: string
166 mod: string
167 source: string
168
169 h_file: string
170 length: integer
171 end
172 record CEntry
173 dep: string
174 mod: string
175 build: BuildEntry
176
177 a_file: string
178 end
179
180 luas: {LuaEntry}
181 cs: {CEntry}
182end
183
184local function add_lua(data: Data, dep: string, mod: string, source: string)
185 table.insert(data.luas, { dep = dep, mod = mod, source = source })
186end
187
188local function add_c(data: Data, dep: string, mod: string, build: BuildEntry)
189 table.insert(data.cs, { dep = dep, mod = mod, build = build })
190end
191
192local record Rockspec
193 record Build
194 record Install
195 lua: {(string | integer): string}
196 end
197
198 type: string
199 modules: {string: (string | BuildEntry)}
200 install: Install
201 platforms: {string: Build}
202 end
203
204 build: Build
205end
206
207local function load_rockspec(dep: string, rockspec_filename: string): Rockspec
208 local rockspec: Rockspec = {}
209 local fd = io.open(rockspec_filename)
210 local source = fd:read("*a")
211 fd:close()
212 local chunk = assert(load(source, dep, "t", rockspec as {any:any}))
213 chunk()
214 return rockspec
215end
216
217local function process_build_entry(data: Data, dep: string, mod: string, modt: string|BuildEntry)
218 if modt is string then
219 if modt:match("lua$") then
220 add_lua(data, dep, mod, "vendor/" .. dep .. "/" .. modt)
221 else
222 add_c(data, dep, mod, { sources = { modt } })
223 end
224 elseif modt is BuildEntry then
225 add_c(data, dep, mod, modt)
226 end
227end
228
229local function process_build_modules(data: Data, dep: string, entries: {string: (string|BuildEntry)})
230 for mod, modt in sortedpairs(entries) do
231 process_build_entry(data, dep, mod, modt)
232 end
233end
234
235local function process_build_install(data: Data, dep: string, entries: {(string|integer): string})
236 for mod, modt in sortedpairs(entries) do
237 if mod is integer then
238 assert(modt is string)
239 mod = modt:gsub("^src/", ""):gsub("^lua/", ""):gsub("%.[^.]*$", ""):gsub("/", ".")
240 end
241 assert(mod is string)
242
243 process_build_entry(data, dep, mod, modt)
244 end
245end
246
247local function process_build(data: Data, dep: string, build: Rockspec.Build)
248 if build.modules then
249 process_build_modules(data, dep, build.modules)
250 end
251 if build.install and build.install.lua then
252 process_build_install(data, dep, build.install.lua)
253 end
254end
255
256local function process(data: Data, dep: string, rockspec_filename: string)
257 local rockspec = load_rockspec(dep, rockspec_filename)
258
259 assert(rockspec.build.type == "builtin")
260
261 if rockspec.build.modules or rockspec.build.install then
262 process_build(data, dep, rockspec.build)
263 end
264
265 if rockspec.build.platforms then
266 if rockspec.build.platforms[PLATFORM] then
267 process_build(data, dep, rockspec.build.platforms[PLATFORM])
268 end
269 end
270end
271
272--------------------------------------------------------------------------------
273-- Generate entries for Makefile-based build
274--------------------------------------------------------------------------------
275
276local function global_name(mod: string): string
277 return "luarocks_gen_" .. mod:gsub("%.", "_")
278end
279
280local function generate(input_filename: string, entry: Data.LuaEntry): string
281 local fd = assert(io.open(input_filename, "rb"))
282 local content = fd:read("*a"):gsub("^#![^\n]+\n", "")
283 fd:close()
284
285 entry.length = #content
286
287 return apply_template([[
288 /* automatically generated by bootstrap.tl */
289
290 static const unsigned char $(global)[] = {
291 $(code)
292 };
293 ]], {
294 global = global_name(entry.mod),
295 code = hexdump(content),
296 })
297end
298
299local function generate_all_luas(luas: {Data.LuaEntry})
300 for _, entry in ipairs(luas) do
301 local filename = "gen/lua/" .. entry.mod:gsub("%.", "/") .. ".h"
302 mkdir_p(dirname(filename))
303
304 local fd = assert(io.open(filename, "wb"))
305 fd:write(reindent_c(generate(entry.source, entry)))
306 entry.h_file = filename
307 fd:close()
308 end
309
310 local includes = {}
311 local array = {}
312 for _, entry in ipairs(luas) do
313 table.insert(includes, ("#include \"%s\""):format(entry.h_file))
314 table.insert(array, apply_template([[
315 {
316 .module_name = "$(mod)",
317 .source_name = "$(source)",
318 .length = $(length),
319 .code = $(global),
320 },
321 ]], {
322 mod = entry.mod,
323 dep = entry.dep,
324 source = entry.source,
325 length = tostring(entry.length),
326 global = global_name(entry.mod),
327 }))
328 end
329
330 table.insert(array, apply_template([[
331 {
332 .module_name = NULL,
333 .source_name = NULL,
334 .length = 0,
335 .code = NULL,
336 },
337 ]], {}))
338
339 write_template("gen/gen.h", [[
340 /* automatically generated by bootstrap.tl */
341
342 $(includes)
343
344 static const Gen GEN[] = {
345 $(array)
346 };
347 ]], {
348 array = table.concat(array, "\n"),
349 includes = table.concat(includes, "\n"),
350 })
351end
352
353local function get_flag_list(flag: string, entries: {string}, parent: string): string
354 local out = {}
355 for _, entry in ipairs(entries) do
356 table.insert(out, flag .. " " .. parent .. entry)
357 end
358 return table.concat(out, " ")
359end
360
361local function generate_makefile_entry(entry: Data.CEntry, seen: {string:boolean}, dirs: {string:boolean}): string
362 local out = {}
363 assert(entry.build.sources)
364
365 local incdirs = ""
366 if entry.build.incdirs then
367 incdirs = get_flag_list("-I", entry.build.incdirs, "vendor/" .. entry.dep .. "/")
368 end
369 local defines = ""
370 if entry.build.defines then
371 defines = get_flag_list("-D", entry.build.defines, "")
372 end
373
374 local objects = {}
375 for _, f in ipairs(entry.build.sources) do
376 local file = "vendor/" .. entry.dep .. "/" .. f
377 local obj_file = "target/objects/" .. entry.dep .. "/" .. file:gsub("%.c$", ".o")
378 table.insert(objects, obj_file)
379
380 if not seen[file] then
381 local d = dirname(obj_file)
382 if not dirs[d] then
383 dirs[d] = true
384 end
385
386 -- the pipe indicates an order-only prerequisite
387 -- (https://www.gnu.org/software/make/manual/make.html#Prerequisite-Types)
388 table.insert(out, ("%s: %s | %s"):format(obj_file, file, d))
389 table.insert(out, ("\t$(CC) -c -o %s %s %s %s"):format(obj_file, file, incdirs, defines))
390 seen[file] = true
391 end
392 end
393
394 local a_file = "target/libraries/" .. entry.mod:gsub("%.", "/") .. ".a"
395 entry.a_file = a_file
396
397 local d = dirname(a_file)
398 if not dirs[d] then
399 dirs[d] = true
400 end
401
402 local object_list = table.concat(objects, " ")
403 table.insert(out, ("%s: %s | %s"):format(a_file, object_list, d))
404 --table.insert(out, ("\t$(MKDIR) -p %s"):format(dirname(a_file)))
405 table.insert(out, ("\t$(AR) rcu %s %s"):format(a_file, object_list))
406 table.insert(out, "")
407
408 return table.concat(out, "\n")
409end
410
411local function process_c_entry(mod: string, externs: {string}, declares: {string})
412 if c_module_exceptions[mod] then
413 for _, m in ipairs(c_module_exceptions[mod]) do
414 process_c_entry(m, externs, declares)
415 end
416 return
417 end
418
419 local cfunc = "luaopen_" .. mod:gsub("%.", "_")
420
421 table.insert(externs, ("extern int %s(lua_State* L);"):format(cfunc))
422
423 table.insert(declares, ("lua_pushcfunction(L, %s);"):format(cfunc))
424 table.insert(declares, ("lua_setfield(L, -2, \"%s\");"):format(mod))
425end
426
427local makefile_vendor_template = [[
428# automatically generated by bootstrap.tl
429
430VENDOR_LIBS = $(a_files)
431
432$(entries)
433
434]]
435
436local function generate_all_cs(cs: {Data.CEntry})
437 local seen = {}
438 local dirs = {}
439
440 local entries = {}
441 for _, entry in ipairs(cs) do
442 table.insert(entries, generate_makefile_entry(entry, seen, dirs))
443 end
444
445 table.insert(entries, "")
446 for d, _ in sortedpairs(dirs) do
447 table.insert(entries, ("%s:"):format(d))
448 table.insert(entries, ("\t$(MKDIR) -p %s"):format(d))
449 end
450
451 local a_files = {}
452 for _, entry in ipairs(cs) do
453 table.insert(a_files, entry.a_file)
454 end
455
456 write_template("Makefile.vendor", makefile_vendor_template, {
457 entries = table.concat(entries, "\n"),
458 a_files = table.concat(a_files, " "),
459 })
460
461 local externs = {}
462 local declares = {}
463 for _, entry in ipairs(cs) do
464 process_c_entry(entry.mod, externs, declares)
465 end
466
467 write_template("gen/libraries.h", [[
468 /* automatically generated by bootstrap.tl */
469
470 $(externs)
471
472 static void declare_libraries(lua_State* L) {
473 lua_getglobal(L, "package"); /* package */
474 lua_getfield(L, -1, "preload"); /* package package.preload */
475 $(declares)
476 lua_settop(L, 0); /* */
477 }
478 ]], {
479 externs = table.concat(externs, "\n"),
480 declares = table.concat(declares, "\n"),
481 })
482end
483
484local function generate_main_h()
485 local fd = assert(io.open("gen/main.h", "wb"))
486 fd:write(reindent_c(generate("src/bin/luarocks", {
487 mod = "main"
488 })))
489 fd:close()
490end
491
492--------------------------------------------------------------------------------
493-- Main operation
494--------------------------------------------------------------------------------
495
496local data: Data = {
497 luas = {},
498 cs = {},
499}
500
501for file in find_files("src") do
502 if file:match("%.lua$") then
503 table.insert(data.luas, {
504 dep = "luarocks",
505 mod = file:gsub("^src/(.*).lua", "%1"):gsub("/", "."),
506 source = file,
507 })
508 end
509end
510
511for _, dep in ipairs(dependencies) do
512 print(dep)
513 process(data, dep, rockspec_locations[dep])
514end
515
516generate_all_luas(data.luas)
517generate_all_cs(data.cs)
518generate_main_h()
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 00000000..6cefe212
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,160 @@
1#include <lua.h>
2#include <lualib.h>
3#include <lauxlib.h>
4#include <errno.h>
5#include <stdio.h>
6#include <stdlib.h>
7
8typedef struct {
9 char* module_name;
10 char* source_name;
11 int length;
12 const unsigned char* code;
13} Gen;
14
15#include "gen/gen.h"
16#include "gen/libraries.h"
17
18static const char* progname = "luarocks";
19
20/* portable alerts, from srlua */
21#ifdef _WIN32
22#include <windows.h>
23#define alert(message) MessageBox(NULL, message, progname, MB_ICONERROR | MB_OK)
24#define getprogname() char name[MAX_PATH]; argv[0]= GetModuleFileName(NULL,name,sizeof(name)) ? name : NULL;
25#else
26#define alert(message) fprintf(stderr,"%s: %s\n", progname, message)
27#define getprogname()
28#endif
29
30static int registry_key;
31
32/* fatal error, from srlua */
33static void fatal(const char* message) {
34 alert(message);
35 exit(EXIT_FAILURE);
36}
37
38static void load_main(lua_State* L) {
39 #include "gen/main.h"
40
41 if (luaL_loadbuffer(L, luarocks_gen_main, sizeof(luarocks_gen_main), progname) != LUA_OK) {
42 fatal(lua_tostring(L, -1));
43 }
44}
45
46
47static void declare_modules(lua_State* L) {
48 lua_settop(L, 0); /* */
49 lua_newtable(L); /* modules */
50 lua_pushlightuserdata(L, (void*) &registry_key); /* modules registry_key */
51 lua_pushvalue(L, 1); /* modules registry_key modules */
52 lua_rawset(L, LUA_REGISTRYINDEX); /* modules */
53
54 for (int i = 0; GEN[i].module_name; i++) {
55 const Gen* entry = &GEN[i];
56 luaL_loadbuffer(L, entry->code, entry->length, entry->source_name);
57 lua_setfield(L, 1, entry->module_name);
58 }
59}
60
61
62/* custom package loader */
63static int pkg_loader(lua_State* L) {
64 lua_pushlightuserdata(L, (void*) &registry_key); /* modname ? registry_key */
65 lua_rawget(L, LUA_REGISTRYINDEX); /* modname ? modules */
66 lua_pushvalue(L, -1); /* modname ? modules modules */
67 lua_pushvalue(L, 1); /* modname ? modules modules modname */
68 lua_gettable(L, -2); /* modname ? modules mod */
69 if (lua_type(L, -1) == LUA_TNIL) {
70 lua_pop(L, 1); /* modname ? modules */
71 lua_pushvalue(L, 1); /* modname ? modules modname */
72 lua_pushliteral(L, ".init"); /* modname ? modules modname ".init" */
73 lua_concat(L, 2); /* modname ? modules modname..".init" */
74 lua_gettable(L, -2); /* modname ? mod */
75 }
76 return 1;
77}
78
79static void install_pkg_loader(lua_State* L) {
80 lua_settop(L, 0); /* */
81 lua_getglobal(L, "table"); /* table */
82 lua_getfield(L, -1, "insert"); /* table table.insert */
83 lua_getglobal(L, "package"); /* table table.insert package */
84 lua_getfield(L, -1, "searchers"); /* table table.insert package package.searchers */
85 if (lua_type(L, -1) == LUA_TNIL) {
86 lua_pop(L, 1);
87 lua_getfield(L, -1, "loaders"); /* table table.insert package package.loaders */
88 }
89 lua_copy(L, 4, 3); /* table table.insert package.searchers */
90 lua_settop(L, 3); /* table table.insert package.searchers */
91 lua_pushnumber(L, 1); /* table table.insert package.searchers 1 */
92 lua_pushcfunction(L, pkg_loader); /* table table.insert package.searchers 1 pkg_loader */
93 lua_call(L, 3, 0); /* table */
94 lua_settop(L, 0); /* */
95}
96
97/* main script launcher, from srlua */
98static int pmain(lua_State *L) {
99 int argc = lua_tointeger(L, 1);
100 char** argv = lua_touserdata(L, 2);
101 int i;
102 load_main(L);
103 lua_createtable(L, argc, 0);
104 for (i = 0; i < argc; i++) {
105 lua_pushstring(L, argv[i]);
106 lua_rawseti(L, -2, i);
107 }
108 lua_setglobal(L, "arg");
109 luaL_checkstack(L, argc - 1, "too many arguments to script");
110 for (i = 1; i < argc; i++) {
111 lua_pushstring(L, argv[i]);
112 }
113 lua_call(L, argc - 1, 0);
114 return 0;
115}
116
117/* error handler, from luac */
118static int msghandler (lua_State *L) {
119 /* is error object not a string? */
120 const char *msg = lua_tostring(L, 1);
121 if (msg == NULL) {
122 /* does it have a metamethod that produces a string */
123 if (luaL_callmeta(L, 1, "__tostring") && lua_type(L, -1) == LUA_TSTRING) {
124 /* then that is the message */
125 return 1;
126 } else {
127 msg = lua_pushfstring(L, "(error object is a %s value)", luaL_typename(L, 1));
128 }
129 }
130 /* append a standard traceback */
131 luaL_traceback(L, L, msg, 1);
132 return 1;
133}
134
135/* main function, from srlua */
136int main(int argc, char** argv) {
137 lua_State* L;
138 getprogname();
139 if (argv[0] == NULL) {
140 fatal("cannot locate this executable");
141 }
142 L = luaL_newstate();
143 if (L == NULL) {
144 fatal("not enough memory for state");
145 }
146 luaL_openlibs(L);
147 install_pkg_loader(L);
148 declare_libraries(L);
149 declare_modules(L);
150 lua_pushcfunction(L, &msghandler);
151 lua_pushcfunction(L, &pmain);
152 lua_pushinteger(L, argc);
153 lua_pushlightuserdata(L, argv);
154 if (lua_pcall(L, 2, 0, -4) != 0) {
155 fatal(lua_tostring(L, -1));
156 }
157 lua_close(L);
158 return EXIT_SUCCESS;
159}
160