#!BMK @define assemble local src = nvl(arg1, %infile%) local obj = nvl(arg2, %outfile%) if bmk.Platform() == "macos" then if bmk.CPU() == "ppc" then cmd = "as -arch ppc" elseif bmk.CPU() == "x86" then cmd = "as -arch i386" else cmd = "as -arch x86_64" end cmd = cmd .. " -W -o " .. bmk.Quote(obj) .. " " .. bmk.Quote(src) else if bmk.Platform() == "win32" then local prefix = bmk.Option("path_to_wine", "") if prefix ~= "" then prefix = prefix .. " " end cmd = prefix .. bmk.Quote(utils.BlitzMaxPath() .. "/bin/fasm.exe") .. " " else cmd = bmk.Quote(utils.BlitzMaxPath() .. "/bin/fasm") .. " " end if bmk.Platform() == "linux" or bmk.Platform() == "android" or bmk.Platform() == "raspberrypi" then cmd = cmd .. " -m32768 " end cmd = cmd .. bmk.Quote(src) .. " " .. bmk.Quote(obj) end if bmk.MultiSys(cmd, src, obj, "") ~= 0 then bmk.ThrowNew("Build Error: Failed to assemble " .. src) end @end @define assembleNative local src = nvl(arg1, %infile%) local obj = nvl(arg2, %outfile%) cmd = "as" if bmk.Platform() == "win32" then if bmk.CPU() == "x86" then cmd = cmd .. " -arch i686" else cmd = cmd .. " -arch generic64" end end cmd = cmd .. " -W -o " .. bmk.Quote(obj) .. " " .. bmk.Quote(src) if bmk.MultiSys(cmd, src, obj, "") ~= 0 then bmk.ThrowNew("Build Error: Failed to assemble " .. src) end @end @define compileBMX local src = nvl(arg1, %infile%) local obj = nvl(arg2, %outfile%) local opts = nvl(arg3, %options%) local gen = "" azm = sys.StripExt(obj) if bmk.BCCVersion() == "BlitzMax" then # remove any "NG" generated source. gen = azm .. ".c" else # remove any "legacy" generated source. gen = azm .. ".s" end azm = azm .. ".s" local bcc_app = "bcc" # if we are doing a universal build, be sure and call the correct bcc! if %universal% == "1" and bmk.CPU() == "ppc" then bcc_app = bcc_app .. "_ppc" end if bmk.OSPlatform() == "win32" then bcc_app = bcc_app .. ".exe" end local prefix = "" if bmk.Platform() == "win32" then prefix = bmk.Option("path_to_wine", "") if prefix ~= "" then prefix = prefix .. " " end end cmd = prefix .. bmk.Quote(utils.BlitzMaxPath() .. "/bin/" .. bcc_app) .." " .. opts .. " -o " .. bmk.Quote(azm) .. " " .. bmk.Quote(src) if bmk.MultiSys( cmd, src, obj, gen ) ~= 0 then bmk.ThrowNew("Build Error: failed to compile " .. src) end #if bmk.Platform() == "macos" and bmk.CPU() == "x86" and bmk.BCCVersion() == "BlitzMax" then # cmd = bmk.Quote(utils.BlitzMaxPath() .. "/bin/fasm2as") .. " " .. bmk.Quote(azm) # if bmk.Sys( cmd ) ~= 0 then # bmk.ThrowNew("Fasm2as failed - please contact BRL!") # end #end # TODO : we can't call another generated function from here... so we'd need to make sure this is called elsewhere. #assemble(nil, azm, obj) @end @define fasm2as local src = nvl(arg1, %infile%) local obj = nvl(arg2, %outfile%) local azm = sys.StripExt(obj) .. ".s" if bmk.Platform() == "macos" and bmk.CPU() == "x86" and bmk.BCCVersion() == "BlitzMax" then cmd = bmk.Quote(utils.BlitzMaxPath() .. "/bin/fasm2as") .. " " .. bmk.Quote(azm) if bmk.MultiSys( cmd, "", "", "" ) ~= 0 then bmk.ThrowNew("Fasm2as failed - please contact BRL!") end end @end @define compileC local src = nvl(arg1, %infile%) local obj = nvl(arg2, %outfile%) local opts = arg3 #opts = opts .. " " .. %cc_opts% .. " " .. %BMK_CC_OPTS% local ext = sys.ExtractExt(src) if bmk.Platform() == "macos" or bmk.Platform() == "osx" or bmk.Platform() == "ios" then if bmk.Platform() == "macos" or bmk.Platform() == "osx" then cmd = bmk.Option(bmk.BuildName("gcc"), "gcc") if ext == "cpp" or ext == "cxx" or ext == "mm" or ext == "cc" then cmd = bmk.Option(bmk.BuildName("gpp"), "g++") end else cmd = bmk.Option(bmk.BuildName("gcc"), "gcc") if ext == "cpp" or ext == "cxx" or ext == "mm" or ext == "cc" then cmd = bmk.Option(bmk.BuildName("gpp"), "g++") end end # need to use gcc, not llvm... # 10.7 # but for 10.8 we have no choice... if tonumber(%macos_version%) >= 4208 and tonumber(%macos_version%) < 4224 then cmd = cmd .. "-4.2" end if bmk.CPU() == "ppc" and (bmk.Platform() == "macos" or bmk.Platform() == "osx") then cmd = cmd .. " -arch ppc " elseif bmk.CPU() == "x86" then cmd = cmd .. " -arch i386 " elseif bmk.CPU() == "x64" then cmd = cmd .. " -arch x86_64 " elseif bmk.CPU() == "armv7" and bmk.Platform() == "ios" then cmd = cmd .. " -arch armv7 " elseif bmk.CPU() == "arm64" then cmd = cmd .. " -arch arm64 " end if bmk.Option(bmk.BuildName("sysroot"), "") ~= "" then cmd = cmd .. " -isysroot " .. bmk.Option(bmk.BuildName("sysroot"), "") end elseif bmk.Platform() == "win32" then local prefix = bmk.MinGWExePrefix() if bmk.OSPlatform() == "win32" then ext = ".exe" else ext = "" end cmd = bmk.Option("path_to_gcc", bmk.MinGWBinPath() .. "/" .. prefix .. "gcc" .. ext) if ext == "cpp" or ext == "cxx" or ext == "mm" or ext == "cc" then cmd = bmk.Option("path_to_gpp", bmk.MinGWBinPath() .. "/" .. prefix .. "g++" .. ext) end elseif bmk.Platform() == "linux" or bmk.Platform() == "android" or bmk.Platform() == "raspberrypi" or bmk.Platform() == "haiku" then cmd = bmk.Option(bmk.BuildName("gcc"), "gcc") if bmk.Option("nopie", "") == "true" then globals.SetOption("cc_opts", "pie", "") end elseif bmk.Platform() == "emscripten" then cmd = bmk.Option(bmk.BuildName("gcc"), "emcc") cmd = cmd .. " -Wno-warn-absolute-paths " elseif bmk.Platform() == "nx" then cmd = bmk.Option(bmk.BuildName("gcc"), "gcc") if ext == "cpp" or ext == "cxx" or ext == "mm" or ext == "cc" then cmd = bmk.Option(bmk.BuildName("gpp"), "g++") end end if bmk.Platform() == "nx" then cmd = cmd .. " -ffunction-sections" cmd = cmd .. " -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE" cmd = cmd .. " -I" .. bmk.Option("nx.devkitpro", "") .. "/libnx/include" cmd = cmd .. " -I" .. bmk.Option("nx.devkitpro", "") cmd = cmd .. " -I" .. bmk.Option("nx.devkitpro", "") .. "/portlibs/switch/include" end # disable warnings ? if %CC_WARNINGS% == "" then opts = opts .. " -w" end if bmk.BCCVersion() ~= "BlitzMax" then opts = opts .. " -DBMX_NG" if bmk.Platform() == "nx" then opts = opts .. " -D__SWITCH__" end end local genDebug = "" if bmk.IsDebugBuild() == 1 then genDebug = " -g" end # Remove -fno-exceptions if we have provided -fexceptions local cc_opts = %cc_opts% if cc_opts:find("-fexceptions") ~= nil then cc_opts = cc_opts:gsub("%-fno%-exceptions", print) end if opts:find("-fexceptions") ~= nil then cc_opts = cc_opts:gsub("%-fno%-exceptions", "") end cmd = cmd .. opts .. cc_opts .. %mod_ccopts% .. genDebug .. " -o " .. bmk.Quote(obj) .. " " .. bmk.Quote(src) if bmk.MultiSys( cmd, src, obj, "" ) ~= 0 then bmk.ThrowNew("Build Error: failed to compile " .. src) end @end @define addresourcepath globals.Add("resource_path", arg1) @end @define addlib globals.Add("libs", arg1) @end @define addoption globals.Add(arg1, arg2, 0) @end @define setoption globals.Add(arg1, arg2, 1) @end ## adds a cc_opt option @define addccopt globals.AddOption("cc_opts", arg1, arg2) @end @define setccopt globals.SetOption("cc_opts", arg1, arg2) @end @define addwin32ccopt if bmk.Platform() == "win32" then globals.AddOption("cc_opts", arg1, arg2) end @end @define setwin32ccopt if bmk.Platform() == "win32" then globals.SetOption("cc_opts", arg1, arg2) end @end @define setwin32x86ccopt if bmk.Platform() == "win32" and bmk.CPU() == "x86" then globals.SetOption("cc_opts", arg1, arg2) end @end @define setwin32x64ccopt if bmk.Platform() == "win32" and bmk.CPU() == "x64" then globals.SetOption("cc_opts", arg1, arg2) end @end @define addmacccopt if bmk.Platform() == "macos" then globals.AddOption("cc_opts", arg1, arg2) end @end @define setmacccopt if bmk.Platform() == "macos" then globals.SetOption("cc_opts", arg1, arg2) end @end @define addmacppcccopt if bmk.Platform() == "macos" and bmk.CPU() == "ppc" then globals.AddOption("cc_opts", arg1, arg2) end @end @define setmacppcccopt if bmk.Platform() == "macos" and bmk.CPU() == "ppc" then globals.SetOption("cc_opts", arg1, arg2) end @end @define addmacx86ccopt if bmk.Platform() == "macos" and bmk.CPU() == "x86" then globals.AddOption("cc_opts", arg1, arg2) end @end @define setmacx86ccopt if bmk.Platform() == "macos" and bmk.CPU() == "x86" then globals.SetOption("cc_opts", arg1, arg2) end @end @define addlinuxccopt if bmk.Platform() == "linux" or bmk.Platform() == "android" or bmk.Platform() == "raspberrypi" then globals.AddOption("cc_opts", arg1, arg2) end @end @define setlinuxccopt if bmk.Platform() == "linux" or bmk.Platform() == "android" or bmk.Platform() == "raspberrypi" then globals.SetOption("cc_opts", arg1, arg2) end @end ## removes a cc_opt option @define rmccopt globals.Remove("cc_opts", arg1) @end @define addldopt globals.AddOption("ld_opts", arg1, arg2) @end @define setldopt globals.SetOption("ld_opts", arg1, arg2) @end @define addwin32ldopt if bmk.Platform() == "win32" then globals.AddOption("ld_opts", arg1, arg2) end @end @define addmacldopt if bmk.Platform() == "macos" then globals.AddOption("ld_opts", arg1, arg2) end @end @define addlinuxldopt if bmk.Platform() == "linux" or bmk.Platform() == "android" or bmk.Platform() == "raspberrypi" then globals.AddOption("ld_opts", arg1, arg2) end @end @define setmacldopt if bmk.Platform() == "macos" then globals.SetOption("ld_opts", arg1, arg2) end @end @define setwin32ldopt if bmk.Platform() == "win32" then globals.SetOption("ld_opts", arg1, arg2) end @end @define setlinuxldopt if bmk.Platform() == "linux" then globals.SetOption("ld_opts", arg1, arg2) end @end @define setraspberrypildopt if bmk.Platform() == "raspberrypi" then globals.SetOption("ld_opts", arg1, arg2) end @end # compiles the specified file, using the current options. @define make make.Make(arg1) @end @define skipmod globals.Add("skip_mod", arg1) @end @define skipmodwin32 if bmk.Platform() == "win32" then globals.Add("skip_mod", arg1) end @end @define skipmodmac if bmk.Platform() == "macos" then globals.Add("skip_mod", arg1) end @end @define skipmodlinux if bmk.Platform() == "linux" or bmk.Platform() == "android" or bmk.Platform() == "raspberrypi" then globals.Add("skip_mod", arg1) end @end @define adddef globals.AddC("user_defs", arg1) @end # the default ccopts # used for compiling c-type files @define default_cc_opts globals.Clear("cc_opts") if bmk.Platform() == "macos" or bmk.Platform() == "osx" then if tonumber(%macos_version%) >= 2800 then # macos version >= 10.15.0 ? globals.SetOption("cc_opts", "osversion", "-mmacosx-version-min=10.15") globals.SetOption("ld_opts", "osversion", "-mmacosx-version-min=10.15") globals.SetOption("ld_opts", "stdlib", "-stdlib=libc++") elseif tonumber(%macos_version%) >= 2784 then # macos version >= 10.14.0 ? globals.SetOption("cc_opts", "osversion", "-mmacosx-version-min=10.12") globals.SetOption("ld_opts", "osversion", "-mmacosx-version-min=10.12") globals.SetOption("ld_opts", "stdlib", "-stdlib=libc++") elseif tonumber(%macos_version%) >= 2752 then # macos version >= 10.12.0 ? globals.SetOption("cc_opts", "osversion", "-mmacosx-version-min=10.9") globals.SetOption("ld_opts", "osversion", "-mmacosx-version-min=10.9") globals.SetOption("ld_opts", "stdlib", "-stdlib=libc++") elseif tonumber(%macos_version%) >= 2704 then # macos version >= 10.9.0 ? globals.SetOption("cc_opts", "osversion", "-mmacosx-version-min=10.7") globals.SetOption("ld_opts", "osversion", "-mmacosx-version-min=10.7") elseif tonumber(%macos_version%) >= 2688 then # macos version >= 10.8.0 ? globals.SetOption("cc_opts", "osversion", "-mmacosx-version-min=10.5") globals.SetOption("ld_opts", "osversion", "-mmacosx-version-min=10.5") elseif tonumber(%macos_version%) >= 2672 then # macos version >= 10.7.0 ? globals.SetOption("cc_opts", "osversion", "-mmacosx-version-min=10.4") globals.SetOption("ld_opts", "osversion", "-mmacosx-version-min=10.4") elseif tonumber(%macos_version%) >= 2640 then # macos version >= 10.5.0 ? globals.SetOption("cc_opts", "osversion", "-mmacosx-version-min=10.3") globals.SetOption("ld_opts", "osversion", "-mmacosx-version-min=10.3") else # otherwise, fallback on same as latest (10.6) globals.SetOption("cc_opts", "osversion", "-mmacosx-version-min=10.6") globals.SetOption("ld_opts", "osversion", "-mmacosx-version-min=10.6") end elseif bmk.Platform() == "ios" then globals.SetOption("cc_opts", "osversion", "-miphoneos-version-min=10.0.0") globals.SetOption("cc_opts", "ostarget", "-target arm64-apple-ios10.0") elseif bmk.Platform() == "win32" then if bmk.HasClang() == 1 then globals.SetOption("cc_opts", "win_family", "-DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP") else if bmk.hasTarget("x86_64") then if bmk.CPU() == "x86" then globals.SetOption("cc_opts", "arch", "-m32") elseif bmk.CPU() == "x64" then globals.SetOption("cc_opts", "arch", "-m64") end else globals.SetOption("cc_opts", "arch", "-march=pentium") end end globals.SetOption("cc_opts", "fastmath", "-ffast-math") elseif bmk.Platform() == "linux" or bmk.Platform() == "android" or bmk.Platform() == "raspberrypi" or bmk.Platform() == "emscripten" or bmk.Platform() == "haiku" then globals.SetOption("cc_opts", "aliasing", "-fno-strict-aliasing") if bmk.CPU() == "x86" then globals.SetOption("cc_opts", "arch", "-m32") globals.SetOption("cc_opts", "fancymath", "-mfancy-math-387") end if bmk.Platform() ~= "haiku" then globals.SetOption("cc_opts", "pie", "-fpie") end end globals.SetOption("cc_opts", "exceptions", "-fno-exceptions") globals.SetOption("cc_opts", "linker", "-c") if bmk.IsGdbDebugBuild() == 0 then if bmk.Platform() ~= "nx" then globals.SetOption("cc_opts", "optimization", "-O3") else globals.SetOption("cc_opts", "optimization", "-O2") end if bmk.CPU() == "x64" then globals.SetOption("cc_opts", "simd", "-msse3") end if bmk.IsDebugBuild() == 0 then if bmk.Platform() ~= "emscripten" then globals.SetOption("cc_opts", "stripsymbols", "-s") end end end @end # Supported file extensions # # SOURCE_UNKNOWN = 0 # SOURCE_BMX = 1 # SOURCE_IFACE = 2 # SOURCE_C = 4 # SOURCE_HEADER = 8 # SOURCE_ASM = 16 @define source_type local ext = ";" .. arg0 .. ";" if string.find(";bmx;", ext) then return 1 elseif string.find(";i;", ext) then return 2 elseif string.find(";c;m;cc;cpp;cxx;mm;", ext) then return 4 elseif string.find(";h;hpp;hxx;", ext) then return 8 elseif string.find(";s;asm;", ext) then return 16 end return 0 @end @define make_win32_resource if bmk.OSPlatform() == "win32" then ext = ".exe" else ext = "" end local windres = bmk.Option("path_to_windres", bmk.MinGWBinPath() .. "/" .. bmk.MinGWExePrefix() .. "windres") .. ext local windresExe = sys.StripDir(windres) local windresDir = sys.ExtractDir(windres) local outfile = %outfile% local undecorated_outfile = outfile local infile = %infile% local decoration = "" if bmk.IsDebugBuild() == 1 then decoration = ".debug" end if bmk.IsThreadedBuild() == 1 and bmk.BCCVersion() == "BlitzMax" then decoration = decoration .. ".mt" end if string.sub( outfile, -string.len( decoration ) ) ~= decoration then outfile = outfile .. decoration end if sys.FileType(windres) == 0 then if bmk.VerboseBuild() == 1 then print(windresExe .. " not found in '" .. windresDir .. "'. Unable to apply any manifest files.") end return end windresExe = bmk.Quote(windresExe) if bmk.VerboseBuild() == 1 then print("Compiling resources...") end local arch = "amd64" if bmk.CPU() == "x86" then arch = "x86" end local tmp_path = %buildpath% .. "/.bmx/" local user_manifest_path = %buildpath% .. "/" .. outfile .. ".exe.manifest" local manifest_path = tmp_path .. outfile .. "." .. bmk.CPU() .. ".manifest" local resource_path = tmp_path .. outfile .. "." .. bmk.CPU() .. ".rc" local object_path = bmk.Quote(tmp_path .. outfile .. "." .. bmk.CPU() .. ".res.o") local icon_path = %buildpath% .. "/" .. outfile .. ".ico" if sys.FileType(icon_path) == 0 then -- fall back to undecorated icon file icon_path = %buildpath% .. "/" .. undecorated_outfile .. ".ico" if sys.FileType(icon_path) == 0 then icon_path = %buildpath% .. "/" .. infile .. ".ico" end end local manifest = "" .. "" .. "" .. "" if bmk.SupportsHiRes() == 1 then manifest = manifest .. "true" end manifest = manifest .. "" .. "" .. "" .. "" if bmk.AppSetting("app.description") ~= "" then manifest = manifest .. bmk.AppSetting("app.description") else manifest = manifest .. outfile end manifest = manifest .. "" .. "" .. "" .. "" .. "" .. "" .. "" local resource = "1 24 \"" if sys.FileType(user_manifest_path) == 1 then resource = resource .. user_manifest_path else resource = resource .. manifest_path end resource = resource .. "\"\n" .. "\n" if sys.FileType(icon_path) == 1 then resource = resource .. "APP_ICON ICON \"" .. icon_path .. "\"\n" .. "\n" end resource = resource .. "1 VERSIONINFO\n" .. "FILEVERSION " if bmk.AppSetting("app.version.major") ~= "" then resource = resource .. bmk.AppSetting("app.version.major") else resource = resource .. "1" end if bmk.AppSetting("app.version.minor") ~= "" then resource = resource .. "," .. bmk.AppSetting("app.version.minor") else resource = resource .. ",0" end if bmk.AppSetting("app.version.patch") ~= "" then resource = resource .. "," .. bmk.AppSetting("app.version.patch") else resource = resource .. ",0" end if bmk.AppSetting("app.version.build") ~= "" then resource = resource .. "," .. bmk.AppSetting("app.version.build") else resource = resource .. ",0" end resource = resource .. "\n" .. "PRODUCTVERSION 1,0,0,0\n" .. "FILEOS 0x40004\n" .. "FILETYPE 0x1\n" .. "{\n" .. "BLOCK \"StringFileInfo\"\n" .. "{\n" .. "BLOCK \"040904b0\"\n" .. "{\n" if bmk.AppSetting("app.comments") ~= "" then resource = resource .. "VALUE \"Comments\", \"" .. bmk.AppSetting("app.comments") .. "\"\n" end if bmk.AppSetting("app.company") ~= "" then resource = resource .. "VALUE \"CompanyName\", \"" .. bmk.AppSetting("app.company") .. "\"\n" end if bmk.AppSetting("app.version.name") ~= "" then resource = resource .. "VALUE \"FileVersion\", \"" .. bmk.AppSetting("app.version.name") .. "\"\n" .. "VALUE \"ProductVersion\", \"" .. bmk.AppSetting("app.version.name") .. "\"\n" end if bmk.AppSetting("app.description") ~= "" then resource = resource .. "VALUE \"FileDescription\", \"" .. bmk.AppSetting("app.description") .. "\"\n" end if bmk.AppSetting("app.name") ~= "" then resource = resource .. "VALUE \"InternalName\", \"" .. bmk.AppSetting("app.name") .. "\"\n" .. "VALUE \"ProductName\", \"" .. bmk.AppSetting("app.name") .. "\"\n" end if bmk.AppSetting("app.copyright") ~= "" then resource = resource .. "VALUE \"LegalCopyright\", \"" .. bmk.AppSetting("app.copyright") .. "\"\n" end if bmk.AppSetting("app.trademarks") ~= "" then resource = resource .. "VALUE \"LegalTrademarks\", \"" .. bmk.AppSetting("app.trademarks") .. "\"\n" end resource = resource .. "VALUE \"OriginalFilename\", \"" .. outfile .. ".exe\"\n" .. "}\n" .. "}\n" .. "BLOCK \"VarFileInfo\"\n" .. "{\n" .. "VALUE \"Translation\", 0x0409, 0\n" .. "}\n" .. "}" if futils.SaveText(manifest_path, manifest) then if futils.SaveText(resource_path, resource) then local cmd = windresExe .. " -i " .. bmk.Quote(resource_path) .. " -o " .. object_path -- windres should be run from its location in order to avoid issues with spaces in paths local cwd = sys.CurrentDir() sys.ChangeDir(windresDir) bmk.Sys(cmd) sys.ChangeDir(cwd) end end @end