Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

View File

@@ -0,0 +1,395 @@
--
-- d/actions/gmake.lua
-- Define the D makefile action(s).
-- Copyright (c) 2013-2015 Andrew Gough, Manu Evans, and the Premake project
--
local p = premake
local m = p.modules.d
m.make = {}
local dmake = m.make
require ("gmake")
local make = p.make
local cpp = p.make.cpp
local project = p.project
local config = p.config
local fileconfig = p.fileconfig
-- This check may be unnecessary as we only 'require' this file from d.lua
-- IFF the action already exists, however this may help if this file is
-- directly required, rather than d.lua itself.
local gmake = p.action.get( 'gmake' )
if gmake == nil then
error( "Failed to locate prequisite action 'gmake'" )
end
--
-- Patch the gmake action with the allowed tools...
--
gmake.valid_languages = table.join(gmake.valid_languages, { p.D } )
gmake.valid_tools.dc = { "dmd", "gdc", "ldc" }
function m.make.separateCompilation(prj)
local some = false
local all = true
for cfg in project.eachconfig(prj) do
if cfg.compilationmodel == "File" then
some = true
else
all = false
end
end
return iif(all, "all", iif(some, "some", "none"))
end
--
-- Override the GMake action 'onProject' funtion to provide
-- D knowledge...
--
p.override( gmake, "onProject", function(oldfn, prj)
p.escaper(make.esc)
if project.isd(prj) then
local makefile = make.getmakefilename(prj, true)
p.generate(prj, makefile, m.make.generate)
return
end
oldfn(prj)
end)
p.override( make, "objdir", function(oldfn, cfg)
if cfg.project.language ~= "D" or cfg.compilationmodel == "File" then
oldfn(cfg)
end
end)
p.override( make, "objDirRules", function(oldfn, prj)
if prj.language ~= "D" or m.make.separateCompilation(prj) ~= "none" then
oldfn(prj)
end
end)
---
-- Add namespace for element definition lists for p.callarray()
---
m.elements = {}
--
-- Generate a GNU make C++ project makefile, with support for the new platforms API.
--
m.elements.makefile = function(prj)
return {
make.header,
make.phonyRules,
m.make.configs,
m.make.objects, -- TODO: This is basically identical to make.cppObjects(), and should ideally be merged/shared
make.shellType,
m.make.targetRules,
make.targetDirRules,
make.objDirRules,
make.cppCleanRules, -- D clean code is identical to C/C++
make.preBuildRules,
make.preLinkRules,
m.make.dFileRules,
}
end
function m.make.generate(prj)
p.callArray(m.elements.makefile, prj)
end
function m.make.buildRule(prj)
_p('$(TARGET): $(SOURCEFILES) $(LDDEPS)')
_p('\t@echo Building %s', prj.name)
_p('\t$(SILENT) $(BUILDCMD)')
_p('\t$(POSTBUILDCMDS)')
end
function m.make.linkRule(prj)
_p('$(TARGET): $(OBJECTS) $(LDDEPS)')
_p('\t@echo Linking %s', prj.name)
_p('\t$(SILENT) $(LINKCMD)')
_p('\t$(POSTBUILDCMDS)')
end
function m.make.targetRules(prj)
local separateCompilation = m.make.separateCompilation(prj)
if separateCompilation == "all" then
m.make.linkRule(prj)
elseif separateCompilation == "none" then
m.make.buildRule(prj)
else
for cfg in project.eachconfig(prj) do
_x('ifeq ($(config),%s)', cfg.shortname)
if cfg.compilationmodel == "File" then
m.make.linkRule(prj)
else
m.make.buildRule(prj)
end
_p('endif')
end
end
_p('')
end
function m.make.dFileRules(prj)
local separateCompilation = m.make.separateCompilation(prj)
if separateCompilation ~= "none" then
make.cppFileRules(prj)
end
end
--
-- Override the 'standard' file rule to support D source files
--
p.override(cpp, "standardFileRules", function(oldfn, prj, node)
-- D file
if path.isdfile(node.abspath) then
_p('\t$(SILENT) $(DC) $(ALL_DFLAGS) $(OUTPUTFLAG) -c $<')
else
oldfn(prj, node)
end
end)
--
-- Let make know it can compile D source files
--
p.override(make, "fileType", function(oldfn, node)
if path.isdfile(node.abspath) then
return "objects"
else
return oldfn(node)
end
end)
--
-- Write out the settings for a particular configuration.
--
m.elements.makeconfig = function(cfg)
return {
m.make.dTools,
make.target,
m.make.target,
make.objdir,
m.make.versions,
m.make.debug,
m.make.imports,
m.make.stringImports,
m.make.dFlags,
make.libs,
make.ldDeps,
make.ldFlags,
m.make.linkCmd,
make.preBuildCmds,
make.preLinkCmds,
make.postBuildCmds,
m.make.allRules,
make.settings,
}
end
function m.make.configs(prj)
for cfg in project.eachconfig(prj) do
-- identify the toolset used by this configurations (would be nicer if
-- this were computed and stored with the configuration up front)
local toolset = m.make.getToolset(cfg)
if not toolset then
error("Invalid toolset '" + (_OPTIONS.dc or cfg.toolset) + "'")
end
_x('ifeq ($(config),%s)', cfg.shortname)
p.callArray(m.elements.makeconfig, cfg, toolset)
_p('endif')
_p('')
end
end
function m.make.getToolset(cfg)
local toolset, err = p.api.checkValue(p.fields.toolset, _OPTIONS.dc or cfg.toolset or "dmd")
if err then
error { msg=err }
end
return p.tools[toolset]
end
function m.make.dTools(cfg, toolset)
local tool = toolset.gettoolname(cfg, "dc")
if tool then
_p(' DC = %s', tool)
end
end
function m.make.target(cfg, toolset)
if cfg.compilationmodel == "File" then
_p(' OUTPUTFLAG = %s', toolset.gettarget('"$@"'))
end
end
function m.make.versions(cfg, toolset)
_p(' VERSIONS +=%s', make.list(toolset.getversions(cfg.versionconstants, cfg.versionlevel)))
end
function m.make.debug(cfg, toolset)
_p(' DEBUG +=%s', make.list(toolset.getdebug(cfg.debugconstants, cfg.debuglevel)))
end
function m.make.imports(cfg, toolset)
local imports = p.esc(toolset.getimportdirs(cfg, cfg.importdirs))
_p(' IMPORTS +=%s', make.list(imports))
end
function m.make.stringImports(cfg, toolset)
local stringImports = p.esc(toolset.getstringimportdirs(cfg, cfg.stringimportdirs))
_p(' STRINGIMPORTS +=%s', make.list(stringImports))
end
function m.make.dFlags(cfg, toolset)
_p(' ALL_DFLAGS += $(DFLAGS)%s $(VERSIONS) $(DEBUG) $(IMPORTS) $(STRINGIMPORTS) $(ARCH)', make.list(table.join(toolset.getdflags(cfg), cfg.buildoptions)))
end
function m.make.linkCmd(cfg, toolset)
if cfg.compilationmodel == "File" then
_p(' LINKCMD = $(DC) ' .. toolset.gettarget("$(TARGET)") .. ' $(ALL_LDFLAGS) $(LIBS) $(OBJECTS)')
-- local cc = iif(p.languages.isc(cfg.language), "CC", "CXX")
-- _p(' LINKCMD = $(%s) -o $(TARGET) $(OBJECTS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)', cc)
else
_p(' BUILDCMD = $(DC) ' .. toolset.gettarget("$(TARGET)") .. ' $(ALL_DFLAGS) $(ALL_LDFLAGS) $(LIBS) $(SOURCEFILES)')
end
end
function m.make.allRules(cfg, toolset)
-- TODO: The C++ version has some special cases for OSX and Windows... check whether they should be here too?
if cfg.compilationmodel == "File" then
_p('all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET)')
else
_p('all: $(TARGETDIR) prebuild prelink $(TARGET)')
end
_p('\t@:')
-- _p('')
end
--
-- List the objects file for the project, and each configuration.
--
-- TODO: This is basically identical to make.cppObjects(), and should ideally be merged/shared
function m.make.objects(prj)
-- create lists for intermediate files, at the project level and
-- for each configuration
local root = { sourcefiles={}, objects={} }
local configs = {}
for cfg in project.eachconfig(prj) do
configs[cfg] = { sourcefiles={}, objects={} }
end
-- now walk the list of files in the project
local tr = project.getsourcetree(prj)
p.tree.traverse(tr, {
onleaf = function(node, depth)
-- figure out what configurations contain this file, and
-- if it uses custom build rules
local incfg = {}
local inall = true
local custom = false
for cfg in project.eachconfig(prj) do
local filecfg = fileconfig.getconfig(node, cfg)
if filecfg and not filecfg.flags.ExcludeFromBuild then
incfg[cfg] = filecfg
custom = fileconfig.hasCustomBuildRule(filecfg)
else
inall = false
end
end
if not custom then
-- skip files that aren't compiled
if not path.isdfile(node.abspath) then
return
end
local sourcename = node.relpath
-- TODO: assign a unique object file name to avoid collisions
local objectname = "$(OBJDIR)/" .. node.objname .. ".o"
-- if this file exists in all configurations, write it to
-- the project's list of files, else add to specific cfgs
if inall then
table.insert(root.sourcefiles, sourcename)
table.insert(root.objects, objectname)
else
for cfg in project.eachconfig(prj) do
if incfg[cfg] then
table.insert(configs[cfg].sourcefiles, sourcename)
table.insert(configs[cfg].objects, objectname)
end
end
end
else
for cfg in project.eachconfig(prj) do
local filecfg = incfg[cfg]
if filecfg then
-- if the custom build outputs an object file, add it to
-- the link step automatically to match Visual Studio
local output = project.getrelative(prj, filecfg.buildoutputs[1])
if path.isobjectfile(output) then
table.insert(configs[cfg].objects, output)
end
end
end
end
end
})
local separateCompilation = m.make.separateCompilation(prj)
-- now I can write out the lists, project level first...
function listobjects(var, list)
_p('%s \\', var)
for _, objectname in ipairs(list) do
_x('\t%s \\', objectname)
end
_p('')
end
if separateCompilation ~= "all" then
listobjects('SOURCEFILES :=', root.sourcefiles)
end
if separateCompilation ~= "none" then
listobjects('OBJECTS :=', root.objects, 'o')
end
-- ...then individual configurations, as needed
for cfg in project.eachconfig(prj) do
local files = configs[cfg]
if (#files.sourcefiles > 0 and separateCompilation ~= "all") or (#files.objects > 0 and separateCompilation ~= "none") then
_x('ifeq ($(config),%s)', cfg.shortname)
if #files.sourcefiles > 0 and separateCompilation ~= "all" then
listobjects(' SOURCEFILES +=', files.sourcefiles)
end
if #files.objects > 0 and separateCompilation ~= "none" then
listobjects(' OBJECTS +=', files.objects)
end
_p('endif')
end
end
_p('')
end

View File

@@ -0,0 +1,531 @@
--
-- d/actions/vcxproj.lua
-- Generate a VisualD .visualdproj project.
-- Copyright (c) 2012-2015 Manu Evans and the Premake project
--
local p = premake
require ("vstudio")
p.modules.d.vc2010 = {}
local vc2010 = p.vstudio.vc2010
local m = p.modules.d.vc2010
m.elements = {}
local vstudio = p.vstudio
local vc2010 = p.vstudio.vc2010
local config = p.config
--
-- Patch DCompiler into the configuration properties
--
p.override(vc2010.elements, "configurationProperties", function(oldfn, cfg)
local items = oldfn(cfg)
if cfg.kind ~= p.UTILITY then
table.insert(items, m.dCompiler)
end
return items
end)
function m.dCompiler(cfg)
local dc = nil
-- TODO: chech for explicit DMD or LDC request?
if _OPTIONS.dc then
local dcMap = {
["dmd"] = "DMD",
["ldc"] = "LDC",
}
dc = dcMap[_OPTIONS.dc]
end
if cfg.flags.UseLDC then
dc = "LDC"
end
-- TODO: dunno how to use `toolset`, since it's also used by the C++ compiler :/
-- local tool, version = p.config.toolset(cfg)
-- if not version then
-- local value = p.action.current().toolset
-- tool, version = p.tools.canonical(value)
-- end
if dc then
if cfg.kind == p.NONE or cfg.kind == p.MAKEFILE then
if p.config.hasFile(cfg, path.isdfile) or _ACTION >= "vs2015" then
vc2010.element("DCompiler", nil, dc)
end
else
vc2010.element("DCompiler", nil, dc)
end
end
end
--
-- Patch the dCompile step into the project items
--
p.override(vc2010.elements, "itemDefinitionGroup", function(oldfn, cfg)
local items = oldfn(cfg)
if cfg.kind ~= p.UTILITY then
table.insertafter(items, vc2010.clCompile, m.dCompile)
end
return items
end)
--
-- Write the <DCompile> settings block.
--
m.elements.dCompile = function(cfg)
return {
m.dOptimization,
m.dImportPaths,
m.dStringImportPaths,
m.dVersionConstants,
m.dDebugConstants,
m.dCompilationModel,
m.dPreserveSourcePath,
m.dRuntime,
m.dCodeGeneration,
m.dLanguage,
m.dMessages,
m.dDocumentation,
m.dAdditionalCompileOptions,
}
end
function m.dCompile(cfg)
if config.hasFile(cfg, path.isdfile) then
p.push('<DCompile>')
p.callArray(m.elements.dCompile, cfg)
p.pop('</DCompile>')
end
end
---
-- DCompile group
---
vc2010.categories.DCompile = {
name = "DCompile",
extensions = { ".d" },
priority = 3,
emitFiles = function(prj, group)
local fileCfgFunc = function(fcfg, condition)
if fcfg then
return {
vc2010.excludedFromBuild,
m.dOptimization,
m.dImportPaths,
m.dStringImportPaths,
m.dVersionConstants,
m.dDebugConstants,
m.dCompilationModel,
m.dPreserveSourcePath,
m.dRuntime,
m.dCodeGeneration,
m.dLanguage,
m.dMessages,
m.dDocumentation,
m.dAdditionalCompileOptions,
}
else
return {
vc2010.excludedFromBuild
}
end
end
vc2010.emitFiles(prj, group, "DCompile", {m.generatedFile}, fileCfgFunc)
end,
emitFilter = function(prj, group)
vc2010.filterGroup(prj, group, "DCompile")
end
}
function m.dOptimization(cfg, condition)
local map = { Off="false", On="true", Debug="false", Full="true", Size="true", Speed="true" }
if cfg.optimize then
vc2010.element('Optimizer', condition, map[cfg.optimize] or "false")
end
end
function m.dImportPaths(cfg, condition)
if cfg.importdirs and #cfg.importdirs > 0 then
local dirs = vstudio.path(cfg, cfg.importdirs)
if #dirs > 0 then
vc2010.element("ImportPaths", condition, "%s;%%(ImportPaths)", table.concat(dirs, ";"))
end
end
end
function m.dStringImportPaths(cfg, condition)
if cfg.stringimportdirs and #cfg.stringimportdirs > 0 then
local dirs = vstudio.path(cfg, cfg.stringimportdirs)
if #dirs > 0 then
vc2010.element("StringImportPaths", condition, "%s;%%(StringImportPaths)", table.concat(dirs, ";"))
end
end
end
function m.dVersionConstants(cfg, condition)
if cfg.versionconstants and #cfg.versionconstants > 0 then
local versionconstants = table.concat(cfg.versionconstants, ";")
vc2010.element("VersionIdentifiers", condition, versionconstants)
end
end
function m.dDebugConstants(cfg, condition)
if cfg.debugconstants and #cfg.debugconstants > 0 then
local debugconstants = table.concat(cfg.debugconstants, ";")
vc2010.element("DebugIdentifiers", condition, debugconstants)
end
end
function m.dCompilationModel(cfg, condition)
if cfg.compilationmodel and cfg.compilationmodel ~= "Default" then
vc2010.element("CompilationModel", condition, cfg.compilationmodel)
end
end
function m.dPreserveSourcePath(cfg, condition)
if cfg.flags.RetainPaths then
vc2010.element("PreserveSourcePath", condition, "true")
end
end
function m.dRuntime(cfg, condition)
if cfg.flags.OmitDefaultLibrary then
vc2010.element("CRuntimeLibrary", condition, "None")
else
local releaseruntime = not config.isDebugBuild(cfg)
local staticruntime = true
if cfg.staticruntime == "Off" then
staticruntime = false
end
if cfg.runtime == "Debug" then
releaseruntime = false
elseif cfg.runtime == "Release" then
releaseruntime = true
end
if (cfg.staticruntime and cfg.staticruntime ~= "Default") or (cfg.runtime and cfg.runtime ~= "Default") then
if staticruntime == true and releaseruntime == true then
vc2010.element("CRuntimeLibrary", condition, "MultiThreaded")
elseif staticruntime == true and releaseruntime == false then
vc2010.element("CRuntimeLibrary", condition, "MultiThreadedDebug")
elseif staticruntime == false and releaseruntime == true then
vc2010.element("CRuntimeLibrary", condition, "MultiThreadedDll")
elseif staticruntime == false and releaseruntime == false then
vc2010.element("CRuntimeLibrary", condition, "MultiThreadedDebugDll")
end
end
end
end
function m.dCodeGeneration(cfg, condition)
if cfg.buildtarget then
local ObjectFileName = ""
if cfg.buildtarget.basename then
if cfg.buildtarget.prefix then
ObjectFileName = cfg.buildtarget.prefix
end
ObjectFileName = ObjectFileName .. cfg.buildtarget.basename .. ".obj"
end
if cfg.buildtarget.directory then
local outdir = vstudio.path(cfg, cfg.buildtarget.directory)
ObjectFileName = path.join(outdir, ObjectFileName)
end
vc2010.element("ObjectFileName", condition, ObjectFileName)
end
if cfg.flags.Profile then
vc2010.element("Profile", condition, "true")
end
if cfg.flags.ProfileGC then
vc2010.element("ProfileGC", condition, "true")
end
if cfg.flags.CodeCoverage then
vc2010.element("Coverage", condition, "true")
end
if cfg.flags.UnitTest then
vc2010.element("Unittest", condition, "true")
end
if cfg.inlining and cfg.inlining ~= "Default" then
local types = {
Disabled = "false",
Explicit = "true",
Auto = "true",
}
vc2010.element("Inliner", condition, types[cfg.inlining])
end
if cfg.flags.StackFrame then
vc2010.element("StackFrame", condition, "true")
end
if cfg.flags.StackStomp then
vc2010.element("StackStomp", condition, "true")
end
if cfg.flags.AllInstantiate then
vc2010.element("AllInst", condition, "true")
end
if cfg.flags.Main then
vc2010.element("Main", condition, "true")
end
if _OPTIONS.dc ~= "ldc" and not cfg.flags.UseLDC then
if cfg.vectorextensions then
local vextMap = {
AVX = "avx",
AVX2 = "avx2",
}
if vextMap[cfg.vectorextensions] ~= nil then
vc2010.element("CPUArchitecture", condition, vextMap[cfg.vectorextensions])
end
end
end
-- if cfg.debugcode then
-- local types = {
-- DebugFull = "Debug",
-- DebugLight = "Default",
-- Release = "Release",
-- }
-- vc2010.element("DebugCode", condition, types[cfg.debugcode])
-- end
-- TODO: proper option for this? should support unspecified...
if config.isDebugBuild(cfg) then
vc2010.element("DebugCode", condition, "Debug")
else
vc2010.element("DebugCode", condition, "Release")
end
if cfg.symbols then
if cfg.symbols == p.Off then
vc2010.element("DebugInfo", condition, "None")
elseif cfg.symbols ~= "Default" then
vc2010.element("DebugInfo", condition, iif(cfg.flags.SymbolsLikeC, "VS", "Mago"))
end
end
if cfg.boundscheck and cfg.boundscheck ~= "Default" then
local types = {
Off = "Off",
SafeOnly = "SafeOnly",
On = "On",
}
vc2010.element("BoundsCheck", condition, types[cfg.boundscheck])
end
if cfg.flags.PerformSyntaxCheckOnly then
vc2010.element("PerformSyntaxCheckOnly", condition, "true")
end
end
function m.dLanguage(cfg, condition)
if cfg.flags.BetterC then
vc2010.element("BetterC", condition, "true")
end
if #cfg.preview > 0 then
for _, opt in ipairs(cfg.preview) do
if opt == "dip25" then
vc2010.element("DIP25", condition, "true")
elseif opt == "dip1000" then
vc2010.element("DIP1000", condition, "true")
elseif opt == "dip1008" then
vc2010.element("DIP1008", condition, "true")
elseif opt == "fieldwise" then
vc2010.element("PreviewFieldwise", condition, "true")
elseif opt == "dtorfields" then
vc2010.element("PreviewDtorFields", condition, "true")
elseif opt == "intpromote" then
vc2010.element("PreviewIntPromote", condition, "true")
elseif opt == "fixAliasThis" then
vc2010.element("PreviewFixAliasThis", condition, "true")
end
end
end
if #cfg.revert > 0 then
for _, opt in ipairs(cfg.revert) do
if opt == "import" then
vc2010.element("RevertImport", condition, "true")
end
end
end
end
function m.dMessages(cfg, condition)
if cfg.warnings == p.OFF then
vc2010.element("Warnings", condition, "None")
elseif cfg.warnings and cfg.warnings ~= "Default" then
vc2010.element("Warnings", condition, iif(cfg.flags.FatalCompileWarnings, "Error", "Info"))
end
if cfg.deprecatedfeatures and cfg.deprecatedfeatures ~= "Default" then
local types = {
Error = "Error",
Warn = "Info",
Allow = "Allow",
}
vc2010.element("Deprecations", condition, types[cfg.deprecatedfeatures])
end
if cfg.flags.ShowCommandLine then
vc2010.element("ShowCommandLine", condition, "true")
end
if cfg.flags.Verbose then
vc2010.element("Verbose", condition, "true")
end
if cfg.flags.ShowTLS then
vc2010.element("ShowTLS", condition, "true")
end
if cfg.flags.ShowGC then
vc2010.element("ShowGC", condition, "true")
end
if cfg.flags.IgnorePragma then
vc2010.element("IgnorePragma", condition, "true")
end
if cfg.flags.ShowDependencies then
vc2010.element("ShowDependencies", condition, "true")
end
if #cfg.transition > 0 then
for _, opt in ipairs(cfg.transition) do
if opt == "field" then
vc2010.element("TransitionField", condition, "true")
elseif opt == "checkimports" then
vc2010.element("TransitionCheckImports", condition, "true")
elseif opt == "complex" then
vc2010.element("TransitionComplex", condition, "true")
end
end
end
end
function m.dDocumentation(cfg, condition)
if cfg.docdir then
vc2010.element("DocDir", condition, cfg.docdir)
end
if cfg.docname then
vc2010.element("DocFile", condition, cfg.docname)
end
if #cfg.preview > 0 then
for _, opt in ipairs(cfg.preview) do
if opt == "markdown" then
vc2010.element("PreviewMarkdown", condition, "true")
end
end
end
if #cfg.transition > 0 then
for _, opt in ipairs(cfg.transition) do
if opt == "vmarkdown" then
vc2010.element("TransitionVMarkdown", condition, "true")
end
end
end
if cfg.dependenciesfile then
vc2010.element("DepFile", condition, cfg.dependenciesfile)
end
if cfg.headerdir then
vc2010.element("HeaderDir", condition, cfg.headerdir)
end
if cfg.headername then
vc2010.element("HeaderFile", condition, cfg.headername)
end
if cfg.jsonfile then
vc2010.element("JSONFile", condition, cfg.jsonfile)
end
end
function m.dAdditionalCompileOptions(cfg, condition)
local opts = cfg.buildoptions
if cfg.flags.LowMem then
table.insert(opts, "-lowmem")
end
if cfg.cppdialect and cfg.cppdialect ~= "Default" then
local cppMap = {
["C++latest"] = "c++20",
["C++98"] = "c++98",
["C++0x"] = "c++11",
["C++11"] = "c++11",
["C++1y"] = "c++14",
["C++14"] = "c++14",
["C++1z"] = "c++17",
["C++17"] = "c++17",
["C++2a"] = "c++20",
["C++20"] = "c++20",
["gnu++98"] = "c++98",
["gnu++0x"] = "c++11",
["gnu++11"] = "c++11",
["gnu++1y"] = "c++14",
["gnu++14"] = "c++14",
["gnu++1z"] = "c++17",
["gnu++17"] = "c++17",
["gnu++2a"] = "c++20",
["gnu++20"] = "c++20",
}
if cppMap[cfg.cppdialect] ~= nil then
table.insert(opts, "-extern-std=" .. cppMap[cfg.cppdialect])
end
end
-- TODO: better way to check toolset?
if _OPTIONS.dc == "ldc" or cfg.flags.UseLDC then
if cfg.vectorextensions then
local vextMap = {
AVX = "avx",
AVX2 = "avx2",
SSE = "sse",
SSE2 = "sse2",
SSE3 = "sse3",
SSSE3 = "ssse3",
["SSE4.1"] = "sse4.1",
["SSE4.2"] = "sse4.2",
}
if vextMap[cfg.vectorextensions] ~= nil then
table.insert(opts, "-mattr=+" .. vextMap[cfg.vectorextensions])
end
end
if #cfg.isaextensions > 0 then
local isaMap = {
MOVBE = "movbe",
POPCNT = "popcnt",
PCLMUL = "pclmul",
LZCNT = "lzcnt",
BMI = "bmi",
BMI2 = "bmi2",
F16C = "f16c",
AES = "aes",
FMA = "fma",
FMA4 = "fma4",
RDRND = "rdrnd",
}
for _, ext in ipairs(cfg.isaextensions) do
if isaMap[ext] ~= nil then
table.insert(opts, "-mattr=+" .. isaMap[ext])
end
end
end
if #cfg.computetargets > 0 then
table.insert(opts, "-mdcompute-targets=" .. table.concat(cfg.computetargets, ','))
end
end
if #opts > 0 then
opts = table.concat(opts, " ")
vc2010.element("AdditionalOptions", condition, '%s %%(AdditionalOptions)', opts)
end
end

View File

@@ -0,0 +1,364 @@
--
-- d/actions/visuald.lua
-- Generate a VisualD .visualdproj project.
-- Copyright (c) 2012-2015 Manu Evans and the Premake project
--
local p = premake
local m = p.modules.d
m.visuald = {}
require ("vstudio")
local vstudio = p.vstudio
local workspace = p.workspace
local project = p.project
local config = p.config
local tree = p.tree
--
-- Patch the vstudio actions with D support...
--
for k,v in pairs({ "vs2005", "vs2008", "vs2010", "vs2012", "vs2013", "vs2015", "vs2017", "vs2019" }) do
local vs = p.action.get(v)
if vs ~= nil then
table.insert( vs.valid_languages, p.D )
vs.valid_tools.dc = { "dmd", "gdc", "ldc" }
p.override(vs, "onProject", function(oldfn, prj)
oldfn(prj)
if project.isd(prj) then
p.generate(prj, ".visualdproj", m.visuald.generate)
end
end)
end
end
--
-- Patch a bunch of other functions
--
p.override(project, "isnative", function(oldfn, prj)
return project.isd(prj) or oldfn(prj)
end)
p.override(vstudio, "projectfile", function(oldfn, prj)
if project.isd(prj) then
return p.filename(prj, ".visualdproj")
end
return oldfn(prj)
end)
p.override(vstudio, "tool", function(oldfn, prj)
if project.isd(prj) then
return "002A2DE9-8BB6-484D-9802-7E4AD4084715"
end
return oldfn(prj)
end)
--
-- Generate a Visual D project.
--
m.elements.project = function(prj)
return {
m.visuald.header,
m.visuald.globals,
m.visuald.projectConfigurations,
m.visuald.files,
}
end
function m.visuald.generate(prj)
p.eol("\r\n")
p.indent(" ")
p.callArray(m.elements.project, prj)
_p('</DProject>')
end
function m.visuald.header(prj)
-- for some reason Visual D projects don't seem to have an xml header
--_p('<?xml version="1.0" encoding="utf-8"?>')
_p('<DProject>')
end
function m.visuald.globals(prj)
_p(1,'<ProjectGuid>{%s}</ProjectGuid>', prj.uuid)
end
--
-- Write out the list of project configurations, which pairs build
-- configurations with architectures.
--
function m.visuald.projectConfigurations(prj)
-- build a list of all architectures used in this project
for cfg in project.eachconfig(prj) do
local prjPlatform = p.esc(vstudio.projectPlatform(cfg))
local slnPlatform = vstudio.solutionPlatform(cfg)
local is64bit = slnPlatform == "x64" -- TODO: this seems like a hack
_p(1,'<Config name="%s" platform="%s">', prjPlatform, slnPlatform)
_p(2,'<obj>0</obj>')
_p(2,'<link>0</link>')
local isWindows = false
local isDebug = string.find(cfg.buildcfg, 'Debug') ~= nil
local isOptimised = config.isOptimizedBuild(cfg)
if cfg.kind == p.CONSOLEAPP then
_p(2,'<lib>0</lib>')
_p(2,'<subsystem>1</subsystem>')
elseif cfg.kind == p.STATICLIB then
_p(2,'<lib>1</lib>')
_p(2,'<subsystem>0</subsystem>')
elseif cfg.kind == p.SHAREDLIB then
_p(2,'<lib>2</lib>')
_p(2,'<subsystem>0</subsystem>') -- SHOULD THIS BE '2' (windows)??
else
_p(2,'<lib>0</lib>')
_p(2,'<subsystem>2</subsystem>')
isWindows = true
end
_p(2,'<multiobj>0</multiobj>')
_p(2,'<singleFileCompilation>0</singleFileCompilation>')
_p(2,'<oneobj>0</oneobj>')
_p(2,'<trace>%s</trace>', iif(cfg.flags.Profile, '1', '0'))
_p(2,'<quiet>%s</quiet>', iif(cfg.flags.Quiet, '1', '0'))
_p(2,'<verbose>%s</verbose>', iif(cfg.flags.Verbose, '1', '0'))
_p(2,'<vtls>0</vtls>')
_p(2,'<symdebug>%s</symdebug>', iif(cfg.symbols == p.ON or cfg.symbols == "FastLink" or cfg.symbols == "Full", iif(cfg.flags.SymbolsLikeC, '2', '1'), '0'))
_p(2,'<optimize>%s</optimize>', iif(isOptimised, '1', '0'))
_p(2,'<cpu>0</cpu>')
_p(2,'<isX86_64>%s</isX86_64>', iif(is64bit, '1', '0'))
_p(2,'<isLinux>0</isLinux>')
_p(2,'<isOSX>0</isOSX>')
_p(2,'<isWindows>%s</isWindows>', iif(isWindows, '1', '0'))
_p(2,'<isFreeBSD>0</isFreeBSD>')
_p(2,'<isSolaris>0</isSolaris>')
_p(2,'<scheduler>0</scheduler>')
_p(2,'<useDeprecated>%s</useDeprecated>', iif(cfg.deprecatedfeatures == "Allow", '1', '0'))
_p(2,'<errDeprecated>0</errDeprecated>')
_p(2,'<useAssert>0</useAssert>')
_p(2,'<useInvariants>0</useInvariants>')
_p(2,'<useIn>0</useIn>')
_p(2,'<useOut>0</useOut>')
_p(2,'<useArrayBounds>0</useArrayBounds>')
_p(2,'<noboundscheck>%s</noboundscheck>', iif(cfg.boundscheck == "Off", '1', '0'))
_p(2,'<useSwitchError>0</useSwitchError>')
_p(2,'<useUnitTests>%s</useUnitTests>', iif(cfg.flags.UnitTest, '1', '0'))
_p(2,'<useInline>%s</useInline>', iif(cfg.flags.Inline or isOptimised, '1', '0'))
_p(2,'<release>%s</release>', iif(cfg.flags.Release or not isDebug, '1', '0'))
_p(2,'<preservePaths>0</preservePaths>')
_p(2,'<warnings>%s</warnings>', iif(cfg.flags.FatalCompileWarnings, '1', '0'))
_p(2,'<infowarnings>%s</infowarnings>', iif(cfg.warnings and cfg.warnings ~= "Off", '1', '0'))
_p(2,'<checkProperty>0</checkProperty>')
_p(2,'<genStackFrame>0</genStackFrame>')
_p(2,'<pic>%s</pic>', iif(cfg.pic == "On", '1', '0'))
_p(2,'<cov>%s</cov>', iif(cfg.flags.CodeCoverage, '1', '0'))
_p(2,'<nofloat>%s</nofloat>', iif(cfg.floatingpoint and cfg.floatingpoint == "None", '1', '0'))
_p(2,'<Dversion>2</Dversion>')
_p(2,'<ignoreUnsupportedPragmas>0</ignoreUnsupportedPragmas>')
local compiler = { dmd="0", gdc="1", ldc="2" }
local compilerName, err = p.api.checkValue(p.fields.toolset, _OPTIONS.dc or cfg.toolset or "dmd")
if err then
error { msg=err }
end
m.visuald.element(2, "compiler", compiler[compilerName])
m.visuald.element(2, "otherDMD", '0')
m.visuald.element(2, "program", '$(DMDInstallDir)windows\\bin\\dmd.exe')
local impdirs
if #cfg.importdirs > 0 then
impdirs = vstudio.path(cfg, cfg.importdirs)
end
m.visuald.element(2, "imppath", impdirs)
m.visuald.element(2, "fileImppath")
m.visuald.element(2, "outdir", path.translate(project.getrelative(cfg.project, cfg.buildtarget.directory)))
m.visuald.element(2, "objdir", path.translate(project.getrelative(cfg.project, cfg.objdir)))
m.visuald.element(2, "objname")
m.visuald.element(2, "libname")
m.visuald.element(2, "doDocComments", iif(cfg.flags.Documentation, '1', '0'))
m.visuald.element(2, "docdir", cfg.docdir)
m.visuald.element(2, "docname", cfg.docname)
m.visuald.element(2, "modules_ddoc")
m.visuald.element(2, "ddocfiles")
m.visuald.element(2, "doHdrGeneration", iif(cfg.flags.GenerateHeader, '1', '0'))
m.visuald.element(2, "hdrdir", cfg.headerdir)
m.visuald.element(2, "hdrname", cfg.headername)
m.visuald.element(2, "doXGeneration", iif(cfg.flags.GenerateJSON, '1', '0'))
m.visuald.element(2, "xfilename", '$(IntDir)\\$(TargetName).json')
m.visuald.element(2, "debuglevel", iif(cfg.debuglevel, tostring(cfg.debuglevel), '0'))
m.visuald.element(2, "debugids", cfg.debugconstants)
m.visuald.element(2, "versionlevel", iif(cfg.versionlevel, tostring(cfg.versionlevel), '0'))
m.visuald.element(2, "versionids", cfg.versionconstants)
_p(2,'<dump_source>0</dump_source>')
_p(2,'<mapverbosity>0</mapverbosity>')
_p(2,'<createImplib>%s</createImplib>', iif(cfg.kind ~= p.SHAREDLIB or cfg.flags.NoImportLib, '0', '1'))
_p(2,'<defaultlibname />')
_p(2,'<debuglibname />')
_p(2,'<moduleDepsFile />')
_p(2,'<run>0</run>')
_p(2,'<runargs />')
-- _p(2,'<runCv2pdb>%s</runCv2pdb>', iif(cfg.symbols == p.ON, '1', '0'))
_p(2,'<runCv2pdb>1</runCv2pdb>') -- we will just leave this always enabled, since it's ignored if no debuginfo is written
_p(2,'<pathCv2pdb>$(VisualDInstallDir)cv2pdb\\cv2pdb.exe</pathCv2pdb>')
_p(2,'<cv2pdbPre2043>0</cv2pdbPre2043>')
_p(2,'<cv2pdbNoDemangle>0</cv2pdbNoDemangle>')
_p(2,'<cv2pdbEnumType>0</cv2pdbEnumType>')
_p(2,'<cv2pdbOptions />')
_p(2,'<objfiles />')
_p(2,'<linkswitches />')
local links
local explicit = vstudio.needsExplicitLink(cfg)
-- check to see if this project uses an external toolset. If so, let the
-- toolset define the format of the links
local toolset = config.toolset(cfg)
if toolset then
links = toolset.getlinks(cfg, not explicit)
else
local scope = iif(explicit, "all", "system")
links = config.getlinks(cfg, scope, "fullpath")
end
m.visuald.element(2, "libfiles", table.concat(links, " "))
m.visuald.element(2, "libpaths", cfg.libdirs)
_p(2,'<deffile />')
_p(2,'<resfile />')
local target = config.gettargetinfo(cfg)
_p(2,'<exefile>$(OutDir)\\%s</exefile>', target.name)
_p(2,'<useStdLibPath>1</useStdLibPath>')
local runtime = 0
if not cfg.flags.OmitDefaultLibrary then
if config.isDebugBuild(cfg) then
runtime = iif(cfg.flags.StaticRuntime, "2", "4")
else
runtime = iif(cfg.flags.StaticRuntime, "1", "3")
end
end
m.visuald.element(2, "cRuntime", runtime)
local additionalOptions
if #cfg.buildoptions > 0 then
additionalOptions = table.concat(cfg.buildoptions, " ")
end
if #cfg.linkoptions > 0 then
local linkOpts = table.implode(cfg.linkoptions, "-L", "", " ")
if additionalOptions then
additionalOptions = additionalOptions .. " " .. linkOpts
else
additionalOptions = linkOpts
end
end
m.visuald.element(2, "additionalOptions", additionalOptions)
if #cfg.prebuildcommands > 0 then
_p(2,'<preBuildCommand>%s</preBuildCommand>',p.esc(table.implode(cfg.prebuildcommands, "", "", "\r\n")))
else
_p(2,'<preBuildCommand />')
end
if #cfg.postbuildcommands > 0 then
_p(2,'<postBuildCommand>%s</postBuildCommand>',p.esc(table.implode(cfg.postbuildcommands, "", "", "\r\n")))
else
_p(2,'<postBuildCommand />')
end
_p(2,'<filesToClean>*.obj;*.cmd;*.build;*.json;*.dep;*.o</filesToClean>')
_p(1,'</Config>')
end
end
--
-- Write out the source file tree.
--
function m.visuald.files(prj)
_p(1,'<Folder name="%s">', prj.name)
local tr = project.getsourcetree(prj)
tree.traverse(tr, {
-- folders, virtual or otherwise, are handled at the internal nodes
onbranchenter = function(node, depth)
_p(depth, '<Folder name="%s">', node.name)
end,
onbranchexit = function(node, depth)
_p(depth, '</Folder>')
end,
-- source files are handled at the leaves
onleaf = function(node, depth)
_p(depth, '<File path="%s" />', path.translate(node.relpath))
-- _p(depth, '<File path="%s">', path.translate(node.relpath))
-- m.visuald.fileConfiguration(prj, node, depth + 1)
-- _p(depth, '</File>')
end
}, false, 2)
_p(1,'</Folder>')
end
function m.visuald.fileConfiguration(prj, node, depth)
-- maybe we'll need this in the future...
end
--
-- Output an individual project XML element.
--
function m.visuald.element(depth, name, value, ...)
local isTable = type(value) == "table"
if not value or (isTable and #value == 0) then
_p(depth, '<%s />', name)
else
if isTable then
value = p.esc(table.implode(value, "", "", ";"))
_p(depth, '<%s>%s</%s>', name, value, name)
else
if select('#',...) == 0 then
value = p.esc(value)
end
_x(depth, string.format('<%s>%s</%s>', name, value, name), ...)
end
end
end