Created
December 30, 2025 13:01
-
-
Save gvanem/73b34157e2ce74cd2a1fc41f107bbd57 to your computer and use it in GitHub Desktop.
GNU-makefile for MG-LUA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # | |
| # MG-Lua for MSVC / clang-cl | |
| # | |
| THIS_FILE := Makefile.Windows | |
| TODAY := $(shell date +%d-%B-%Y) | |
| PYTHON := py.exe -3 | |
| MAKEFLAGS += --warn-undefined-variables | |
| USE_ASTYLE ?= 1 | |
| USE_LUAJIT ?= 1 | |
| USE_MG_OFFICIAL ?= 1 | |
| USE_MP_COMPILE ?= 1 | |
| USE_WSOCK_TRACE ?= 1 | |
| # | |
| # Change to suite: | |
| # | |
| LUA55_ROOT ?= f:/MinGW32/src/LUA/Lua-5.5 | |
| LUAJIT_ROOT ?= f:/MinGW32/src/LUA/LuaJIT | |
| MONGOOSE_ROOT ?= f:/MinGW32/src/inet/Web/Mongoose | |
| define Usage | |
| Usage: "make -f $(THIS_FILE) [CC=cl | clang-cl] [all | clean | vclean | install]") | |
| Specify CC=cl - build with MSVC | |
| Specify CC=clang-cl - build with clang-cl | |
| endef | |
| ifneq ($(CC),cl) | |
| ifneq ($(CC),clang-cl) | |
| $(error $(Usage)) | |
| endif | |
| endif | |
| ifeq ($(USE_MG_OFFICIAL),1) | |
| MG_DIR = $(MONGOOSE_ROOT) | |
| else | |
| MG_DIR = ./libmongoose/src | |
| endif | |
| # | |
| # From 'src/CMakeLists.txt': | |
| # set(VERSION_MAJ 7) | |
| # set(VERSION_MIN 2) | |
| # | |
| VER_MAJOR = 7 | |
| VER_MINOR = 2 | |
| VER_MICRO = 0 | |
| VERSION = $(VER_MAJOR).$(VER_MINOR).$(VER_MICRO) | |
| # | |
| # Undefine any '%CL%' env-var | |
| # | |
| export CL= | |
| OBJ_DIR = objects | |
| c_to_obj = $(addprefix $(OBJ_DIR)/, $(notdir $(1:.c=.obj))) | |
| # | |
| # What to build: | |
| # | |
| MG_LUA_DLL = bin/mg_lua-$(CPU).dll | |
| MG_LUA_IMP_LIB = lib/mg_lua_imp-$(CPU).lib | |
| MQTT_SERVER_DLL = bin/mqtt-server-$(CPU).dll | |
| MQTT_SERVER_IMP_LIB = lib/mqtt-server_imp-$(CPU).lib | |
| CFLAGS = -nologo -MD -O2 -W4 -Zi \ | |
| -I. \ | |
| -I./src \ | |
| -I$(MG_DIR) \ | |
| -Fd./$(OBJ_DIR)/vc14x.pdb \ | |
| -FI./$(OBJ_DIR)/mg-lua-hacks.h | |
| LDFLAGS = -nologo -debug -verbose -incremental:no \ | |
| -machine:$(CPU) -nodefaultlib:uuid.lib \ | |
| -subsystem:console | |
| RCFLAGS = -nologo | |
| ifeq ($(CC),clang-cl) | |
| CFLAGS += -fms-compatibility \ | |
| -ferror-limit=5 | |
| RCFLAGS += -D__clang__ | |
| else | |
| RCFLAGS += -D_MSC_VER | |
| endif | |
| ifeq ($(USE_LUAJIT),1) | |
| CFLAGS += -I$(LUAJIT_ROOT)/src -DUSE_LUAJIT | |
| LUA_EXE = $(LUAJIT_ROOT)/bin/luajit.exe | |
| LUA_LIB = $(LUAJIT_ROOT)/lib/luajit_static-$(CPU).lib | |
| LUA_LIB = $(LUAJIT_ROOT)/lib/luajit-$(CPU).lib | |
| else | |
| CFLAGS += -I$(LUA55_ROOT) -DLUA_COMPAT_APIINTCASTS | |
| LUA_EXE = $(LUA55_ROOT)/bin/lua.exe | |
| LUA_LIB = $(LUA55_ROOT)/lib/lua55-$(CPU).lib | |
| endif | |
| ifeq ($(USE_WSOCK_TRACE),1) | |
| WS2_32_LIB = wsock_trace-$(CPU).lib | |
| LDFLAGS += -nodefaultlib:ws2_32.lib | |
| else | |
| WS2_32_LIB = ws2_32.lib | |
| endif | |
| vpath %.c src | |
| LIB_SRC = $(addprefix src/, \ | |
| mg_addr.c \ | |
| mg_connection.c \ | |
| mg_dns.c \ | |
| mg_fd.c \ | |
| mg_fs.c \ | |
| mg_fs_file.c \ | |
| mg_http.c \ | |
| mg_http_header.c \ | |
| mg_http_message.c \ | |
| mg_http_part.c \ | |
| mg_http_serve_opts.c \ | |
| mg_iobuf.c \ | |
| mg_json.c \ | |
| mg_logging.c \ | |
| mg_lua.c \ | |
| mg_lua_cb.c \ | |
| mg_mgr.c \ | |
| mg_mqtt.c \ | |
| mg_mqtt_message.c \ | |
| mg_mqtt_opts.c \ | |
| mg_queue.c \ | |
| mg_rpc.c \ | |
| mg_rpc_req.c \ | |
| mg_sntp.c \ | |
| mg_str.c \ | |
| mg_string.c \ | |
| mg_time.c \ | |
| mg_timer.c \ | |
| mg_tls.c \ | |
| mg_tls_opts.c \ | |
| mg_trace.c \ | |
| mg_url.c \ | |
| mg_utility.c \ | |
| mg_ws.c \ | |
| mg_ws_message.c) | |
| vpath %.c $(MG_DIR) | |
| LIB_SRC += $(MG_DIR)/mongoose.c | |
| LIB_OBJ = $(call c_to_obj, $(LIB_SRC)) | |
| # | |
| # For '$(MQTT_SERVER_DLL)' | |
| # | |
| vpath %.c src/examples/mqtt/server | |
| GENERATED = $(OBJ_DIR)/mg-lua-hacks.h | |
| TARGETS = $(MG_LUA_IMP_LIB) \ | |
| $(MG_LUA_DLL) \ | |
| $(MQTT_SERVER_DLL) \ | |
| $(MQTT_SERVER_IMP_LIB) \ | |
| bin/mqtt_server-$(CPU).dll | |
| all: check_lua_exe $(GENERATED) $(TARGETS) | |
| check_lua_exe: | |
| ifneq ($(shell $(LUA_EXE) -v 1>/dev/null 2>/dev/null; echo $$?), 0) | |
| $(error "$(LUA_EXE) executable not found") | |
| endif | |
| bin lib \ | |
| $(OBJ_DIR): | |
| mkdir --parents $@ | |
| $(OBJ_DIR)/mg-lua-hacks.h: $(THIS_FILE) | $(OBJ_DIR) | |
| $(call generate_c, $@, $(MG_LUA_HACKS_H)) | |
| bin/%.exe: $(OBJ_DIR)/%.obj $(MG_LUA_IMP_LIB) $(LUA_LIB) | bin | |
| $(call link_EXE, $@, $^ $(WS2_32_LIB)) | |
| # | |
| # Exports from '$(MG_LUA_DLL)': | |
| # | |
| MG_LUA_EXPORTS = -export:luaopen_mg_lua \ | |
| -export:mg_open_mg_ws \ | |
| -export:mg_open_mg_mqtt \ | |
| -export:mg_str_s | |
| # | |
| # Exports from '$(MQTT_SERVER_DLL)': | |
| # | |
| MQTT_SERVER_EXPORTS = -export:luaopen_mqtt_server | |
| $(MG_LUA_IMP_LIB): $(MG_LUA_DLL) | |
| $(MQTT_SERVER_IMP_LIB): $(MQTT_SERVER_DLL) | |
| .DELETE_ON_ERROR: $(MG_LUA_DLL) $(MG_LUA_IMP_LIB) | |
| $(MG_LUA_DLL): $(LIB_OBJ) $(LUA_LIB) $(OBJ_DIR)/mg_lua.res | bin lib | |
| $(call link_DLL, $@, $(MG_LUA_EXPORTS) $^ $(WS2_32_LIB), $(MG_LUA_IMP_LIB)) | |
| .DELETE_ON_ERROR: $(MQTT_SERVER_DLL) $(MQTT_SERVER_IMP_LIB) | |
| $(MQTT_SERVER_DLL): $(OBJ_DIR)/mqtt-server.obj $(OBJ_DIR)/mqtt-server.res $(MG_LUA_IMP_LIB) $(LUA_LIB) | bin lib | |
| $(call link_DLL, $@, $(MQTT_SERVER_EXPORTS) $^, $(MQTT_SERVER_IMP_LIB)) | |
| bin/mqtt_server-$(CPU).dll: $(MQTT_SERVER_DLL) | |
| cp $(MQTT_SERVER_DLL) $@ | |
| @echo | |
| ifeq ($(CC)-$(USE_MP_COMPILE),cl-1) | |
| $(LIB_OBJ): $(LIB_SRC) | $(CC).args $(OBJ_DIR) | |
| $(call C_compile_MP, $(OBJ_DIR), $(LIB_SRC), LIB_SRC) | |
| endif | |
| $(OBJ_DIR)/%.obj: %.c | $(CC).args $(OBJ_DIR) | |
| $(call C_compile, $@, $<) | |
| $(OBJ_DIR)/%.res: $(OBJ_DIR)/%.rc | |
| $(call RC_compile, $@, $<) | |
| $(OBJ_DIR)/mg_lua.rc: $(THIS_FILE) | $(OBJ_DIR) | |
| $(call create_rc_file, $@, "$(notdir $(MG_LUA_DLL))", "Mongoose-Lua shared library") | |
| $(OBJ_DIR)/mqtt-server.rc: $(THIS_FILE) | $(OBJ_DIR) | |
| $(call create_rc_file, $@, "$(notdir $(MQTT_SERVER_DLL))", "MQTT server") | |
| $(CC).args: $(THIS_FILE) | |
| $(call green_msg, All CFLAGS are in $(BRIGHT_WHITE)$@) | |
| $(call create_resp_file, $@, $(CFLAGS)) | |
| install: # todo | |
| clean: | |
| rm -f cl.args clang-cl.args link.args link.tmp | |
| rm -rf $(OBJ_DIR) | |
| vclean realclean: clean | |
| rm -fr bin lib | |
| %.i: %.c $(OBJ_DIR)/cpp-filter.py $(CC).args $(GENERATED) FORCE | |
| $(call C_preprocess, $@, $<) | |
| FORCE: | |
| $(OBJ_DIR)/cpp-filter.py: $(THIS_FILE) | $(OBJ_DIR) | |
| $(call generate, $@, #) | |
| $(file >> $@,if 1:) | |
| $(file >> $@,$(CPP_FILTER_PY)) | |
| run_http_client: src/examples/http-client/http-client.lua $(MG_LUA_DLL) | |
| $(call run_lua, $<, 0) | |
| run_huge_resp: src/examples/huge-response/huge-resp.lua $(MG_LUA_DLL) | |
| $(call run_lua, $<, 0) | |
| run_mqtt_dashboard: src/examples/mqtt/dashboard/main.lua $(MG_LUA_DLL) | |
| $(call run_lua, $<, 0) | |
| run_mqtt_server: src/examples/mqtt/server/mqtt-server.lua $(MG_LUA_DLL) $(MQTT_SERVER_DLL) bin/mqtt_server-$(CPU).dll | |
| $(call run_lua, $<, 0) | |
| run_json_test: src/examples/json/json-test.lua $(MG_LUA_DLL) | |
| $(call run_lua, $<, 0) | |
| # | |
| # GNU-make macros: | |
| # | |
| # This assumes you have an MSys/Cygwin 'echo.exe' with colour support. | |
| # | |
| BRIGHT_GREEN = \e[1;32m | |
| BRIGHT_WHITE = \e[1;37m | |
| green_msg = @echo -e "$(BRIGHT_GREEN)$(strip $(1))\e[0m" | |
| # | |
| # A "require('mg_lua')" will match "?" here: | |
| # "?-$(CPU).dll" | |
| # ^ | |
| # |__ "mg_lua" | |
| # | |
| define run_lua | |
| $(call green_msg, Running $(BRIGHT_WHITE)$(strip $(LUA_EXE) $(1))) | |
| $(strip export LUA_CPATH=bin/?-$(CPU).dll ; \ | |
| export LUA_PATH=src/?.lua ; \ | |
| export LUA_TRACE=0 ; \ | |
| export MG_LUA_TRACE=0 ; \ | |
| export WSOCK_TRACE_LEVEL=$(strip $(2)) ; \ | |
| $(LUA_EXE) $(1) ) | |
| @echo | |
| endef | |
| define C_compile | |
| $(CC) -c @$(CC).args -Fo./$(strip $(1) $(2)) | |
| @echo | |
| endef | |
| define C_compile_MP | |
| $(call green_msg, Compiling $(words $(2)) .c-files for $(BRIGHT_WHITE)$(strip $(3))) | |
| $(call C_compile, $(1)\\, -MP $(2)) | |
| endef | |
| define RC_compile | |
| rc $(RCFLAGS) -Fo./$(strip $(1) $(2)) | |
| @echo | |
| endef | |
| define create_rc_file | |
| $(call generate, $(1), //) | |
| $(file >> $(1), #define RC_INTERNAL_NAME $(2)) | |
| $(file >> $(1), #define RC_DESCRIPTION $(3)) | |
| $(file >> $(1),$(RC_COMMON)) | |
| endef | |
| ifeq ($(USE_ASTYLE),1) | |
| PP_FILTER = | astyle | |
| pp_comment = The preprocessed and astyled output of '$(strip $(1))' | |
| else | |
| PP_FILTER = | |
| pp_comment = The raw preprocessed output of '$(strip $(1))' | |
| endif | |
| define C_preprocess | |
| $(file > $(1),/* $(call pp_comment, $(2)):) | |
| $(file >> $(1), * $(CC) -E) | |
| $(foreach f, $(CFLAGS), $(file >> $(1), * $(f))) | |
| $(file >> $(1), *---------------------------------------------------------) | |
| $(file >> $(1), */) | |
| $(strip $(CC) -E @$(CC).args $(2) | $(PYTHON) $(OBJ_DIR)/cpp-filter.py $(PP_FILTER) >> $(1)) | |
| endef | |
| define create_resp_file | |
| $(file > $(1)) | |
| $(foreach f, $(2), $(file >> $(1),$(strip $(f))) ) | |
| endef | |
| define link_EXE | |
| $(call green_msg, Linking $(BRIGHT_WHITE)$(strip $(1))) | |
| $(call create_resp_file, link.args, $(LDFLAGS) $(2)) | |
| $(file > $(OBJ_DIR)/check-for-unused-libs.py,if 1:) | |
| $(file >> $(OBJ_DIR)/check-for-unused-libs.py,$(CHECK_FOR_UNUSED_LIBS_PY)) | |
| link -out:$(strip $(1)) @link.args > link.tmp | |
| @rm -f $(1:.exe=.exp) | |
| @$(PYTHON) $(OBJ_DIR)/check-for-unused-libs.py link.tmp | |
| endef | |
| define link_DLL | |
| $(call green_msg, Linking $(BRIGHT_WHITE)$(strip $(1))) | |
| $(call create_resp_file, link.args, -dll $(LDFLAGS) -implib:$(strip $(3)) $(2)) | |
| $(file > $(OBJ_DIR)/check-for-unused-libs.py,if 1:) | |
| $(file >> $(OBJ_DIR)/check-for-unused-libs.py,$(CHECK_FOR_UNUSED_LIBS_PY)) | |
| link -out:$(strip $(1)) @link.args > link.tmp | |
| @rm -f $(3:.lib=.exp) | |
| @$(PYTHON) $(OBJ_DIR)/check-for-unused-libs.py link.tmp | |
| endef | |
| define Warning | |
| $(1) | |
| $(1) DO NOT EDIT! This file was automatically generated | |
| $(1) from $(realpath $(THIS_FILE)) at $(TODAY). | |
| $(1) Edit that file instead. | |
| $(1) | |
| endef | |
| define generate | |
| $(call green_msg, Generating $(BRIGHT_WHITE)$(strip $(1))) | |
| $(file > $(1),$(call Warning,$(strip $(2)))) | |
| endef | |
| define generate_c | |
| $(call generate,$(1),//) | |
| $(file >> $(1),$(2)) | |
| endef | |
| # | |
| # Force included as '-FI./$(OBJ_DIR)/mg-lua-hacks.h' | |
| # with LUA to LuaJIT hacks etc. | |
| # | |
| define MG_LUA_HACKS_H | |
| #pragma once | |
| #define _CRT_SECURE_NO_WARNINGS | |
| #define _CRT_SECURE_NO_DEPRECATE | |
| #define _CRT_NONSTDC_NO_WARNINGS | |
| #define _CRT_OBSOLETE_NO_WARNINGS | |
| #define MG_TLS MG_TLS_BUILTIN | |
| #define MG_ENABLE_LINES 1 | |
| #define MG_ENABLE_MBEDTLS 1 | |
| #define MG_ENABLE_DIRLIST 1 | |
| #define MG_ENABLE_IPV6 1 | |
| #define MG_ENABLE_MD5 1 | |
| #define MG_ENABLE_PACKED_FS 0 | |
| #define MG_ENABLE_POLL 1 | |
| #define MG_ENABLE_SSI 1 | |
| #define MG_ENABLE_WINSOCK 1 | |
| #define MG_MAX_HTTP_HEADERS 7 | |
| #if defined(__clang__) | |
| #pragma clang diagnostic ignored "-Wunused-function" | |
| #elif defined(_MSC_VER) | |
| #pragma warning (disable: 4244 4267 4310) | |
| #endif | |
| #if defined(USE_LUAJIT) | |
| #define LUA_BUILD_AS_DLL /* Use the LuaJIT .DLL */ | |
| #endif | |
| #include <lua.h> | |
| #include <lauxlib.h> | |
| #include <mg_trace.h> | |
| #ifndef luaL_reg | |
| #define luaL_reg luaL_Reg | |
| #endif | |
| #ifndef luaL_checklong | |
| #define luaL_checklong(L, narg) ((long)luaL_checkinteger (L, narg)) | |
| #endif | |
| #ifndef luaL_checkint32 | |
| #define luaL_checkint32(L, narg) ((int)luaL_checkinteger (L, narg)) | |
| #endif | |
| #ifndef luaL_optlong | |
| #define luaL_optlong(L, n, d) ((long)luaL_optinteger (L, n, d)) | |
| #endif | |
| #if !defined(USE_LUAJIT) && (LUA_VERSION_NUM > 502) | |
| static __inline void luaL_openlib (lua_State *L, const char *libname, const luaL_Reg *reg, int nup) | |
| { | |
| if (libname) | |
| { | |
| const luaL_Reg *r_save; | |
| int size = 0; | |
| for (r_save = reg; r_save && r_save->name; r_save++) | |
| size++; | |
| //luaL_pushmodule (L, libname, size); | |
| (void) size; | |
| lua_insert (L, -(nup + 1)); /* Move module table below upvalues. */ | |
| } | |
| if (reg) | |
| luaL_setfuncs (L, reg, nup); | |
| else lua_pop (L, nup); /* Remove upvalues. */ | |
| } | |
| static __inline void luaL_register (lua_State *L, const char *libname, const luaL_Reg *reg) | |
| { | |
| luaL_openlib (L, libname, reg, 0); | |
| } | |
| #endif | |
| endef | |
| ifeq ($(USER),gv) | |
| BUILT_BY = " by <[email protected]>" | |
| else | |
| BUILT_BY = | |
| endif | |
| # | |
| # Common .rc contents for '$(MG_LUA_DLL)' + '$(MQTT_SERVER_DLL)'. | |
| # | |
| define RC_COMMON | |
| #include <winver.h> | |
| #define RC_VERSION $(VER_MAJOR),$(VER_MINOR),$(VER_MICRO),0 | |
| #if defined(__clang__) | |
| #define RC_COMPILER "Clang" | |
| #elif defined(_MSC_VER) | |
| #define RC_COMPILER "MSVC" | |
| #else | |
| #error "Unsupported compiler" | |
| #endif | |
| VS_VERSION_INFO VERSIONINFO | |
| FILEVERSION RC_VERSION | |
| PRODUCTVERSION RC_VERSION | |
| FILEFLAGSMASK 0x3fL | |
| FILEOS VOS__WINDOWS32 | |
| FILETYPE VFT_DLL | |
| FILESUBTYPE 0 | |
| FILEFLAGS 0 | |
| BEGIN | |
| BLOCK "StringFileInfo" | |
| BEGIN | |
| BLOCK "040904b0" | |
| BEGIN | |
| VALUE "CompanyName", "MG-Lua, https://github.com/TheRootED24/mg_lua.git" | |
| VALUE "FileDescription", RC_DESCRIPTION " (" RC_COMPILER ", $(CPU))" | |
| VALUE "FileVersion", "$(VERSION)" | |
| VALUE "InternalName", RC_INTERNAL_NAME | |
| VALUE "LegalCopyright", "Apache-2.0 license" | |
| VALUE "Comments", "Built on $(TODAY)" $(BUILT_BY) | |
| END | |
| END | |
| BLOCK "VarFileInfo" | |
| BEGIN | |
| VALUE "Translation", 0x409, 1200 | |
| END | |
| END | |
| endef | |
| define CPP_FILTER_PY | |
| import sys | |
| empty_lines = 0 | |
| while True: | |
| line = sys.stdin.readline() | |
| if not line: | |
| break | |
| line = line.rstrip() | |
| if line == "": | |
| empty_lines += 1 | |
| continue | |
| # | |
| # MSVC or clang-cl 'line' directive | |
| # | |
| l = line.lstrip() | |
| if l.startswith("#line") or l.startswith("# "): | |
| line = line.replace (r"\\", "/") | |
| print (line) | |
| # | |
| # Print a newline after a functions or structs | |
| # | |
| if l == "}" or l == "};": | |
| print ("") | |
| print ("Removed %d empty lines." % empty_lines, file=sys.stderr) | |
| endef | |
| define CHECK_FOR_UNUSED_LIBS_PY | |
| import os, sys, colorama | |
| map_file = sys.argv [1] | |
| ignore_libs = [ "oldnames.lib" ] | |
| class State: | |
| IDLE = 0 | |
| UNUSED = 1 | |
| colorama.init() | |
| class Colour: | |
| RED = colorama.Fore.RED + colorama.Style.BRIGHT | |
| WHITE = colorama.Fore.WHITE + colorama.Style.BRIGHT | |
| RESET = colorama.Style.RESET_ALL | |
| def cprint (color, s): | |
| print ("%s%s%s" % (color, s, Colour.RESET)) | |
| def report (unused): | |
| num = len(unused) | |
| if num > 0: | |
| cprint (Colour.RED, "%d unused librar%s in %s:" % (num, ["y", "ies"][num > 1], map_file)) | |
| for u in unused: | |
| print (" " + u) | |
| cprint (Colour.WHITE, "Done.\n") | |
| def process_map (state): | |
| unused_libs = [] | |
| f = open (map_file, "rt") | |
| lines = f.readlines() | |
| f.close() | |
| for l in lines: | |
| l = l.strip() | |
| if l == "Unused libraries:": | |
| state = State.UNUSED | |
| continue | |
| if state == State.UNUSED: | |
| if l == "": | |
| break | |
| if os.path.basename (l).lower() not in ignore_libs: | |
| unused_libs.append (l) | |
| return unused_libs | |
| report (process_map(State.IDLE)) | |
| endef |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment