mudgangster

Tiny, scriptable MUD client
Log | Files | Refs

commit ece162f87360abfbb93718ce38d16e5789f6e25c
parent 5411db95d61852d510b826d5613f08ad44aef329
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Sat,  2 May 2020 21:52:54 +0300

Use ninja/lua build system

Diffstat:
M.gitignore | 13+++++++++----
MMakefile | 50+++++++++++++++++++++++++++++++-------------------
Aggbuild/gen_ninja.lua | 387+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aggbuild/lua.linux | 0
Aggbuild/ninja.linux | 0
Aggbuild/ninja_timeline.lua | 45+++++++++++++++++++++++++++++++++++++++++++++
Aggbuild/pack_lua.lua | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Rscripts/example_scripts.nsi -> installer/example_scripts.nsi | 0
Rscripts/licenses.txt -> installer/licenses.txt | 0
Ainstaller/mudgangster.nsi | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlibs/lfs.lua | 7+++----
Mlibs/lpeg.lua | 13+++----------
Mlibs/lua.lua | 71+++++++++++++++++++++++++++++++++++------------------------------------
Mmake.lua | 49++++++++++++++++++++++++++++++++++++++++---------
Dscripts/bin2arr.lua | 8--------
Dscripts/gen_makefile.lua | 333-------------------------------------------------------------------------------
Dscripts/installer.nsi | 56--------------------------------------------------------
Dscripts/merge.lua | 46----------------------------------------------
Dscripts/pack_lua.sh | 7-------
Dsrc/main.cc | 23-----------------------
Msrc/ui.h | 2--
Msrc/x11.cc | 17++++++++++++++++-
22 files changed, 678 insertions(+), 558 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,8 +1,13 @@ -build -release -gen.mk +/build +/release +/build.ninja + +/mudgangster +/mudgangster-* + +.vs/ +.vscode/ -mudgangster *.exe *.exp *.ilk diff --git a/Makefile b/Makefile @@ -1,26 +1,38 @@ all: debug -.PHONY: debug asan release clean +.PHONY: debug asan bench release clean -build/lua_combined.h: src/lua/action.lua src/lua/alias.lua src/lua/chat.lua src/lua/mud.lua src/lua/event.lua src/lua/gag.lua src/lua/handlers.lua src/lua/intercept.lua src/lua/interval.lua src/lua/macro.lua src/lua/main.lua src/lua/script.lua src/lua/serialize.lua src/lua/status.lua src/lua/sub.lua src/lua/utils.lua src/lua/socket.lua - @printf "\033[1;33mbuilding $@\033[0m\n" - @scripts/pack_lua.sh +LUA = ggbuild/lua.linux +NINJA = ggbuild/ninja.linux -debug: build/lua_combined.h - @lua make.lua > gen.mk - @$(MAKE) -f gen.mk +WSLENV ?= notwsl +ifndef WSLENV + LUA = ggbuild/lua.exe + NINJA = ggbuild/ninja.exe +endif -asan: build/lua_combined.h - @lua make.lua asan > gen.mk - @$(MAKE) -f gen.mk +debug: + @$(LUA) make.lua > build.ninja + @$(NINJA) -release: build/lua_combined.h - @lua make.lua release > gen.mk - @$(MAKE) -f gen.mk +asan: + @$(LUA) make.lua asan > build.ninja + @$(NINJA) -clean: - @lua make.lua debug > gen.mk - @$(MAKE) -f gen.mk clean - @lua make.lua asan > gen.mk - @$(MAKE) -f gen.mk clean - @rm -f gen.mk +bench: + @$(LUA) make.lua bench > build.ninja + @$(NINJA) + +release: + @$(LUA) make.lua release > build.ninja + @$(NINJA) +clean: + @$(LUA) make.lua debug > build.ninja + @$(NINJA) -t clean || true + @$(LUA) make.lua asan > build.ninja || true + @$(NINJA) -t clean || true + @$(LUA) make.lua bench > build.ninja || true + @$(NINJA) -t clean || true + @rm -rf build release + @rm -f *.exp *.ilk *.ilp *.lib *.pdb + @rm -f build.ninja diff --git a/ggbuild/gen_ninja.lua b/ggbuild/gen_ninja.lua @@ -0,0 +1,387 @@ +local lfs = require( "INTERNAL_LFS" ) + +local configs = { } + +configs[ "windows" ] = { + bin_suffix = ".exe", + obj_suffix = ".obj", + lib_suffix = ".lib", + + toolchain = "msvc", + + cxxflags = "/c /Oi /Gm- /nologo /DNOMINMAX /DWIN32_LEAN_AND_MEAN", + ldflags = "user32.lib shell32.lib advapi32.lib dbghelp.lib /NOLOGO", +} + +configs[ "windows-debug" ] = { + cxxflags = "/MTd /Z7", + ldflags = "/DEBUG", +} +configs[ "windows-release" ] = { + cxxflags = "/O2 /MT /DNDEBUG", + bin_prefix = "release/", +} +configs[ "windows-bench" ] = { + bin_suffix = "-bench.exe", + cxxflags = configs[ "windows-release" ].cxxflags, + ldflags = configs[ "windows-release" ].ldflags, + prebuilt_lib_dir = "windows-release", +} + +configs[ "linux" ] = { + obj_suffix = ".o", + lib_prefix = "lib", + lib_suffix = ".a", + + toolchain = "gcc", + cc = "gcc", + cxx = "g++", + + cxxflags = "-c -fdiagnostics-color", + ldflags = "-fuse-ld=gold", +} + +configs[ "linux-debug" ] = { + cxxflags = "-O0 -ggdb3 -fno-omit-frame-pointer", +} +configs[ "linux-asan" ] = { + bin_suffix = "-asan", + cxxflags = configs[ "linux-debug" ].cxxflags .. " -fsanitize=address", + ldflags = "-fsanitize=address", + prebuilt_lib_dir = "linux-debug", +} +configs[ "linux-release" ] = { + cxxflags = "-O2 -DNDEBUG", + ldflags = "-s", + bin_prefix = "release/", +} +configs[ "linux-bench" ] = { + bin_suffix = "-bench", + cxxflags = configs[ "linux-release" ].cxxflags, + ldflags = configs[ "linux-release" ].ldflags, + prebuilt_lib_dir = "linux-release", +} + +local function identify_host() + local dll_ext = package.cpath:match( "(%a+)$" ) + + if dll_ext == "dll" then + return "windows" + end + + local p = assert( io.popen( "uname -s" ) ) + local uname = assert( p:read( "*all" ) ):gsub( "%s*$", "" ) + assert( p:close() ) + + if uname == "Linux" then + return "linux" + end + + io.stderr:write( "can't identify host OS" ) + os.exit( 1 ) +end + +OS = identify_host() +config = arg[ 1 ] or "debug" + +local OS_config = OS .. "-" .. config + +if not configs[ OS_config ] then + io.stderr:write( "bad config: " .. OS_config .. "\n" ) + os.exit( 1 ) +end + +local function concat( key ) + return "" + .. ( ( configs[ OS ] and configs[ OS ][ key ] ) or "" ) + .. " " + .. ( ( configs[ OS_config ] and configs[ OS_config ][ key ] ) or "" ) +end + +local function rightmost( key ) + return nil + or ( configs[ OS_config ] and configs[ OS_config ][ key ] ) + or ( configs[ OS ] and configs[ OS ][ key ] ) + or "" +end + +local bin_prefix = rightmost( "bin_prefix" ) +local bin_suffix = rightmost( "bin_suffix" ) +local obj_suffix = rightmost( "obj_suffix" ) +local lib_prefix = rightmost( "lib_prefix" ) +local lib_suffix = rightmost( "lib_suffix" ) +local prebuilt_lib_dir = rightmost( "prebuilt_lib_dir" ) +prebuilt_lib_dir = prebuilt_lib_dir == "" and OS_config or prebuilt_lib_dir +local cxxflags = concat( "cxxflags" ) +local ldflags = concat( "ldflags" ) + +toolchain = rightmost( "toolchain" ) + +local dir = "build/" .. OS_config +local output = { } + +local function flatten_into( res, t ) + for _, x in ipairs( t ) do + if type( x ) == "table" then + flatten_into( res, x ) + else + table.insert( res, x ) + end + end +end + +local function flatten( t ) + local res = { } + flatten_into( res, t ) + return res +end + +local function join( names, suffix, prefix ) + if not names then + return "" + end + + prefix = prefix or "" + local flat = flatten( names ) + for i = 1, #flat do + flat[ i ] = dir .. "/" .. prefix .. flat[ i ] .. suffix + end + return table.concat( flat, " " ) +end + +local function joinpb( names, suffix, prefix ) + if not names then + return "" + end + + prefix = prefix or "" + local flat = flatten( names ) + for i = 1, #flat do + flat[ i ] = "libs/" .. flat[ i ] .. "/" .. prebuilt_lib_dir .. "/" .. prefix .. flat[ i ] .. suffix + end + return table.concat( flat, " " ) +end + +function printf( form, ... ) + print( form:format( ... ) ) +end + +local objs = { } +local objs_flags = { } +local objs_extra_flags = { } + +local bins = { } +local bins_flags = { } +local bins_extra_flags = { } + +local libs = { } + +local function glob_impl( dir, rel, res, prefix, suffix, recursive ) + for filename in lfs.dir( dir .. rel ) do + if filename ~= "." and filename ~= ".." then + local fullpath = dir .. rel .. "/" .. filename + local attr = lfs.attributes( fullpath ) + + if attr.mode == "directory" then + if recursive then + glob_impl( dir, rel .. "/" .. filename, res, prefix, suffix, true ) + end + else + local prefix_start = dir:len() + rel:len() + 2 + if fullpath:find( prefix, prefix_start, true ) == prefix_start and fullpath:sub( -suffix:len() ) == suffix then + table.insert( res, fullpath ) + end + end + end + end +end + +local function glob( srcs ) + local res = { } + for _, pattern in ipairs( flatten( srcs ) ) do + if pattern:find( "*", 1, true ) then + local dir, prefix, suffix = pattern:match( "^(.-)/?([^/*]*)%*+(.*)$" ) + local recursive = pattern:find( "**", 1, true ) ~= nil + assert( not recursive or prefix == "" ) + + glob_impl( dir, "", res, prefix, suffix, recursive ) + else + table.insert( res, pattern ) + end + end + return res +end + +local function add_srcs( srcs ) + for _, src in ipairs( srcs ) do + if not objs[ src ] then + objs[ src ] = { } + end + end +end + +function bin( bin_name, cfg ) + assert( type( cfg ) == "table", "cfg should be a table" ) + assert( type( cfg.srcs ) == "table", "cfg.srcs should be a table" ) + assert( not cfg.libs or type( cfg.libs ) == "table", "cfg.libs should be a table or nil" ) + assert( not cfg.prebuilt_libs or type( cfg.prebuilt_libs ) == "table", "cfg.prebuilt_libs should be a table or nil" ) + assert( not bins[ bin_name ] ) + + bins[ bin_name ] = cfg + cfg.srcs = glob( cfg.srcs ) + add_srcs( cfg.srcs ) +end + +function lib( lib_name, srcs ) + assert( type( srcs ) == "table", "srcs should be a table" ) + assert( not libs[ lib_name ] ) + + local globbed = glob( srcs ) + libs[ lib_name ] = globbed + add_srcs( globbed ) +end + +function obj_cxxflags( pattern, flags ) + table.insert( objs_extra_flags, { pattern = pattern, flags = flags } ) +end + +function obj_dependencies( src, dependencies ) + objs[ src ].dependencies = dependencies +end + +function obj_replace_cxxflags( pattern, flags ) + table.insert( objs_flags, { pattern = pattern, flags = flags } ) +end + +local function toolchain_helper( t, f ) + return function( ... ) + if toolchain == t then + f( ... ) + end + end +end + +msvc_obj_cxxflags = toolchain_helper( "msvc", obj_cxxflags ) +msvc_obj_replace_cxxflags = toolchain_helper( "msvc", obj_replace_cxxflags ) + +gcc_obj_cxxflags = toolchain_helper( "gcc", obj_cxxflags ) +gcc_obj_replace_cxxflags = toolchain_helper( "gcc", obj_replace_cxxflags ) + +printf( "builddir = build" ) +printf( "cxxflags = %s", cxxflags ) +printf( "ldflags = %s", ldflags ) + +if toolchain == "msvc" then + +printf( "lua = ggbuild/lua.exe" ) + +printf( [[ +rule cpp + command = cl /showIncludes $cxxflags $extra_cxxflags -Fo$out $in + description = $in + deps = msvc + +rule bin + command = link /OUT:$out $in $ldflags $extra_ldflags + description = $out + +rule lib + command = lib /NOLOGO /OUT:$out $in + description = $out + +rule rc + command = rc /fo$out /nologo $in_rc + description = $in +]] ) + +elseif toolchain == "gcc" then + +printf( "cpp = %s", rightmost( "cxx" ) ) +printf( "lua = ggbuild/lua.linux" ) +printf( [[ +rule cpp + command = $cpp -MD -MF $out.d $cxxflags $extra_cxxflags -c -o $out $in + depfile = $out.d + description = $in + deps = gcc + +rule bin + command = $cpp -o $out $in $ldflags $extra_ldflags + description = $out + +rule lib + command = ar rs $out $in + description = $out +]] ) + +end + +local function rule_for_src( src_name ) + local ext = src_name:match( "([^%.]+)$" ) + return ( { cc = "cpp" } )[ ext ] +end + +local function write_ninja_script() + for _, flag in ipairs( objs_flags ) do + for name, cfg in pairs( objs ) do + if name:match( flag.pattern ) then + cfg.cxxflags = flag.flags + end + end + end + + for _, flag in ipairs( objs_extra_flags ) do + for name, cfg in pairs( objs ) do + if name:match( flag.pattern ) then + cfg.extra_cxxflags = ( cfg.extra_cxxflags or "" ) .. " " .. flag.flags + end + end + end + + for src_name, cfg in pairs( objs ) do + local rule = rule_for_src( src_name ) + local deps = cfg.dependencies and ( " | " .. cfg.dependencies ) or "" + printf( "build %s/%s%s: %s %s%s", dir, src_name, obj_suffix, rule, src_name, deps ) + if cfg.cxxflags then + printf( " cxxflags = %s", cfg.cxxflags ) + end + if cfg.extra_cxxflags then + printf( " extra_cxxflags = %s", cfg.extra_cxxflags ) + end + end + + for lib_name, srcs in pairs( libs ) do + printf( "build %s/%s%s%s: lib %s", dir, lib_prefix, lib_name, lib_suffix, join( srcs, obj_suffix ) ) + end + + for bin_name, cfg in pairs( bins ) do + local srcs = { cfg.srcs } + + if OS == "windows" and cfg.rc then + srcs = { cfg.srcs, cfg.rc } + printf( "build %s/%s%s: rc %s.rc", dir, cfg.rc, obj_suffix, cfg.rc ) + printf( " in_rc = %s.rc", cfg.rc ) + end + + local full_name = bin_prefix .. bin_name .. bin_suffix + printf( "build %s: bin %s %s %s", + full_name, + join( srcs, obj_suffix ), + join( cfg.libs, lib_suffix, lib_prefix ), + joinpb( cfg.prebuilt_libs, lib_suffix, lib_prefix ) + ) + + local ldflags_key = toolchain .. "_ldflags" + local extra_ldflags_key = toolchain .. "_extra_ldflags" + if cfg[ ldflags_key ] then + printf( " ldflags = %s", cfg[ ldflags_key ] ) + end + if cfg[ extra_ldflags_key ] then + printf( " extra_ldflags = %s", cfg[ extra_ldflags_key ] ) + end + + printf( "default %s", full_name ) + end +end + +automatically_print_output_at_exit = setmetatable( { }, { __gc = write_ninja_script } ) diff --git a/ggbuild/lua.linux b/ggbuild/lua.linux Binary files differ. diff --git a/ggbuild/ninja.linux b/ggbuild/ninja.linux Binary files differ. diff --git a/ggbuild/ninja_timeline.lua b/ggbuild/ninja_timeline.lua @@ -0,0 +1,45 @@ +local graph_width = 85 +local filename_length = 16 + +local log = io.open( "build/.ninja_log", "r" ):read( "*all" ) + +local edges = { } + +for line in log:gmatch( "([^\n]+)" ) do + local start, finish, target = line:match( "^(%d+)%s+(%d+)%s+%d+%s+(%S+)" ) + if start then + table.insert( edges, { + start = tonumber( start ), + dt = tonumber( finish ) - tonumber( start ), + target = target:match( "[^/]+$" ), + } ) + end +end + +table.sort( edges, function( a, b ) + return a.start < b.start +end ) + +local function truncate( str, len ) + str = str:gsub( "%.pic", "" ):gsub( "%.obj", "" ):gsub( "%.o", "" ) + return str:sub( 1, len ) .. string.rep( " ", len - str:len() ) +end + +local total_duration = edges[ #edges ].start + edges[ #edges ].dt + +for i, e in ipairs( edges ) do + local pre = math.floor( graph_width * e.start / total_duration ) + local width = math.max( 0, math.floor( graph_width * e.dt / total_duration - 2 ) ) + + local target = truncate( e.target, filename_length ) + local spacing = string.rep( " ", pre ) + + if i % 2 == 0 then + spacing = spacing:gsub( " ", " - " ) + end + + print( ( "%s %s[%s] %.2fs" ):format( target, spacing, string.rep( ">", width ), e.dt / 1000 ) ) +end + +print() +print( ( "Total build time: %.2fs" ):format( total_duration / 1000 ) ) diff --git a/ggbuild/pack_lua.lua b/ggbuild/pack_lua.lua @@ -0,0 +1,53 @@ +if not arg[ 1 ] or not arg[ 2 ] then + print( arg[ 0 ] .. " <source directory> <path to main>" ) + os.exit( 1 ) +end + +local lfs = require( "INTERNAL_LFS" ) + +local merged = { } + +local root = arg[ 1 ] +local main = arg[ 2 ] + +local function addDir( rel ) + for file in lfs.dir( root .. "/" .. rel ) do + if file ~= "." and file ~= ".." then + local full = root .. "/" .. rel .. file + local attr = lfs.attributes( full ) + + if attr.mode == "directory" then + addDir( rel .. file .. "/" ) + elseif file:match( "%.lua$" ) and ( rel ~= "" or file ~= main ) then + local f = io.open( full, "r" ) + local contents = f:read( "*all" ) + f:close() + + table.insert( merged, ( [[ + package.preload[ "%s" ] = function( ... ) + %s + end]] ):format( + ( rel .. file ):gsub( "%.lua$", "" ):gsub( "/", "." ), + contents + ) + ) + end + end + end +end + +addDir( "" ) + +local f = io.open( root .. "/" .. main, "r" ) +local contents = f:read( "*all" ) +f:close() + +table.insert( merged, contents ) + +local combined = table.concat( merged, "\n" ) + +local f = io.open( "build/lua_combined.h", "w" ) +for i = 1, #combined do + f:write( string.byte( combined, i ) .. "," ) +end +f:close() diff --git a/scripts/example_scripts.nsi b/installer/example_scripts.nsi diff --git a/scripts/licenses.txt b/installer/licenses.txt diff --git a/installer/mudgangster.nsi b/installer/mudgangster.nsi @@ -0,0 +1,56 @@ +!include "MUI2.nsh" + +Name "Mud Gangster" +Outfile "MudGangsterInstaller.exe" + +InstallDir "$PROGRAMFILES64\Mud Gangster" +RequestExecutionLevel admin + +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +Section "Install" SectionInstall + # Install stuff + SetOutPath $INSTDIR + File ..\release\mudgangster.exe + File licenses.txt + + # Start menu shortcut + CreateDirectory "$SMPROGRAMS\Mud Gangster" + CreateShortCut "$SMPROGRAMS\Mud Gangster\Mud Gangster.lnk" "$INSTDIR\mudgangster.exe" + + # Uninstaller + WriteUninstaller "$INSTDIR\uninstall.exe" + + # Registry keys + SetRegView 64 + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "DisplayName" "Mud Gangster" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "UninstallString" "$INSTDIR\uninstall.exe" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "DisplayIcon" "$INSTDIR\mudgangster.exe" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "Publisher" "Hirve" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "DisplayVersion" "0.0.0.0" + WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "NoModify" 1 + WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "NoRepair" 1 + + SectionGetSize ${SectionInstall} $0 + IntFmt $1 "0x%08X" $0 + WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "EstimatedSize" $1 +SectionEnd + +Section "Uninstall" + # Files + Delete "$INSTDIR\MudGangster.exe" + Delete "$INSTDIR\licenses.txt" + Delete "$INSTDIR\uninstall.exe" + RMDir "$INSTDIR" + + # Start menu shortcut + Delete "$SMPROGRAMS\Mud Gangster\Mud Gangster.lnk" + RMDir "$SMPROGRAMS\Mud Gangster" + + # Registry keys + SetRegView 64 + DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" +SectionEnd diff --git a/libs/lfs.lua b/libs/lfs.lua @@ -1,4 +1,3 @@ -lib( "lfs", { "libs/lfs/lfs" } ) --- obj_replace_cxxflags( "libs/lpeg/%", "-c -O2 -x c" ) -obj_cxxflags( "libs/lfs/%", "/c /TC /I libs/lua" ) -obj_cxxflags( "libs/lfs/%", "/wd4267" ) +lib( "lfs", { "libs/lfs/lfs.cc" } ) +obj_cxxflags( "libs/lfs/.*", "/c /TC /I libs/lua" ) +obj_cxxflags( "libs/lfs/.*", "/wd4267" ) diff --git a/libs/lpeg.lua b/libs/lpeg.lua @@ -1,10 +1,3 @@ -lib( "lpeg", { - "libs/lpeg/lpcap", - "libs/lpeg/lpcode", - "libs/lpeg/lpprint", - "libs/lpeg/lptree", - "libs/lpeg/lpvm", -} ) --- obj_replace_cxxflags( "libs/lpeg/%", "-c -O2 -x c" ) -obj_cxxflags( "libs/lpeg/%", "/c /TC /I libs/lua" ) -obj_cxxflags( "libs/lpeg/%", "/wd4244 /wd4267" ) +lib( "lpeg", { "libs/lpeg/*.cc" } ) +obj_cxxflags( "libs/lpeg/.*", "/c /TC /I libs/lua" ) +obj_cxxflags( "libs/lpeg/.*", "/wd4244 /wd4267" ) diff --git a/libs/lua.lua b/libs/lua.lua @@ -1,38 +1,37 @@ lib( "lua", { - "libs/lua/lapi", - "libs/lua/lcode", - "libs/lua/lctype", - "libs/lua/ldebug", - "libs/lua/ldo", - "libs/lua/ldump", - "libs/lua/lfunc", - "libs/lua/lgc", - "libs/lua/llex", - "libs/lua/lmem", - "libs/lua/lobject", - "libs/lua/lopcodes", - "libs/lua/lparser", - "libs/lua/lstate", - "libs/lua/lstring", - "libs/lua/ltable", - "libs/lua/ltm", - "libs/lua/lundump", - "libs/lua/lvm", - "libs/lua/lzio", - "libs/lua/lauxlib", - "libs/lua/lbaselib", - "libs/lua/lbitlib", - "libs/lua/lcorolib", - "libs/lua/ldblib", - "libs/lua/liolib", - "libs/lua/lmathlib", - "libs/lua/loslib", - "libs/lua/lstrlib", - "libs/lua/ltablib", - "libs/lua/lutf8lib", - "libs/lua/loadlib", - "libs/lua/linit", + "libs/lua/lapi.cc", + "libs/lua/lcode.cc", + "libs/lua/lctype.cc", + "libs/lua/ldebug.cc", + "libs/lua/ldo.cc", + "libs/lua/ldump.cc", + "libs/lua/lfunc.cc", + "libs/lua/lgc.cc", + "libs/lua/llex.cc", + "libs/lua/lmem.cc", + "libs/lua/lobject.cc", + "libs/lua/lopcodes.cc", + "libs/lua/lparser.cc", + "libs/lua/lstate.cc", + "libs/lua/lstring.cc", + "libs/lua/ltable.cc", + "libs/lua/ltm.cc", + "libs/lua/lundump.cc", + "libs/lua/lvm.cc", + "libs/lua/lzio.cc", + "libs/lua/lauxlib.cc", + "libs/lua/lbaselib.cc", + "libs/lua/lbitlib.cc", + "libs/lua/lcorolib.cc", + "libs/lua/ldblib.cc", + "libs/lua/liolib.cc", + "libs/lua/lmathlib.cc", + "libs/lua/loslib.cc", + "libs/lua/lstrlib.cc", + "libs/lua/ltablib.cc", + "libs/lua/lutf8lib.cc", + "libs/lua/loadlib.cc", + "libs/lua/linit.cc", } ) --- obj_replace_cxxflags( "libs/lua/%", "-c -O2 -x c -DLUA_COMPAT_5_2 -DLUA_USE_LINUX" ) -obj_cxxflags( "libs/lua/%", "/c /TC /DLUA_COMPAT_5_2" ) -obj_cxxflags( "libs/lua/%", "/wd4244 /wd4310" ) +obj_cxxflags( "libs/lua/.*", "/c /TC /DLUA_COMPAT_5_2" ) +obj_cxxflags( "libs/lua/.*", "/wd4244 /wd4310" ) diff --git a/make.lua b/make.lua @@ -1,18 +1,49 @@ -require( "scripts.gen_makefile" ) +require( "ggbuild.gen_ninja" ) -local platform_objs = { "src/main", "src/x11" } -local libs = { } +obj_cxxflags( ".*", "-I source -I libs" ) + +msvc_obj_cxxflags( ".*", "/W4 /wd4100 /wd4146 /wd4189 /wd4201 /wd4307 /wd4324 /wd4351 /wd4127 /wd4505 /wd4530 /wd4702 /wd4706 /D_CRT_SECURE_NO_WARNINGS" ) +msvc_obj_cxxflags( ".*", "/wd4244 /wd4267" ) -- silence conversion warnings because there are tons of them +msvc_obj_cxxflags( ".*", "/fp:fast /GR- /EHs-c-" ) + +gcc_obj_cxxflags( ".*", "-std=c++11 -msse3 -ffast-math -fno-exceptions -fno-rtti -fno-strict-aliasing -fno-strict-overflow -fvisibility=hidden" ) +gcc_obj_cxxflags( ".*", "-Wall -Wextra -Wcast-align -Wvla -Wformat-security" ) -- -Wconversion +gcc_obj_cxxflags( ".*", "-Wno-unused-parameter -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-format-truncation" ) +gcc_obj_cxxflags( ".*", "-Werror=vla -Werror=format-security -Werror=unused-value" ) + +local platform_srcs, platform_libs if OS == "windows" then require( "libs.lua" ) require( "libs.lpeg" ) require( "libs.lfs" ) - platform_objs = "src/win32" - libs = { "lua", "lpeg", "lfs" } + platform_srcs = "src/win32.cc" + platform_libs = { "lua", "lpeg", "lfs" } +else + platform_srcs = "src/x11.cc" + platform_libs = { } end -bin( "mudgangster", { platform_objs, "src/ui", "src/script", "src/textbox", "src/input", "src/platform_network", "src/rc" }, libs ) -rc( "src/rc" ) -msvc_bin_ldflags( "mudgangster", "gdi32.lib Ws2_32.lib" ) -gcc_bin_ldflags( "mudgangster", "-lm -lX11 -llua" ) +bin( "mudgangster", { + srcs = { + platform_srcs, + "src/ui.cc", "src/script.cc", "src/textbox.cc", "src/input.cc", "src/platform_network.cc", + }, + + libs = platform_libs, + + rc = "src/rc", + + msvc_extra_ldflags = "gdi32.lib Ws2_32.lib", + gcc_extra_ldflags = "-lm -lX11 -llua", +} ) + +obj_dependencies( "src/script.cc", "build/lua_combined.h" ) + +printf( [[ +rule combine-lua + command = $lua ggbuild/pack_lua.lua src/lua main.lua + description = lua_combined.h +]] ) +print( "build build/lua_combined.h: combine-lua | ggbuild/pack_lua.lua" ) diff --git a/scripts/bin2arr.lua b/scripts/bin2arr.lua @@ -1,8 +0,0 @@ -local i = 0 -for c in io.stdin:lines( 1 ) do - if i > 0 and i % 16 == 0 then - print() - end - i = i + 1 - io.stdout:write( string.byte( c ) .. "," ) -end diff --git a/scripts/gen_makefile.lua b/scripts/gen_makefile.lua @@ -1,333 +0,0 @@ -local function copy( t ) - local res = { } - for k, v in pairs( t ) do - res[ k ] = v - end - return res -end - -local configs = { - [ "windows" ] = { - bin_suffix = ".exe", - obj_suffix = ".obj", - lib_suffix = ".lib", - - toolchain = "msvc", - - cxxflags = "/I . /I src /c /Oi /Gm- /GR- /EHa- /EHsc /nologo /DNOMINMAX /DWIN32_LEAN_AND_MEAN", - ldflags = "user32.lib shell32.lib advapi32.lib dbghelp.lib /nologo", - warnings = "/W4 /wd4100 /wd4146 /wd4189 /wd4201 /wd4324 /wd4351 /wd4127 /wd4505 /wd4530 /wd4702 /D_CRT_SECURE_NO_WARNINGS", - }, - - [ "windows-64" ] = { }, - - [ "windows-debug" ] = { - cxxflags = "/Od /MTd /Z7 /Zo", - ldflags = "/Od /MTd /Z7 /Zo", - }, - [ "windows-release" ] = { - cxxflags = "/O2 /MT /DRELEASE_BUILD", - bin_prefix = "release/", - }, - - [ "linux" ] = { - obj_suffix = ".o", - lib_prefix = "lib", - lib_suffix = ".a", - - toolchain = "gcc", - cxx = "g++", - - cxxflags = "-I src -c -x c++ -std=c++11 -msse2 -ffast-math -fno-exceptions -fno-rtti -fno-strict-aliasing -fno-strict-overflow -fdiagnostics-color", - ldflags = "-lm -lpthread -ldl", - warnings = "-Wall -Wextra -Wno-unused-parameter -Wno-unused-function -Wshadow -Wcast-align -Wstrict-overflow -Wvla", -- -Wconversion - }, - - [ "linux-64" ] = { }, - - [ "linux-debug" ] = { - cxxflags = "-O0 -ggdb3 -fno-omit-frame-pointer", - }, - [ "linux-asan" ] = { - bin_suffix = "-asan", - cxxflags = "-O0 -ggdb3 -fno-omit-frame-pointer -fsanitize=address", - ldflags = "-fsanitize=address", - }, - [ "linux-release" ] = { - cxxflags = "-O2 -DRELEASE_BUILD", - ldflags = "-s", - bin_prefix = "release/", - }, - - -- TODO: mingw? -} - -configs[ "macos" ] = copy( configs[ "linux" ] ) -configs[ "macos" ].cxx = "clang++" --- TODO: this is not quite right because it can get nuked by gcc_obj_replace_cxxflags -configs[ "macos" ].cxxflags = configs[ "macos" ].cxxflags .. " -mmacosx-version-min=10.9" -configs[ "macos" ].ldflags = "-lm" - -configs[ "macos-64" ] = copy( configs[ "linux-64" ] ) -configs[ "macos-debug" ] = copy( configs[ "linux-debug" ] ) -configs[ "macos-asan" ] = copy( configs[ "linux-asan" ] ) -configs[ "macos-release" ] = copy( configs[ "linux-release" ] ) -configs[ "macos-release" ].ldflags = "-Wl,-dead_strip -Wl,-x" - -configs[ "openbsd" ] = copy( configs[ "linux" ] ) -configs[ "openbsd" ].cxx = "clang++" -configs[ "openbsd" ].cxxflags = configs[ "openbsd" ].cxxflags .. " -I/usr/local/include" -configs[ "openbsd" ].ldflags = "-lm -lpthread -lexecinfo -L/usr/local/lib" - -configs[ "openbsd-64" ] = copy( configs[ "linux-64" ] ) -configs[ "openbsd-debug" ] = copy( configs[ "linux-debug" ] ) - -configs[ "openbsd-release" ] = { - cxxflags = "-O2", - ldflags = "-s", -} - -local function identify_host() - local dll_ext = package.cpath:match( "(%a+)$" ) - - if dll_ext == "dll" or os.getenv( "WSLENV" ) then - return "windows", "64" - end - - local p = assert( io.popen( "uname -s" ) ) - local uname = assert( p:read( "*all" ) ):gsub( "%s*$", "" ) - assert( p:close() ) - - if uname == "Linux" then - return "linux", "64" - end - - if uname == "Darwin" then - return "macos", "64" - end - - if uname == "OpenBSD" then - return "openbsd", "64" - end - - io.stderr:write( "can't identify host OS" ) - os.exit( 1 ) -end - -OS, arch = identify_host() -config = arg[ 1 ] or "debug" - -local double_arch = OS .. "-" .. arch -local double_config = OS .. "-" .. config -local triple = OS .. "-" .. arch .. "-" .. config - -if not configs[ double_arch ] or not configs[ double_config ] then - io.stderr:write( "bad config: " .. triple .. "\n" ) - os.exit( 1 ) -end - -local function concat( key ) - return "" - .. ( ( configs[ OS ] and configs[ OS ][ key ] ) or "" ) - .. " " - .. ( ( configs[ double_arch ] and configs[ double_arch ][ key ] ) or "" ) - .. " " - .. ( ( configs[ double_config ] and configs[ double_config ][ key ] ) or "" ) -end - -local function rightmost( key ) - return nil - or ( configs[ double_config ] and configs[ double_config ][ key ] ) - or ( configs[ double_arch ] and configs[ double_arch ][ key ] ) - or ( configs[ OS ] and configs[ OS ][ key ] ) - or "" -end - -local bin_prefix = rightmost( "bin_prefix" ) -local bin_suffix = rightmost( "bin_suffix" ) -local obj_suffix = rightmost( "obj_suffix" ) -local lib_prefix = rightmost( "lib_prefix" ) -local lib_suffix = rightmost( "lib_suffix" ) -local cxxflags = concat( "cxxflags" ) .. " " .. concat( "warnings" ) -local ldflags = concat( "ldflags" ) - -toolchain = rightmost( "toolchain" ) - -local dir = "build/" .. triple -local output = { } - -local function join( names, suffix, prefix ) - if not names then - return "" - end - - prefix = prefix or "" - local res = { } - for i, name in ipairs( names ) do - if type( name ) == "table" then - res[ i ] = join( name, suffix, prefix ) - else - res[ i ] = dir .. "/" .. prefix .. names[ i ] .. suffix - end - end - return table.concat( res, " " ) -end - -local function printh( form, ... ) - print( form:format( ... ) ) -end - -local function printf( form, ... ) - table.insert( output, form:format( ... ) ) -end - -function bin( bin_name, objs, libs ) - assert( type( objs ) == "table", "objs should be a table" ) - assert( not libs or type( libs ) == "table", "libs should be a table or nil" ) - local bin_path = ( "%s%s%s" ):format( bin_prefix, bin_name, bin_suffix ) - printh( "BINS += %s", bin_path ) - printf( "%s: %s %s", bin_path, join( objs, obj_suffix ), join( libs, lib_suffix, lib_prefix ) ) - printf( "clean::\n\trm -f %s", bin_path ) -end - -function lib( lib_name, objs ) - assert( type( objs ) == "table", "objs should be a table" ) - printf( "%s/%s%s%s: %s", dir, lib_prefix, lib_name, lib_suffix, join( objs, obj_suffix ) ) -end - -function rc( rc_name ) - if OS == "windows" then - printf( "%s/%s%s: %s.rc", dir, rc_name, obj_suffix, rc_name, rc_name ) - printf( "\t@printf \"\\033[1;33mbuilding $@\\033[0m\\n\"" ) - printf( "\t@mkdir -p \"$(@D)\"" ) - printf( "\t@rc.exe /fo$@ /nologo $<" ) - else - local cxx = rightmost( "cxx" ) - printf( "%s/%s%s:", dir, rc_name, obj_suffix ) - printf( "\t@printf \"\\033[1;33mbuilding $@\\033[0m\\n\"" ) - printf( "\t@mkdir -p \"$(@D)\"" ) - printf( "\t@%s -c -x c++ /dev/null -o $@", cxx ) - end -end - -function bin_ldflags( bin_name, ldflags ) - local bin_path = ( "%s%s%s" ):format( bin_prefix, bin_name, bin_suffix ) - printf( "%s: LDFLAGS += %s", bin_path, ldflags ) -end - -function obj_cxxflags( obj_name, cxxflags ) - printf( "%s/%s%s: CXXFLAGS += %s", dir, obj_name, obj_suffix, cxxflags ) -end - -function obj_replace_cxxflags( obj_name, cxxflags ) - printf( "%s/%s%s: CXXFLAGS := %s", dir, obj_name, obj_suffix, cxxflags ) -end - -local function toolchain_helper( t, f ) - return function( ... ) - if toolchain == t then - f( ... ) - end - end -end - -msvc_bin_ldflags = toolchain_helper( "msvc", bin_ldflags ) -msvc_obj_cxxflags = toolchain_helper( "msvc", obj_cxxflags ) -msvc_obj_replace_cxxflags = toolchain_helper( "msvc", obj_replace_cxxflags ) - -gcc_bin_ldflags = toolchain_helper( "gcc", bin_ldflags ) -gcc_obj_cxxflags = toolchain_helper( "gcc", obj_cxxflags ) -gcc_obj_replace_cxxflags = toolchain_helper( "gcc", obj_replace_cxxflags ) - -printf( "CXXFLAGS := %s", cxxflags ) -printf( "LDFLAGS := %s", ldflags ) -printf( "MAKEFLAGS += -r" ) - -printf( "" ) -printf( "all: $(BINS)" ) -printf( "" ) - -if toolchain == "msvc" then - -printf( [[ -VC = ${ProgramFiles(x86)}\Microsoft Visual Studio 14.0\VC -KIT81 = ${ProgramFiles(x86)}\Windows Kits\8.1 -KIT10 = ${ProgramFiles(x86)}\Windows Kits\10 -DX = ${ProgramFiles(x86)}\Microsoft DirectX SDK (June 2010) - -export INCLUDE := $(VC)\include;$(KIT10)\Include\10.0.10240.0\ucrt;$(KIT81)\Include\shared;$(DX)\Include;$(KIT81)\Include\um;$(KIT81)\Include\winrt -export LIB := $(VC)\lib\amd64;$(KIT10)\Lib\10.0.10240.0\ucrt\x64;$(KIT81)\lib\winv6.3\um\x64 -export PATH := /cygdrive/c/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/:/cygdrive/c/Program Files (x86)/Windows Kits/8.1/bin/x64/:$(PATH) -]] ) - -printf( [[ -$(BINS): %%: - @printf "\033[1;31mbuilding $@\033[0m\n" - @mkdir -p "$(@D)" - @cl.exe -Fe$@ $^ $(LDFLAGS) -]] ) -printf( [[ -%s/%%%s: %%.cc - @printf "\033[1;32mbuilding $<\033[0m\n" - @mkdir -p "$(@D)" - @cl.exe $(CXXFLAGS) -Fo$@ $^ -]], dir, obj_suffix ) -printf( [[ -$(OBJS): %%: - @printf "\033[1;32mbuilding $<\033[0m\n" - @mkdir -p "$(@D)" - @cl.exe $(CXXFLAGS) -Fo$@ -Tp$< -]] ) -printf( [[ -%%%s: - @printf "\033[1;35mbuilding $@\033[0m\n" - @mkdir -p "$(@D)" - @lib.exe -OUT:$@ $^ -]], lib_suffix ) - -elseif toolchain == "gcc" then - -local cxx = rightmost( "cxx" ) - -printf( [[ -$(BINS): %%: - @env printf "\033[1;31mbuilding $@\033[0m\n" - @mkdir -p "$(@D)" - @%s -o $@ $^ $(LDFLAGS) -]], cxx ) -printf( [[ -%s/%%%s: %%.cc - @env printf "\033[1;32mbuilding $<\033[0m\n" - @mkdir -p "$(@D)" - @%s $(CXXFLAGS) -o $@ $< -MMD -MP -]], dir, obj_suffix, cxx ) -printf( [[ -$(OBJS): %%: - @env printf "\033[1;32mbuilding $<\033[0m\n" - @mkdir -p "$(@D)" - @%s $(CXXFLAGS) -o $@ $< -MMD -MP -]], cxx ) -printf( [[ -%%%s: - @env printf "\033[1;35mbuilding $@\033[0m\n" - @mkdir -p "$(@D)" - @$(AR) rs $@ $^ -]], lib_suffix ) - --- you can't -include %s/**.d, so let's hardcode 6 levels and hope that's enough -printf( "-include %s/*.d", dir ) -printf( "-include %s/*/*.d", dir ) -printf( "-include %s/*/*/*.d", dir ) -printf( "-include %s/*/*/*/*.d", dir ) -printf( "-include %s/*/*/*/*/*.d", dir ) -printf( "-include %s/*/*/*/*/*/*.d", dir ) - -end - -printf( "clean::\n\trm -rf build release" ) - -automatically_print_output_at_exit = setmetatable( { }, { - __gc = function() - print( table.concat( output, "\n" ) ) - end -} ) diff --git a/scripts/installer.nsi b/scripts/installer.nsi @@ -1,56 +0,0 @@ -!include "MUI2.nsh" - -Name "Mud Gangster" -Outfile "MudGangsterInstaller.exe" - -InstallDir "$PROGRAMFILES64\Mud Gangster" -RequestExecutionLevel admin - -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -Section "Install" SectionInstall - # Install stuff - SetOutPath $INSTDIR - File ..\release\mudgangster.exe - File licenses.txt - - # Start menu shortcut - CreateDirectory "$SMPROGRAMS\Mud Gangster" - CreateShortCut "$SMPROGRAMS\Mud Gangster\Mud Gangster.lnk" "$INSTDIR\mudgangster.exe" - - # Uninstaller - WriteUninstaller "$INSTDIR\uninstall.exe" - - # Registry keys - SetRegView 64 - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "DisplayName" "Mud Gangster" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "UninstallString" "$INSTDIR\uninstall.exe" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "DisplayIcon" "$INSTDIR\mudgangster.exe" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "Publisher" "Hirve" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "DisplayVersion" "0.0.0.0" - WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "NoModify" 1 - WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "NoRepair" 1 - - SectionGetSize ${SectionInstall} $0 - IntFmt $1 "0x%08X" $0 - WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" "EstimatedSize" $1 -SectionEnd - -Section "Uninstall" - # Files - Delete "$INSTDIR\MudGangster.exe" - Delete "$INSTDIR\licenses.txt" - Delete "$INSTDIR\uninstall.exe" - RMDir "$INSTDIR" - - # Start menu shortcut - Delete "$SMPROGRAMS\Mud Gangster\Mud Gangster.lnk" - RMDir "$SMPROGRAMS\Mud Gangster" - - # Registry keys - SetRegView 64 - DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MudGangster" -SectionEnd diff --git a/scripts/merge.lua b/scripts/merge.lua @@ -1,46 +0,0 @@ -if not arg[ 1 ] or not arg[ 2 ] then - print( arg[ 0 ] .. " <source directory> <path to main> [Lua version]" ) - os.exit( 1 ) -end - -local lfs = require( "lfs" ) - -local merged = { } - -local root = arg[ 1 ] -local main = arg[ 2 ] - -local function addDir( rel ) - for file in lfs.dir( root .. "/" .. rel ) do - if file ~= "." and file ~= ".." then - local full = root .. "/" .. rel .. file - local attr = lfs.attributes( full ) - - if attr.mode == "directory" then - addDir( rel .. file .. "/" ) - elseif file:match( "%.lua$" ) and ( rel ~= "" or file ~= main ) then - local f = io.open( full, "r" ) - local contents = f:read( "*all" ) - f:close() - - table.insert( merged, ( [[ - package.preload[ "%s" ] = function( ... ) - %s - end]] ):format( - ( rel .. file ):gsub( "%.lua$", "" ):gsub( "/", "." ), - contents - ) - ) - end - end - end -end - -addDir( "" ) - -local f = io.open( root .. "/" .. main, "r" ) -local contents = f:read( "*all" ) -f:close() - -print( table.concat( merged, "\n" ) ) -print( contents ) diff --git a/scripts/pack_lua.sh b/scripts/pack_lua.sh @@ -1,7 +0,0 @@ -#! /bin/sh - -set -o pipefail - -mkdir -p build -lua scripts/merge.lua src/lua main.lua > build/lua_combined.lua -exec lua scripts/merge.lua src/lua main.lua | lua scripts/bin2arr.lua > build/lua_combined.h diff --git a/src/main.cc b/src/main.cc @@ -1,23 +0,0 @@ -#include "script.h" -#include "input.h" -#include "ui.h" -#include "platform_ui.h" -#include "platform_network.h" - -int main() { - net_init(); - ui_init(); - input_init(); - platform_ui_init(); - script_init(); - - event_loop(); - - script_term(); - platform_ui_term(); - input_term(); - ui_term(); - net_term(); - - return 0; -} diff --git a/src/ui.h b/src/ui.h @@ -59,5 +59,3 @@ void platform_send( void * sock, const char * data, size_t len ); void platform_close( void * sock ); bool ui_set_font( const char * name, int size ); - -void event_loop(); diff --git a/src/x11.cc b/src/x11.cc @@ -11,6 +11,7 @@ #include "script.h" #include "ui.h" +#include "platform_ui.h" #include "platform_network.h" struct Socket { @@ -572,7 +573,13 @@ static Socket * socket_from_fd( int fd ) { return NULL; } -void event_loop() { +int main() { + net_init(); + ui_init(); + input_init(); + platform_ui_init(); + script_init(); + ui_handleXEvents(); while( !closing ) { @@ -618,4 +625,12 @@ void event_loop() { ui_handleXEvents(); } + + script_term(); + platform_ui_term(); + input_term(); + ui_term(); + net_term(); + + return 0; }