diff options
author | 2019-09-29 15:30:18 +0200 | |
---|---|---|
committer | 2019-09-29 09:30:18 -0400 | |
commit | ed2b7e5ef1626c0d6318b6ea71897efbb4356277 (patch) | |
tree | 62a84a4a2c804922839dbfa60ec664b84beaaee0 /3rdparty/genie/src/actions/ninja/ninja_cpp.lua | |
parent | 1bd1288c9e17bdba9544d1e56be7618106fece7e (diff) |
Synced with GENie upstream revision e78d6c1 (#5631)
* Synced with GENie upstream revision e78d6c1
* Add Visual Studio 2019 support
* Fix hardcoded -m64
* Switch appveyor to Visual Studio 2019
* Fix genie being built as 32-bit
* MSVC build is known to be broken currently. Let it fail until all the known issues are fixed.
* Update the packages before building
* Build with 3 threads
Appveyor VMs have only 2 cores and 8 GB RAM.
* Enable caching of pacman cache
Diffstat (limited to '3rdparty/genie/src/actions/ninja/ninja_cpp.lua')
-rw-r--r-- | 3rdparty/genie/src/actions/ninja/ninja_cpp.lua | 162 |
1 files changed, 133 insertions, 29 deletions
diff --git a/3rdparty/genie/src/actions/ninja/ninja_cpp.lua b/3rdparty/genie/src/actions/ninja/ninja_cpp.lua index 4007c117948..14cbf5d0456 100644 --- a/3rdparty/genie/src/actions/ninja/ninja_cpp.lua +++ b/3rdparty/genie/src/actions/ninja/ninja_cpp.lua @@ -8,6 +8,14 @@ local ninja = premake.ninja local cpp = premake.ninja.cpp local p = premake +local function wrap_ninja_cmd(c) + if os.is("windows") then + return 'cmd /c "' .. c .. '"' + else + return c + end +end + -- generate project + config build file function ninja.generate_cpp(prj) local pxy = ninja.get_proxy("prj", prj) @@ -36,7 +44,7 @@ local p = premake local flags = { defines = ninja.list(tool.getdefines(cfg.defines)), - includes = ninja.list(table.join(tool.getincludedirs(cfg.includedirs), tool.getquoteincludedirs(cfg.userincludedirs))), + includes = ninja.list(table.join(tool.getincludedirs(cfg.includedirs), tool.getquoteincludedirs(cfg.userincludedirs), tool.getsystemincludedirs(cfg.systemincludedirs))), cppflags = ninja.list(tool.getcppflags(cfg)), asmflags = ninja.list(table.join(tool.getcflags(cfg), cfg.buildoptions, cfg.buildoptions_asm)), cflags = ninja.list(table.join(tool.getcflags(cfg), cfg.buildoptions, cfg.buildoptions_c)), @@ -48,35 +56,67 @@ local p = premake _p("# core rules for " .. cfg.name) _p("rule cc") - _p(" command = " .. tool.cc .. " $defines $includes $flags -MMD -MF $out.d -c -o $out $in") + _p(" command = " .. wrap_ninja_cmd(tool.cc .. " $defines $includes $flags -MMD -MF $out.d -c -o $out $in")) _p(" description = cc $out") - _p(" depfile = $out.d") - _p(" deps = gcc") + _p(" depfile = $out.d") + _p(" deps = gcc") _p("") _p("rule cxx") - _p(" command = " .. tool.cxx .. " $defines $includes $flags -MMD -MF $out.d -c -o $out $in") + _p(" command = " .. wrap_ninja_cmd(tool.cxx .. " $defines $includes $flags -MMD -MF $out.d -c -o $out $in")) _p(" description = cxx $out") - _p(" depfile = $out.d") - _p(" deps = gcc") + _p(" depfile = $out.d") + _p(" deps = gcc") _p("") _p("rule ar") - _p(" command = " .. tool.ar .. " $flags $out $in $libs " .. (os.is("MacOSX") and " 2>&1 > /dev/null | sed -e '/.o) has no symbols$$/d'" or "")) - _p(" description = ar $out") + _p(" command = " .. wrap_ninja_cmd(tool.ar .. " $flags $out @$out.rsp " .. (os.is("MacOSX") and " 2>&1 > /dev/null | sed -e '/.o) has no symbols$$/d'" or ""))) + _p(" description = ar $out") + _p(" rspfile = $out.rsp") + _p(" rspfile_content = $in $libs") _p("") local link = iif(cfg.language == "C", tool.cc, tool.cxx) _p("rule link") - _p(" command = " .. link .. " -o $out @$out.rsp $all_ldflags $libs") - _p(" rspfile = $out.rsp") - _p(" rspfile_content = $all_outputfiles") - _p(" description = link $out") + local startgroup = '' + local endgroup = '' + if (cfg.flags.LinkSupportCircularDependencies) then + startgroup = '-Wl,--start-group' + endgroup = '-Wl,--end-group' + end + _p(" command = " .. wrap_ninja_cmd("$pre_link " .. link .. " -o $out @$out.rsp $all_ldflags $post_build")) + _p(" description = link $out") + _p(" rspfile = $out.rsp") + _p(" rspfile_content = $all_outputfiles " .. string.format("%s $libs %s", startgroup, endgroup)) + _p("") + + _p("rule exec") + _p(" command = " .. wrap_ninja_cmd("$command")) + _p(" description = Run $type commands") _p("") + if #cfg.prebuildcommands > 0 then + _p("build __prebuildcommands_" .. premake.esc(prj.name) .. ": exec") + _p(1, "command = " .. wrap_ninja_cmd("echo Running pre-build commands && " .. table.implode(cfg.prebuildcommands, "", "", " && "))) + _p(1, "type = pre-build") + _p("") + end + + cfg.pchheader_full = cfg.pchheader + for _, incdir in ipairs(cfg.includedirs) do + -- convert this back to an absolute path for os.isfile() + local abspath = path.getabsolute(path.join(cfg.project.location, cfg.shortname, incdir)) + + local testname = path.join(abspath, cfg.pchheader_full) + if os.isfile(testname) then + cfg.pchheader_full = path.getrelative(cfg.location, testname) + break + end + end + cpp.custombuildtask(prj, cfg) cpp.dependencyRules(prj, cfg) - cpp.file_rules(cfg, flags) + cpp.file_rules(prj, cfg, flags) local objfiles = {} @@ -98,6 +138,8 @@ local p = premake local command_by_name = {} local command_files = {} + local prebuildsuffix = #cfg.prebuildcommands > 0 and "||__prebuildcommands_" .. premake.esc(prj.name) or "" + for _, custombuildtask in ipairs(prj.custombuildtask or {}) do for _, buildtask in ipairs(custombuildtask or {}) do for _, cmd in ipairs(buildtask[4] or {}) do @@ -156,7 +198,7 @@ local p = premake _p("# custom build rules") for command, details in pairs(seen_commands) do _p("rule " .. details.name) - _p(1, "command = " .. command) + _p(1, "command = " .. wrap_ninja_cmd(command)) end for cmd_index, cmdsets in ipairs(command_files) do @@ -167,7 +209,7 @@ local p = premake for i, dep in ipairs(cmdset[3]) do deps = deps .. path.getrelative(cfg.location, dep) .. ' ' end - _p("build " .. file_out .. ': ' .. cmdset[4] .. ' ' .. file_in .. ' | ' .. deps) + _p("build " .. file_out .. ': ' .. cmdset[4] .. ' ' .. file_in .. ' | ' .. deps .. prebuildsuffix) _p("") end end @@ -175,6 +217,8 @@ local p = premake function cpp.dependencyRules(prj, cfg) local extra_deps = {} + local order_deps = {} + local extra_flags = {} for _, dependency in ipairs(prj.dependency or {}) do for _, dep in ipairs(dependency or {}) do @@ -191,38 +235,90 @@ local p = premake end end + local pchfilename = cfg.pchheader_full and cpp.pchname(cfg, cfg.pchheader_full) or '' + for _, file in ipairs(cfg.files) do + local objfilename = file == cfg.pchheader and cpp.pchname(cfg, file) or cpp.objectname(cfg, file) + if path.issourcefile(file) or file == cfg.pchheader then + if #cfg.prebuildcommands > 0 then + if order_deps[objfilename] == nil then + order_deps[objfilename] = {} + end + table.insert(order_deps[objfilename], '__prebuildcommands_' .. premake.esc(prj.name)) + end + end + if path.issourcefile(file) then + if cfg.pchheader_full and not cfg.flags.NoPCH then + local nopch = table.icontains(prj.nopch, file) + if not nopch then + local suffix = path.isobjcfile(file) and '_objc' or '' + if extra_deps[objfilename] == nil then + extra_deps[objfilename] = {} + end + table.insert(extra_deps[objfilename], pchfilename .. suffix .. ".gch") + + if extra_flags[objfilename] == nil then + extra_flags[objfilename] = {} + end + table.insert(extra_flags[objfilename], '-include ' .. pchfilename .. suffix) + end + end + end + end + -- store prepared deps for file_rules() phase cfg.extra_deps = extra_deps + cfg.order_deps = order_deps + cfg.extra_flags = extra_flags end function cpp.objectname(cfg, file) return path.join(cfg.objectsdir, path.trimdots(path.removeext(file)) .. ".o") end - function cpp.file_rules(cfg, flags) + function cpp.pchname(cfg, file) + return path.join(cfg.objectsdir, path.trimdots(file)) + end + + function cpp.file_rules(prj,cfg, flags) _p("# build files") for _, file in ipairs(cfg.files) do _p("# FILE: " .. file) - if path.issourcefile(file) then + if cfg.pchheader_full == file then + local pchfilename = cpp.pchname(cfg, file) + local extra_deps = #cfg.extra_deps and '| ' .. table.concat(cfg.extra_deps[pchfilename] or {}, ' ') or '' + local order_deps = #cfg.order_deps and '|| ' .. table.concat(cfg.order_deps[pchfilename] or {}, ' ') or '' + local extra_flags = #cfg.extra_flags and ' ' .. table.concat(cfg.extra_flags[pchfilename] or {}, ' ') or '' + _p("build " .. pchfilename .. ".gch : cxx " .. file .. extra_deps .. order_deps) + _p(1, "flags = " .. flags['cxxflags'] .. extra_flags .. iif(prj.language == "C", "-x c-header", "-x c++-header")) + _p(1, "includes = " .. flags.includes) + _p(1, "defines = " .. flags.defines) + + _p("build " .. pchfilename .. "_objc.gch : cxx " .. file .. extra_deps .. order_deps) + _p(1, "flags = " .. flags['objcflags'] .. extra_flags .. iif(prj.language == "C", "-x objective-c-header", "-x objective-c++-header")) + _p(1, "includes = " .. flags.includes) + _p(1, "defines = " .. flags.defines) + elseif path.issourcefile(file) then local objfilename = cpp.objectname(cfg, file) local extra_deps = #cfg.extra_deps and '| ' .. table.concat(cfg.extra_deps[objfilename] or {}, ' ') or '' + local order_deps = #cfg.order_deps and '|| ' .. table.concat(cfg.order_deps[objfilename] or {}, ' ') or '' + local extra_flags = #cfg.extra_flags and ' ' .. table.concat(cfg.extra_flags[objfilename] or {}, ' ') or '' local cflags = "cflags" if path.isobjcfile(file) then - _p("build " .. objfilename .. ": cxx " .. file .. extra_deps) + _p("build " .. objfilename .. ": cxx " .. file .. extra_deps .. order_deps) cflags = "objcflags" elseif path.isasmfile(file) then - _p("build " .. objfilename .. ": cc " .. file .. extra_deps) + _p("build " .. objfilename .. ": cc " .. file .. extra_deps .. order_deps) cflags = "asmflags" elseif path.iscfile(file) and not cfg.options.ForceCPP then - _p("build " .. objfilename .. ": cc " .. file .. extra_deps) + _p("build " .. objfilename .. ": cc " .. file .. extra_deps .. order_deps) else - _p("build " .. objfilename .. ": cxx " .. file .. extra_deps) + _p("build " .. objfilename .. ": cxx " .. file .. extra_deps .. order_deps) cflags = "cxxflags" end - _p(1, "flags = " .. flags[cflags]) + _p(1, "flags = " .. flags[cflags] .. extra_flags) _p(1, "includes = " .. flags.includes) _p(1, "defines = " .. flags.defines) elseif path.isresourcefile(file) then @@ -238,26 +334,34 @@ local p = premake local lddeps = ninja.list(premake.getlinks(cfg, "siblings", "fullpath")) local libs = lddeps .. " " .. ninja.list(tool.getlinkflags(cfg)) + local prebuildsuffix = #cfg.prebuildcommands > 0 and "||__prebuildcommands" or "" + local function writevars() - _p(1, "all_ldflags = " .. all_ldflags) - _p(1, "libs = " .. libs) + _p(1, "all_ldflags = " .. all_ldflags) + _p(1, "libs = " .. libs) _p(1, "all_outputfiles = " .. table.concat(objfiles, " ")) + if #cfg.prelinkcommands > 0 then + _p(1, 'pre_link = echo Running pre-link commands && ' .. table.implode(cfg.prelinkcommands, "", "", " && ") .. " && ") + end + if #cfg.postbuildcommands > 0 then + _p(1, 'post_build = && echo Running post-build commands && ' .. table.implode(cfg.postbuildcommands, "", "", " && ")) + end end if cfg.kind == "StaticLib" then local ar_flags = ninja.list(tool.getarchiveflags(cfg, cfg, false)) _p("# link static lib") - _p("build " .. cfg:getoutputfilename() .. ": ar " .. table.concat(objfiles, " ") .. " | " .. lddeps) + _p("build " .. cfg:getoutputfilename() .. ": ar " .. table.concat(objfiles, " ") .. " | " .. lddeps .. prebuildsuffix) _p(1, "flags = " .. ninja.list(tool.getarchiveflags(cfg, cfg, false))) _p(1, "all_outputfiles = " .. table.concat(objfiles, " ")) - elseif cfg.kind == "SharedLib" then + elseif cfg.kind == "SharedLib" or cfg.kind == "Bundle" then local output = cfg:getoutputfilename() _p("# link shared lib") - _p("build " .. output .. ": link " .. table.concat(objfiles, " ") .. " | " .. libs) + _p("build " .. output .. ": link " .. table.concat(objfiles, " ") .. " | " .. lddeps .. prebuildsuffix) writevars() elseif (cfg.kind == "ConsoleApp") or (cfg.kind == "WindowedApp") then _p("# link executable") - _p("build " .. cfg:getoutputfilename() .. ": link " .. table.concat(objfiles, " ") .. " | " .. lddeps) + _p("build " .. cfg:getoutputfilename() .. ": link " .. table.concat(objfiles, " ") .. " | " .. lddeps .. prebuildsuffix) writevars() else p.error("ninja action doesn't support this kind of target " .. cfg.kind) |