Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -0,0 +1,27 @@
Copyright (c) 2013-2015 Andrew Gough, Manu Evans, and individual contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of Premake nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,84 @@
Premake Extension to support the [D](http://dlang.org) language
### Features ###
* Support actions: gmake, vs20xx (VisualD)
* Support all compilers; DMD, LDC, GDC
* Support combined and separate compilation
### Usage ###
Simply add:
```lua
language "D"
```
to your project definition and populate with .d files.
C and C++ projects that include .d files will also support some of the API below. Any API tagged with (D/C/C++) works in D and C/C++ projects. Any API tagged with (C/C++) only works for .d files in C/C++ projects.
### APIs ###
* [flags](https://github.com/premake/premake-dlang/wiki/flags)
* AllInstantiate
* CodeCoverage
* Color
* Documentation
* GenerateHeader
* GenerateJSON
* GenerateMap
* IgnorePragma
* LowMem
* Main
* PerformSyntaxCheckOnly
* Profile
* ProfileGC
* Quiet
* RetainPaths
* ShowCommandLine
* ShowDependencies
* ShowGC
* ShowTLS
* StackFrame
* StackStomp
* SymbolsLikeC
* UnitTest
* UseLDC
* Verbose
* boundscheck ("type") [Off, SafeOnly, On]
* compilationmodel ("model") [ Project, Package, File ]
* checkaction
* computetargets
* [debugconstants](https://github.com/premake/premake-dlang/wiki/debugconstants)
* [debuglevel](https://github.com/premake/premake-dlang/wiki/debuglevel)
* dependenciesfile ("filename")
* deprecatedfeatures ("feature") [ Error, Info, Allow ]
* [docdir](https://github.com/premake/premake-dlang/wiki/docdir)
* [docname](https://github.com/premake/premake-dlang/wiki/docname)
* [headerdir](https://github.com/premake/premake-dlang/wiki/headerdir)
* [headername](https://github.com/premake/premake-dlang/wiki/headername)
* importdirs { "paths" }
* [inlining](https://github.com/premake/premake-core/wiki/inlining)
* jsonfile ("filename")
* importdirs
* [optimize](https://github.com/premake/premake-core/wiki/optimize)
* preview
* revert
* runtime ("type") [ Debug, Release ]
* staticruntime ("state") [ on, off ]
* stringimportdirs { "paths" }
* transition
* [versionconstants](https://github.com/premake/premake-dlang/wiki/versionconstants)
* [versionlevel](https://github.com/premake/premake-dlang/wiki/versionlevel)
### Example ###
The contents of your premake5.lua file would be:
```lua
solution "MySolution"
configurations { "release", "debug" }
project "MyDProject"
kind "ConsoleApp"
language "D"
files { "src/main.d", "src/extra.d" }
```

View file

@ -0,0 +1,10 @@
return {
"_preload.lua",
"d.lua",
"actions/gmake.lua",
"actions/vcxproj.lua",
"actions/visuald.lua",
"tools/dmd.lua",
"tools/gdc.lua",
"tools/ldc.lua",
}

View file

@ -0,0 +1,272 @@
--
-- Name: d/_preload.lua
-- Purpose: Define the D language API's.
-- Author: Manu Evans
-- Created: 2013/10/28
-- Copyright: (c) 2013-2015 Manu Evans and the Premake project
--
-- TODO:
-- MonoDevelop/Xamarin Studio has 'workspaces', which correspond to collections
-- of Premake workspaces. If premake supports multiple workspaces, we should
-- write out a workspace file...
local p = premake
local api = p.api
--
-- Register the D extension
--
p.D = "D"
api.addAllowed("language", p.D)
api.addAllowed("floatingpoint", "None")
api.addAllowed("flags", {
"CodeCoverage",
"Color",
"Documentation",
"GenerateHeader",
"GenerateJSON",
"GenerateMap",
"LowMem",
"Profile",
"Quiet",
"RetainPaths",
"SymbolsLikeC",
"UnitTest",
-- These are used by C++/D mixed $todo move them somewhere else? "flags2" "Dflags"?
-- [Code Generation Flags]
"UseLDC",
"ProfileGC",
"StackFrame",
"StackStomp",
"AllInstantiate",
"BetterC",
"Main",
"PerformSyntaxCheckOnly",
-- [Messages Flags]
"ShowCommandLine",
"Verbose",
"ShowTLS",
"ShowGC",
"IgnorePragma",
"ShowDependencies",
})
api.addAllowed("toolset", {
"dmd",
"gdc",
"ldc",
})
--
-- Register some D specific properties
--
api.register {
name = "boundscheck",
scope = "config",
kind = "string",
allowed = {
"Default",
"Off",
"On",
"SafeOnly",
},
}
api.register {
name = "compilationmodel",
scope = "config",
kind = "string",
allowed = {
"Default",
"File",
"Package", -- TODO: this doesn't work with gmake!!
"Project",
},
}
api.register {
name = "checkaction",
scope = "config",
kind = "string",
allowed = {
"Default",
"D",
"C",
"Halt",
"Context",
},
}
api.register {
name = "computetargets",
scope = "config",
kind = "list:string",
}
-- api.register {
-- name = "debugcode",
-- scope = "config",
-- kind = "string",
-- }
api.register {
name = "debugconstants",
scope = "config",
kind = "list:string",
tokens = true,
}
api.register {
name = "debuglevel",
scope = "config",
kind = "integer",
}
api.register {
name = "dependenciesfile",
scope = "config",
kind = "path",
tokens = true,
}
api.register {
name = "deprecatedfeatures",
scope = "config",
kind = "string",
allowed = {
"Default",
"Allow",
"Warn",
"Error",
},
}
api.register {
name = "docdir",
scope = "config",
kind = "path",
tokens = true,
}
api.register {
name = "docname",
scope = "config",
kind = "string",
tokens = true,
}
api.register {
name = "headerdir",
scope = "config",
kind = "path",
tokens = true,
}
api.register {
name = "headername",
scope = "config",
kind = "string",
tokens = true,
}
api.register {
name = "jsonfile",
scope = "config",
kind = "path",
tokens = true,
}
api.register {
name = "importdirs",
scope = "config",
kind = "list:path",
tokens = true,
}
api.register {
name = "preview",
scope = "config",
kind = "list:string",
allowed = {
"dip25",
"dip1000",
"dip1008",
"fieldwise",
"markdown",
"fixAliasThis",
"intpromote",
"dtorfields",
},
}
api.register {
name = "revert",
scope = "config",
kind = "list:string",
allowed = {
"dip25",
"import",
},
}
api.register {
name = "stringimportdirs",
scope = "config",
kind = "list:path",
tokens = true,
}
api.register {
name = "transition",
scope = "config",
kind = "list:string",
allowed = {
"field",
"checkimports",
"complex",
"tls",
"vmarkdown",
},
}
api.register {
name = "versionconstants",
scope = "config",
kind = "list:string",
tokens = true,
}
api.register {
name = "versionlevel",
scope = "config",
kind = "integer",
}
--
-- Provide information for the help output
--
newoption
{
category = "compilers",
trigger = "dc",
value = "VALUE",
description = "Choose a D compiler",
allowed = {
{ "dmd", "Digital Mars (dmd)" },
{ "gdc", "GNU GDC (gdc)" },
{ "ldc", "LLVM LDC (ldc2)" },
}
}
--
-- Decide when to load the full module
--
return function (cfg)
return (cfg.language == p.D or cfg.language == "C" or cfg.language == "C++")
end

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

View file

@ -0,0 +1,49 @@
--
-- d/d.lua
-- Define the D makefile action(s).
-- Copyright (c) 2013-2015 Andrew Gough, Manu Evans, and the Premake project
--
local p = premake
p.modules.d = {}
local m = p.modules.d
m._VERSION = p._VERSION
m.elements = {}
local api = p.api
--
-- Patch the project table to provide knowledge of D projects
--
function p.project.isd(prj)
return prj.language == p.D
end
--
-- Patch the path table to provide knowledge of D file extenstions
--
function path.isdfile(fname)
return path.hasextension(fname, { ".d" })
end
function path.isdheader(fname)
return path.hasextension(fname, { ".di" })
end
--
-- Patch actions
--
include( "tools/dmd.lua" )
include( "tools/gdc.lua" )
include( "tools/ldc.lua" )
include( "actions/gmake.lua" )
include( "actions/vcxproj.lua" )
include( "actions/visuald.lua" )
return m

View file

@ -0,0 +1,9 @@
require ("d")
return {
"test_visualstudio.lua",
"test_gmake.lua",
"test_dmd.lua",
"test_gdc.lua",
"test_ldc.lua",
}

View file

@ -0,0 +1,106 @@
---
-- d/tests/test_dmd.lua
-- Automated test suite for dmd.
-- Copyright (c) 2011-2015 Manu Evans and the Premake project
---
local suite = test.declare("d_dmd")
local p = premake
local m = p.modules.d
local make = p.make
local project = p.project
---------------------------------------------------------------------------
-- Setup/Teardown
---------------------------------------------------------------------------
local wks, prj, cfg
function suite.setup()
p.escaper(make.esc)
wks = test.createWorkspace()
end
local function prepare_cfg(calls)
prj = p.workspace.getproject(wks, 1)
local cfg = test.getconfig(prj, "Debug")
local toolset = p.tools.dmd
p.callArray(calls, cfg, toolset)
end
--
-- Check configuration generation
--
function suite.dmd_dTools()
prepare_cfg({ m.make.dTools })
test.capture [[
DC = dmd
]]
end
function suite.dmd_target()
prepare_cfg({ m.make.target })
test.capture [[
]]
end
function suite.dmd_target_separateCompilation()
compilationmodel "File"
prepare_cfg({ m.make.target })
test.capture [[
OUTPUTFLAG = -of"$@"
]]
end
function suite.dmd_versions()
versionlevel (10)
versionconstants { "A", "B" }
prepare_cfg({ m.make.versions })
test.capture [[
VERSIONS += -version=A -version=B -version=10
]]
end
function suite.dmd_debug()
debuglevel (10)
debugconstants { "A", "B" }
prepare_cfg({ m.make.debug })
test.capture [[
DEBUG += -debug=A -debug=B -debug=10
]]
end
function suite.dmd_imports()
importdirs { "dir1", "dir2/" }
prepare_cfg({ m.make.imports })
test.capture [[
IMPORTS += -Idir1 -Idir2
]]
end
function suite.dmd_dFlags()
prepare_cfg({ m.make.dFlags })
test.capture [[
ALL_DFLAGS += $(DFLAGS) -release $(VERSIONS) $(DEBUG) $(IMPORTS) $(STRINGIMPORTS) $(ARCH)
]]
end
function suite.dmd_linkCmd()
prepare_cfg({ m.make.linkCmd })
test.capture [[
BUILDCMD = $(DC) -of$(TARGET) $(ALL_DFLAGS) $(ALL_LDFLAGS) $(LIBS) $(SOURCEFILES)
]]
end
function suite.dmd_linkCmd_separateCompilation()
compilationmodel "File"
prepare_cfg({ m.make.linkCmd })
test.capture [[
LINKCMD = $(DC) -of$(TARGET) $(ALL_LDFLAGS) $(LIBS) $(OBJECTS)
]]
end

View file

@ -0,0 +1,106 @@
---
-- d/tests/test_dmd.lua
-- Automated test suite for dmd.
-- Copyright (c) 2011-2015 Manu Evans and the Premake project
---
local suite = test.declare("d_gdc")
local p = premake
local m = p.modules.d
local make = p.make
local project = p.project
---------------------------------------------------------------------------
-- Setup/Teardown
---------------------------------------------------------------------------
local wks, prj, cfg
function suite.setup()
p.escaper(make.esc)
wks = test.createWorkspace()
end
local function prepare_cfg(calls)
prj = p.workspace.getproject(wks, 1)
local cfg = test.getconfig(prj, "Debug")
local toolset = p.tools.gdc
p.callArray(calls, cfg, toolset)
end
--
-- Check configuration generation
--
function suite.dmd_dTools()
prepare_cfg({ m.make.dTools })
test.capture [[
DC = gdc
]]
end
function suite.dmd_target()
prepare_cfg({ m.make.target })
test.capture [[
]]
end
function suite.dmd_target_separateCompilation()
compilationmodel "File"
prepare_cfg({ m.make.target })
test.capture [[
OUTPUTFLAG = -o "$@"
]]
end
function suite.dmd_versions()
versionlevel (10)
versionconstants { "A", "B" }
prepare_cfg({ m.make.versions })
test.capture [[
VERSIONS += -fversion=A -fversion=B -fversion=10
]]
end
function suite.dmd_debug()
debuglevel (10)
debugconstants { "A", "B" }
prepare_cfg({ m.make.debug })
test.capture [[
DEBUG += -fdebug=A -fdebug=B -fdebug=10
]]
end
function suite.dmd_imports()
importdirs { "dir1", "dir2/" }
prepare_cfg({ m.make.imports })
test.capture [[
IMPORTS += -Idir1 -Idir2
]]
end
function suite.dmd_dFlags()
prepare_cfg({ m.make.dFlags })
test.capture [[
ALL_DFLAGS += $(DFLAGS) -frelease $(VERSIONS) $(DEBUG) $(IMPORTS) $(STRINGIMPORTS) $(ARCH)
]]
end
function suite.dmd_linkCmd()
prepare_cfg({ m.make.linkCmd })
test.capture [[
BUILDCMD = $(DC) -o $(TARGET) $(ALL_DFLAGS) $(ALL_LDFLAGS) $(LIBS) $(SOURCEFILES)
]]
end
function suite.dmd_linkCmd_separateCompilation()
compilationmodel "File"
prepare_cfg({ m.make.linkCmd })
test.capture [[
LINKCMD = $(DC) -o $(TARGET) $(ALL_LDFLAGS) $(LIBS) $(OBJECTS)
]]
end

View file

@ -0,0 +1,222 @@
---
-- d/tests/test_gmake.lua
-- Automated test suite for gmake project generation.
-- Copyright (c) 2011-2015 Manu Evans and the Premake project
---
local suite = test.declare("d_make")
local p = premake
local m = p.modules.d
local make = p.make
local project = p.project
---------------------------------------------------------------------------
-- Setup/Teardown
---------------------------------------------------------------------------
local wks, prj, cfg
function suite.setup()
p.escaper(make.esc)
wks = test.createWorkspace()
end
local function prepare()
prj = p.workspace.getproject(wks, 1)
end
local function prepare_cfg(calls)
prj = p.workspace.getproject(wks, 1)
local cfg = test.getconfig(prj, "Debug")
local toolset = m.make.getToolset(cfg) or p.tools.dmd
p.callArray(calls, cfg, toolset)
end
--
-- Check project generation
--
function suite.make_targetRules()
prepare()
m.make.targetRules(prj)
test.capture [[
$(TARGET): $(SOURCEFILES) $(LDDEPS)
@echo Building MyProject
$(SILENT) $(BUILDCMD)
$(POSTBUILDCMDS)
]]
end
function suite.make_targetRules_separateCompilation()
compilationmodel "File"
prepare()
m.make.targetRules(prj)
test.capture [[
$(TARGET): $(OBJECTS) $(LDDEPS)
@echo Linking MyProject
$(SILENT) $(LINKCMD)
$(POSTBUILDCMDS)
]]
end
function suite.make_targetRules_mixedCompilation()
configuration { "Release" }
compilationmodel "File"
prepare()
m.make.targetRules(prj)
test.capture [[
ifeq ($(config),debug)
$(TARGET): $(SOURCEFILES) $(LDDEPS)
@echo Building MyProject
$(SILENT) $(BUILDCMD)
$(POSTBUILDCMDS)
endif
ifeq ($(config),release)
$(TARGET): $(OBJECTS) $(LDDEPS)
@echo Linking MyProject
$(SILENT) $(LINKCMD)
$(POSTBUILDCMDS)
endif
]]
end
function suite.make_fileRules()
files { "blah.d" }
prepare()
m.make.dFileRules(prj)
test.capture [[
]]
end
function suite.make_fileRules_separateCompilation()
files { "blah.d" }
compilationmodel "File"
prepare()
m.make.dFileRules(prj)
test.capture [[
$(OBJDIR)/blah.o: blah.d
@echo $(notdir $<)
$(SILENT) $(DC) $(ALL_DFLAGS) $(OUTPUTFLAG) -c $<
]]
end
function suite.make_fileRules_mixedCompilation()
files { "blah.d" }
configuration { "Release" }
compilationmodel "File"
prepare()
m.make.dFileRules(prj)
test.capture [[
$(OBJDIR)/blah.o: blah.d
@echo $(notdir $<)
$(SILENT) $(DC) $(ALL_DFLAGS) $(OUTPUTFLAG) -c $<
]]
end
function suite.make_objects()
files { "blah.d" }
prepare()
m.make.objects(prj)
test.capture [[
SOURCEFILES := \
blah.d \
]]
end
function suite.make_objects_separateCompilation()
files { "blah.d" }
compilationmodel "File"
prepare()
m.make.objects(prj)
test.capture [[
OBJECTS := \
$(OBJDIR)/blah.o \
]]
end
function suite.make_objects_mixedCompilation()
files { "blah.d" }
configuration { "Release" }
compilationmodel "File"
files { "blah2.d" }
prepare()
m.make.objects(prj)
test.capture [[
SOURCEFILES := \
blah.d \
OBJECTS := \
$(OBJDIR)/blah.o \
ifeq ($(config),release)
SOURCEFILES += \
blah2.d \
OBJECTS += \
$(OBJDIR)/blah2.o \
endif
]]
end
--
-- Check configuration generation
--
function suite.make_allRules()
prepare_cfg({ m.make.allRules })
test.capture [[
all: $(TARGETDIR) prebuild prelink $(TARGET)
@:
]]
end
function suite.make_allRules_separateCompilation()
compilationmodel "File"
prepare_cfg({ m.make.allRules })
test.capture [[
all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET)
@:
]]
end
function suite.make_dTools_dmd()
toolset "dmd"
prepare_cfg({ m.make.dTools })
test.capture [[
DC = dmd
]]
end
function suite.make_dTools_gdc()
toolset "gdc"
prepare_cfg({ m.make.dTools })
test.capture [[
DC = gdc
]]
end
function suite.make_dTools_ldc()
toolset "ldc"
prepare_cfg({ m.make.dTools })
test.capture [[
DC = ldc2
]]
end

View file

@ -0,0 +1,106 @@
---
-- d/tests/test_dmd.lua
-- Automated test suite for dmd.
-- Copyright (c) 2011-2015 Manu Evans and the Premake project
---
local suite = test.declare("d_ldc")
local p = premake
local m = p.modules.d
local make = p.make
local project = p.project
---------------------------------------------------------------------------
-- Setup/Teardown
---------------------------------------------------------------------------
local wks, prj, cfg
function suite.setup()
p.escaper(make.esc)
wks = test.createWorkspace()
end
local function prepare_cfg(calls)
prj = p.workspace.getproject(wks, 1)
local cfg = test.getconfig(prj, "Debug")
local toolset = p.tools.ldc
p.callArray(calls, cfg, toolset)
end
--
-- Check configuration generation
--
function suite.dmd_dTools()
prepare_cfg({ m.make.dTools })
test.capture [[
DC = ldc2
]]
end
function suite.dmd_target()
prepare_cfg({ m.make.target })
test.capture [[
]]
end
function suite.dmd_target_separateCompilation()
compilationmodel "File"
prepare_cfg({ m.make.target })
test.capture [[
OUTPUTFLAG = -of="$@"
]]
end
function suite.dmd_versions()
versionlevel (10)
versionconstants { "A", "B" }
prepare_cfg({ m.make.versions })
test.capture [[
VERSIONS += -d-version=A -d-version=B -d-version=10
]]
end
function suite.dmd_debug()
debuglevel (10)
debugconstants { "A", "B" }
prepare_cfg({ m.make.debug })
test.capture [[
DEBUG += -d-debug=A -d-debug=B -d-debug=10
]]
end
function suite.dmd_imports()
importdirs { "dir1", "dir2/" }
prepare_cfg({ m.make.imports })
test.capture [[
IMPORTS += -I=dir1 -I=dir2
]]
end
function suite.dmd_dFlags()
prepare_cfg({ m.make.dFlags })
test.capture [[
ALL_DFLAGS += $(DFLAGS) -release $(VERSIONS) $(DEBUG) $(IMPORTS) $(STRINGIMPORTS) $(ARCH)
]]
end
function suite.dmd_linkCmd()
prepare_cfg({ m.make.linkCmd })
test.capture [[
BUILDCMD = $(DC) -of=$(TARGET) $(ALL_DFLAGS) $(ALL_LDFLAGS) $(LIBS) $(SOURCEFILES)
]]
end
function suite.dmd_linkCmd_separateCompilation()
compilationmodel "File"
prepare_cfg({ m.make.linkCmd })
test.capture [[
LINKCMD = $(DC) -of=$(TARGET) $(ALL_LDFLAGS) $(LIBS) $(OBJECTS)
]]
end

View file

@ -0,0 +1,75 @@
---
-- d/tests/test_visualstudio.lua
-- Automated test suite for VisualD project generation.
-- Copyright (c) 2011-2015 Manu Evans and the Premake project
---
local suite = test.declare("visual_d")
local p = premake
local m = p.modules.d
---------------------------------------------------------------------------
-- Setup/Teardown
---------------------------------------------------------------------------
local wks, prj, cfg
function suite.setup()
p.action.set("vs2010")
-- p.escaper(p.vstudio.vs2005.esc)
p.indent(" ")
wks = workspace "MyWorkspace"
configurations { "Debug", "Release" }
language "D"
kind "ConsoleApp"
end
local function prepare()
prj = project "MyProject"
end
local function prepare_cfg()
prj = project "MyProject"
cfg = test.getconfig(prj, "Debug")
end
--
-- Check sln for the proper project entry
--
function suite.slnProj()
project "MyProject"
language "D"
p.vstudio.sln2005.reorderProjects(wks)
p.vstudio.sln2005.projects(wks)
test.capture [[
Project("{002A2DE9-8BB6-484D-9802-7E4AD4084715}") = "MyProject", "MyProject.visualdproj", "{42B5DBC6-AE1F-903D-F75D-41E363076E92}"
EndProject
]]
end
--
-- Project tests
--
function suite.OnProject_header()
prepare()
m.visuald.header(prj)
test.capture [[
<DProject>
]]
end
function suite.OnProject_globals()
prepare()
m.visuald.globals(prj)
test.capture [[
<ProjectGuid>{42B5DBC6-AE1F-903D-F75D-41E363076E92}</ProjectGuid>
]]
end
-- TODO: break up the project gen and make lots more tests...

View file

@ -0,0 +1,486 @@
--
-- d/tools/dmd.lua
-- Provides dmd-specific configuration strings.
-- Copyright (c) 2013-2015 Andrew Gough, Manu Evans, and the Premake project
--
local tdmd = {}
local p = premake
local project = p.project
local config = p.config
local d = p.modules.d
--
-- Set default tools
--
tdmd.gcc = {}
tdmd.gcc.dc = "dmd"
tdmd.optlink = {}
tdmd.optlink.dc = "dmd"
-- /////////////////////////////////////////////////////////////////////////
-- dmd + GCC toolchain
-- /////////////////////////////////////////////////////////////////////////
--
-- Return a list of LDFLAGS for a specific configuration.
--
tdmd.gcc.ldflags = {
architecture = {
x86 = { "-m32" },
x86_64 = { "-m64" },
},
kind = {
SharedLib = "-shared",
StaticLib = "-lib",
}
}
function tdmd.gcc.getldflags(cfg)
local flags = config.mapFlags(cfg, tdmd.gcc.ldflags)
return flags
end
--
-- Return a list of decorated additional libraries directories.
--
tdmd.gcc.libraryDirectories = {
architecture = {
x86 = "-L-L/usr/lib",
x86_64 = "-L-L/usr/lib64",
}
}
function tdmd.gcc.getLibraryDirectories(cfg)
local flags = config.mapFlags(cfg, tdmd.gcc.libraryDirectories)
-- Scan the list of linked libraries. If any are referenced with
-- paths, add those to the list of library search paths
for _, dir in ipairs(config.getlinks(cfg, "system", "directory")) do
table.insert(flags, '-L-L' .. project.getrelative(cfg.project, dir))
end
return flags
end
--
-- Return the list of libraries to link, decorated with flags as needed.
--
function tdmd.gcc.getlinks(cfg, systemonly)
local result = {}
local links
if not systemonly then
links = config.getlinks(cfg, "siblings", "object")
for _, link in ipairs(links) do
-- skip external project references, since I have no way
-- to know the actual output target path
if not link.project.external then
if link.kind == p.STATICLIB then
-- Don't use "-l" flag when linking static libraries; instead use
-- path/libname.a to avoid linking a shared library of the same
-- name if one is present
table.insert(result, "-L" .. project.getrelative(cfg.project, link.linktarget.abspath))
else
table.insert(result, "-L-l" .. link.linktarget.basename)
end
end
end
end
-- The "-l" flag is fine for system libraries
links = config.getlinks(cfg, "system", "fullpath")
for _, link in ipairs(links) do
if path.isframework(link) then
table.insert(result, "-framework " .. path.getbasename(link))
elseif path.isobjectfile(link) then
table.insert(result, "-L" .. link)
else
table.insert(result, "-L-l" .. path.getbasename(link))
end
end
return result
end
-- /////////////////////////////////////////////////////////////////////////
-- tdmd + OPTLINK toolchain
-- /////////////////////////////////////////////////////////////////////////
--
-- Return a list of LDFLAGS for a specific configuration.
--
tdmd.optlink.ldflags = {
architecture = {
x86 = { "-m32" },
x86_64 = { "-m64" },
},
kind = {
SharedLib = "-shared",
StaticLib = "-lib",
}
}
function tdmd.optlink.getldflags(cfg)
local flags = config.mapFlags(cfg, tdmd.optlink.ldflags)
return flags
end
--
-- Return a list of decorated additional libraries directories.
--
function tdmd.optlink.getLibraryDirectories(cfg)
local flags = {}
-- Scan the list of linked libraries. If any are referenced with
-- paths, add those to the list of library search paths
for _, dir in ipairs(config.getlinks(cfg, "system", "directory")) do
table.insert(flags, '-Llib "' .. project.getrelative(cfg.project, dir) .. '"')
end
return flags
end
--
-- Returns a list of linker flags for library names.
--
function tdmd.optlink.getlinks(cfg)
local result = {}
local links = config.getlinks(cfg, "dependencies", "object")
for _, link in ipairs(links) do
-- skip external project references, since I have no way
-- to know the actual output target path
if not link.project.externalname then
local linkinfo = config.getlinkinfo(link)
if link.kind == p.STATICLIB then
table.insert(result, project.getrelative(cfg.project, linkinfo.abspath))
end
end
end
-- The "-l" flag is fine for system libraries
links = config.getlinks(cfg, "system", "basename")
for _, link in ipairs(links) do
if path.isobjectfile(link) then
table.insert(result, link)
elseif path.hasextension(link, p.systems[cfg.system].staticlib.extension) then
table.insert(result, link)
end
end
return result
end
-- /////////////////////////////////////////////////////////////////////////
-- common dmd code (either toolchain)
-- /////////////////////////////////////////////////////////////////////////
-- if we are compiling on windows, we need to specialise to OPTLINK as the linker
-- OR!!! if cfg.system ~= p.WINDOWS then
if string.match( os.getversion().description, "Windows" ) ~= nil then
-- TODO: on windows, we may use OPTLINK or MSLINK (for Win64)...
-- printf("TODO: select proper linker for 32/64 bit code")
p.tools.dmd = tdmd.optlink
else
p.tools.dmd = tdmd.gcc
end
local dmd = p.tools.dmd
--
-- Returns list of D compiler flags for a configuration.
--
dmd.dflags = {
architecture = {
x86 = "-m32mscoff",
x86_64 = "-m64",
},
flags = {
OmitDefaultLibrary = "-mscrtlib=",
CodeCoverage = "-cov",
Color = "-color",
Documentation = "-D",
FatalWarnings = "-w",
GenerateHeader = "-H",
GenerateJSON = "-X",
GenerateMap = "-map",
LowMem = "-lowmem",
Profile = "-profile",
Quiet = "-quiet",
RetainPaths = "-op",
SymbolsLikeC = "-gc",
UnitTest = "-unittest",
Verbose = "-v",
ProfileGC = "-profile=gc",
StackFrame = "-gs",
StackStomp = "-gx",
AllInstantiate = "-allinst",
BetterC = "-betterC",
Main = "-main",
PerformSyntaxCheckOnly = "-o-",
ShowTLS = "-vtls",
ShowGC = "-vgc",
IgnorePragma = "-ignore",
ShowDependencies = "-deps",
},
boundscheck = {
Off = "-boundscheck=off",
On = "-boundscheck=on",
SafeOnly = "-boundscheck=safeonly",
},
checkaction = {
D = "-checkaction=D",
C = "-checkaction=C",
Halt = "-checkaction=halt",
Context = "-checkaction=context",
},
cppdialect = {
["C++latest"] = "-extern-std=c++20", -- TODO: keep this up to date >_<
["C++98"] = "-extern-std=c++98",
["C++0x"] = "-extern-std=c++11",
["C++11"] = "-extern-std=c++11",
["C++1y"] = "-extern-std=c++14",
["C++14"] = "-extern-std=c++14",
["C++1z"] = "-extern-std=c++17",
["C++17"] = "-extern-std=c++17",
["C++2a"] = "-extern-std=c++20",
["C++20"] = "-extern-std=c++20",
["gnu++98"] = "-extern-std=c++98",
["gnu++0x"] = "-extern-std=c++11",
["gnu++11"] = "-extern-std=c++11",
["gnu++1y"] = "-extern-std=c++14",
["gnu++14"] = "-extern-std=c++14",
["gnu++1z"] = "-extern-std=c++17",
["gnu++17"] = "-extern-std=c++17",
["gnu++2a"] = "-extern-std=c++20",
["gnu++20"] = "-extern-std=c++20",
},
deprecatedfeatures = {
Allow = "-d",
Warn = "-dw",
Error = "-de",
},
floatingpoint = {
None = "-nofloat",
},
optimize = {
On = "-O -inline",
Full = "-O -inline",
Size = "-O -inline",
Speed = "-O -inline",
},
pic = {
On = "-fPIC",
},
symbols = {
On = "-g",
FastLink = "-g",
Full = "-g",
},
vectorextensions = {
AVX = "-mcpu=avx",
AVX2 = "-mcpu=avx2",
},
warnings = {
Default = "-wi",
High = "-wi",
Extra = "-wi",
Everything = "-wi",
},
}
function dmd.getdflags(cfg)
local flags = config.mapFlags(cfg, dmd.dflags)
if config.isDebugBuild(cfg) then
table.insert(flags, "-debug")
else
table.insert(flags, "-release")
end
if not cfg.flags.OmitDefaultLibrary then
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
table.insert(flags, "-mscrtlib=libcmt")
elseif staticruntime == true and releaseruntime == false then
table.insert(flags, "-mscrtlib=libcmtd")
elseif staticruntime == false and releaseruntime == true then
table.insert(flags, "-mscrtlib=msvcrt")
elseif staticruntime == false and releaseruntime == false then
table.insert(flags, "-mscrtlib=msvcrtd")
end
end
end
if cfg.flags.Documentation then
if cfg.docname then
table.insert(flags, "-Df" .. p.quoted(cfg.docname))
end
if cfg.docdir then
table.insert(flags, "-Dd" .. p.quoted(cfg.docdir))
end
end
if cfg.flags.GenerateHeader then
if cfg.headername then
table.insert(flags, "-Hf" .. p.quoted(cfg.headername))
end
if cfg.headerdir then
table.insert(flags, "-Hd" .. p.quoted(cfg.headerdir))
end
end
if #cfg.preview > 0 then
for _, opt in ipairs(cfg.preview) do
table.insert(flags, "-preview=" .. opt)
end
end
if #cfg.revert > 0 then
for _, opt in ipairs(cfg.revert) do
table.insert(flags, "-revert=" .. opt)
end
end
if #cfg.transition > 0 then
for _, opt in ipairs(cfg.transition) do
table.insert(flags, "-transition=" .. opt)
end
end
return flags
end
--
-- Decorate versions for the DMD command line.
--
function dmd.getversions(versions, level)
local result = {}
for _, version in ipairs(versions) do
table.insert(result, '-version=' .. version)
end
if level then
table.insert(result, '-version=' .. level)
end
return result
end
--
-- Decorate debug constants for the DMD command line.
--
function dmd.getdebug(constants, level)
local result = {}
for _, constant in ipairs(constants) do
table.insert(result, '-debug=' .. constant)
end
if level then
table.insert(result, '-debug=' .. level)
end
return result
end
--
-- Decorate import file search paths for the DMD command line.
--
function dmd.getimportdirs(cfg, dirs)
local result = {}
for _, dir in ipairs(dirs) do
dir = project.getrelative(cfg.project, dir)
table.insert(result, '-I' .. p.quoted(dir))
end
return result
end
--
-- Decorate string import file search paths for the DMD command line.
--
function dmd.getstringimportdirs(cfg, dirs)
local result = {}
for _, dir in ipairs(dirs) do
dir = project.getrelative(cfg.project, dir)
table.insert(result, '-J' .. p.quoted(dir))
end
return result
end
--
-- Returns the target name specific to compiler
--
function dmd.gettarget(name)
return "-of" .. name
end
--
-- Returns makefile-specific configuration rules.
--
dmd.makesettings = {
}
function dmd.getmakesettings(cfg)
local settings = config.mapFlags(cfg, dmd.makesettings)
return table.concat(settings)
end
--
-- Retrieves the executable command name for a tool, based on the
-- provided configuration and the operating environment.
--
-- @param cfg
-- The configuration to query.
-- @param tool
-- The tool to fetch, one of "dc" for the D compiler, or "ar" for the static linker.
-- @return
-- The executable command name for a tool, or nil if the system's
-- default value should be used.
--
dmd.tools = {
-- dmd will probably never support any foreign architectures...?
}
function dmd.gettoolname(cfg, tool)
local names = dmd.tools[cfg.architecture] or dmd.tools[cfg.system] or {}
local name = names[tool]
return name or dmd[tool]
end

View file

@ -0,0 +1,328 @@
--
-- d/tools/gdc.lua
-- Provides GDC-specific configuration strings.
-- Copyright (c) 2013-2015 Andrew Gough, Manu Evans, and the Premake project
--
local p = premake
p.tools.gdc = { }
local gdc = p.tools.gdc
local project = p.project
local config = p.config
local d = p.modules.d
--
-- Set default tools
--
gdc.dc = "gdc"
--
-- Returns list of D compiler flags for a configuration.
--
gdc.dflags = {
architecture = {
x86 = "-m32",
x86_64 = "-m64",
},
flags = {
Documentation = "-fdoc",
FatalWarnings = "-Werror",
GenerateHeader = "-fintfc",
GenerateJSON = "-fX",
-- Release = "-frelease",
RetainPaths = "-op",
SymbolsLikeC = "-fdebug-c",
UnitTest = "-funittest",
Verbose = "-fd-verbose",
-- THESE ARE THE DMD ARGS...
-- ProfileGC = "-profile=gc",
-- StackFrame = "-gs",
-- StackStomp = "-gx",
-- AllInstantiate = "-allinst",
-- BetterC = "-betterC",
-- Main = "-main",
-- PerformSyntaxCheckOnly = "-o-",
ShowTLS = "-fd-vtls",
-- ShowGC = "-vgc",
-- IgnorePragma = "-ignore",
ShowDependencies = "-fdeps",
},
boundscheck = {
Off = "-fno-bounds-check",
-- On = "-boundscheck=on",
-- SafeOnly = "-boundscheck=safeonly",
},
deprecatedfeatures = {
Allow = "-fdeprecated",
-- Warn = "-dw",
-- Error = "-de",
},
floatingpoint = {
Fast = "-ffast-math",
Strict = "-ffloat-store",
},
optimize = {
Off = "-O0",
On = "-O2 -finline-functions",
Debug = "-Og",
Full = "-O3 -finline-functions",
Size = "-Os -finline-functions",
Speed = "-O3 -finline-functions",
},
pic = {
On = "-fPIC",
},
vectorextensions = {
AVX = "-mavx",
SSE = "-msse",
SSE2 = "-msse2",
},
warnings = {
-- Default = "-w", -- TODO: check this...
High = "-Wall",
Extra = "-Wall -Wextra",
Everything = "-Weverything",
},
symbols = {
On = "-g",
FastLink = "-g",
Full = "-g -gf",
}
}
function gdc.getdflags(cfg)
local flags = config.mapFlags(cfg, gdc.dflags)
if config.isDebugBuild(cfg) then
table.insert(flags, "-fdebug")
else
table.insert(flags, "-frelease")
end
if cfg.flags.Documentation then
if cfg.docname then
table.insert(flags, "-fdoc-file=" .. p.quoted(cfg.docname))
end
if cfg.docdir then
table.insert(flags, "-fdoc-dir=" .. p.quoted(cfg.docdir))
end
end
if cfg.flags.GenerateHeader then
if cfg.headername then
table.insert(flags, "-fintfc-file=" .. p.quoted(cfg.headername))
end
if cfg.headerdir then
table.insert(flags, "-fintfc-dir=" .. p.quoted(cfg.headerdir))
end
end
return flags
end
--
-- Decorate versions for the DMD command line.
--
function gdc.getversions(versions, level)
local result = {}
for _, version in ipairs(versions) do
table.insert(result, '-fversion=' .. version)
end
if level then
table.insert(result, '-fversion=' .. level)
end
return result
end
--
-- Decorate debug constants for the DMD command line.
--
function gdc.getdebug(constants, level)
local result = {}
for _, constant in ipairs(constants) do
table.insert(result, '-fdebug=' .. constant)
end
if level then
table.insert(result, '-fdebug=' .. level)
end
return result
end
--
-- Decorate import file search paths for the DMD command line.
--
function gdc.getimportdirs(cfg, dirs)
local result = {}
for _, dir in ipairs(dirs) do
dir = project.getrelative(cfg.project, dir)
table.insert(result, '-I' .. p.quoted(dir))
end
return result
end
--
-- Decorate import file search paths for the DMD command line.
--
function gdc.getstringimportdirs(cfg, dirs)
local result = {}
for _, dir in ipairs(dirs) do
dir = project.getrelative(cfg.project, dir)
table.insert(result, '-J' .. p.quoted(dir))
end
return result
end
--
-- Returns the target name specific to compiler
--
function gdc.gettarget(name)
return "-o " .. name
end
--
-- Return a list of LDFLAGS for a specific configuration.
--
gdc.ldflags = {
architecture = {
x86 = { "-m32" },
x86_64 = { "-m64" },
},
kind = {
SharedLib = function(cfg)
local r = { iif(cfg.system == p.MACOSX, "-dynamiclib", "-shared") }
if cfg.system == "windows" and not cfg.flags.NoImportLib then
table.insert(r, '-Wl,--out-implib="' .. cfg.linktarget.relpath .. '"')
end
return r
end,
WindowedApp = function(cfg)
if cfg.system == p.WINDOWS then return "-mwindows" end
end,
},
}
function gdc.getldflags(cfg)
local flags = config.mapFlags(cfg, gdc.ldflags)
return flags
end
--
-- Return a list of decorated additional libraries directories.
--
gdc.libraryDirectories = {
architecture = {
x86 = "-L/usr/lib",
x86_64 = "-L/usr/lib64",
}
}
function gdc.getLibraryDirectories(cfg)
local flags = config.mapFlags(cfg, gdc.libraryDirectories)
-- Scan the list of linked libraries. If any are referenced with
-- paths, add those to the list of library search paths
for _, dir in ipairs(config.getlinks(cfg, "system", "directory")) do
table.insert(flags, '-Wl,-L' .. project.getrelative(cfg.project, dir))
end
return flags
end
--
-- Return the list of libraries to link, decorated with flags as needed.
--
function gdc.getlinks(cfg, systemonly)
local result = {}
local links
if not systemonly then
links = config.getlinks(cfg, "siblings", "object")
for _, link in ipairs(links) do
-- skip external project references, since I have no way
-- to know the actual output target path
if not link.project.external then
if link.kind == p.STATICLIB then
-- Don't use "-l" flag when linking static libraries; instead use
-- path/libname.a to avoid linking a shared library of the same
-- name if one is present
table.insert(result, "-Wl," .. project.getrelative(cfg.project, link.linktarget.abspath))
else
table.insert(result, "-Wl,-l" .. link.linktarget.basename)
end
end
end
end
-- The "-l" flag is fine for system libraries
links = config.getlinks(cfg, "system", "fullpath")
for _, link in ipairs(links) do
if path.isframework(link) then
table.insert(result, "-framework " .. path.getbasename(link))
elseif path.isobjectfile(link) then
table.insert(result, "-Wl," .. link)
else
table.insert(result, "-Wl,-l" .. path.getbasename(link))
end
end
return result
end
--
-- Returns makefile-specific configuration rules.
--
gdc.makesettings = {
}
function gdc.getmakesettings(cfg)
local settings = config.mapFlags(cfg, gdc.makesettings)
return table.concat(settings)
end
--
-- Retrieves the executable command name for a tool, based on the
-- provided configuration and the operating environment.
--
-- @param cfg
-- The configuration to query.
-- @param tool
-- The tool to fetch, one of "dc" for the D compiler, or "ar" for the static linker.
-- @return
-- The executable command name for a tool, or nil if the system's
-- default value should be used.
--
gdc.tools = {
ps3 = {
dc = "ppu-lv2-gdc",
ar = "ppu-lv2-ar",
},
}
function gdc.gettoolname(cfg, tool)
local names = gdc.tools[cfg.architecture] or gdc.tools[cfg.system] or {}
local name = names[tool]
return name or gdc[tool]
end

View file

@ -0,0 +1,419 @@
--
-- d/tools/ldc.lua
-- Provides LDC-specific configuration strings.
-- Copyright (c) 2013-2015 Andrew Gough, Manu Evans, and the Premake project
--
local p = premake
p.tools.ldc = { }
local ldc = p.tools.ldc
local project = p.project
local config = p.config
local d = p.modules.d
--
-- Set default tools
--
ldc.namestyle = "posix"
--
-- Returns list of D compiler flags for a configuration.
--
ldc.dflags = {
architecture = {
x86 = "-m32",
x86_64 = "-m64",
ARM = "-march=arm",
ARM64 = "-march=aarch64",
-- ppc = "-march=ppc32",
-- ppc64 = "-march=ppc64",
-- spu = "-march=cellspu",
-- mips = "-march=mips", -- -march=mipsel?
},
flags = {
OmitDefaultLibrary = "-mscrtlib=",
CodeCoverage = "-cov",
Color = "-enable-color",
Documentation = "-D",
FatalWarnings = "-w", -- Use LLVM flag? : "-fatal-assembler-warnings",
GenerateHeader = "-H",
GenerateJSON = "-X",
LowMem = "-lowmem",
RetainPaths = "-op",
SymbolsLikeC = "-gc",
UnitTest = "-unittest",
Verbose = "-v",
AllInstantiate = "-allinst",
BetterC = "-betterC",
Main = "-main",
PerformSyntaxCheckOnly = "-o-",
ShowGC = "-vgc",
IgnorePragma = "-ignore",
},
boundscheck = {
Off = "-boundscheck=off",
On = "-boundscheck=on",
SafeOnly = "-boundscheck=safeonly",
},
checkaction = {
D = "-checkaction=D",
C = "-checkaction=C",
Halt = "-checkaction=halt",
Context = "-checkaction=context",
},
cppdialect = {
["C++latest"] = "-extern-std=c++17", -- TODO: keep this up to date >_<
["C++98"] = "-extern-std=c++98",
["C++0x"] = "-extern-std=c++11",
["C++11"] = "-extern-std=c++11",
["C++1y"] = "-extern-std=c++14",
["C++14"] = "-extern-std=c++14",
["C++1z"] = "-extern-std=c++17",
["C++17"] = "-extern-std=c++17",
["C++2a"] = "-extern-std=c++20",
["C++20"] = "-extern-std=c++20",
["gnu++98"] = "-extern-std=c++98",
["gnu++0x"] = "-extern-std=c++11",
["gnu++11"] = "-extern-std=c++11",
["gnu++1y"] = "-extern-std=c++14",
["gnu++14"] = "-extern-std=c++14",
["gnu++1z"] = "-extern-std=c++17",
["gnu++17"] = "-extern-std=c++17",
["gnu++2a"] = "-extern-std=c++20",
["gnu++20"] = "-extern-std=c++20",
},
deprecatedfeatures = {
Allow = "-d",
Warn = "-dw",
Error = "-de",
},
floatingpoint = {
Fast = "-fp-contract=fast -enable-unsafe-fp-math",
-- Strict = "-ffloat-store",
},
optimize = {
Off = "-O0",
On = "-O2",
Debug = "-O0",
Full = "-O3",
Size = "-Oz",
Speed = "-O3",
},
pic = {
On = "-relocation-model=pic",
},
vectorextensions = {
AVX = "-mattr=+avx",
AVX2 = "-mattr=+avx2",
SSE = "-mattr=+sse",
SSE2 = "-mattr=+sse2",
SSE3 = "-mattr=+sse3",
SSSE3 = "-mattr=+ssse3",
["SSE4.1"] = "-mattr=+sse4.1",
["SSE4.2"] = "-mattr=+sse4.2",
},
warnings = {
Default = "-wi",
High = "-wi",
Extra = "-wi", -- TODO: is there a way to get extra warnings?
Everything = "-wi",
},
symbols = {
On = "-g",
FastLink = "-g",
Full = "-g",
}
}
function ldc.getdflags(cfg)
local flags = config.mapFlags(cfg, ldc.dflags)
if config.isDebugBuild(cfg) then
table.insert(flags, "-d-debug")
else
table.insert(flags, "-release")
end
if not cfg.flags.OmitDefaultLibrary then
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
table.insert(flags, "-mscrtlib=libcmt")
elseif staticruntime == true and releaseruntime == false then
table.insert(flags, "-mscrtlib=libcmtd")
elseif staticruntime == false and releaseruntime == true then
table.insert(flags, "-mscrtlib=msvcrt")
elseif staticruntime == false and releaseruntime == false then
table.insert(flags, "-mscrtlib=msvcrtd")
end
end
end
if cfg.flags.Documentation then
if cfg.docname then
table.insert(flags, "-Df=" .. p.quoted(cfg.docname))
end
if cfg.docdir then
table.insert(flags, "-Dd=" .. p.quoted(cfg.docdir))
end
end
if cfg.flags.GenerateHeader then
if cfg.headername then
table.insert(flags, "-Hf=" .. p.quoted(cfg.headername))
end
if cfg.headerdir then
table.insert(flags, "-Hd=" .. p.quoted(cfg.headerdir))
end
end
if #cfg.computetargets > 0 then
table.insert(flags, "-mdcompute-targets=" .. table.concat(cfg.computetargets, ','))
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.transition) do
if isaMap[ext] ~= nil then
table.insert(flags, "-mattr=+" .. isaMap[ext])
end
end
end
if #cfg.preview > 0 then
for _, opt in ipairs(cfg.preview) do
table.insert(flags, "-preview=" .. opt)
end
end
if #cfg.revert > 0 then
for _, opt in ipairs(cfg.revert) do
table.insert(flags, "-revert=" .. opt)
end
end
if #cfg.transition > 0 then
for _, opt in ipairs(cfg.transition) do
table.insert(flags, "-transition=" .. opt)
end
end
return flags
end
--
-- Decorate versions for the DMD command line.
--
function ldc.getversions(versions, level)
local result = {}
for _, version in ipairs(versions) do
table.insert(result, '-d-version=' .. version)
end
if level then
table.insert(result, '-d-version=' .. level)
end
return result
end
--
-- Decorate debug constants for the DMD command line.
--
function ldc.getdebug(constants, level)
local result = {}
for _, constant in ipairs(constants) do
table.insert(result, '-d-debug=' .. constant)
end
if level then
table.insert(result, '-d-debug=' .. level)
end
return result
end
--
-- Decorate import file search paths for the DMD command line.
--
function ldc.getimportdirs(cfg, dirs)
local result = {}
for _, dir in ipairs(dirs) do
dir = project.getrelative(cfg.project, dir)
table.insert(result, '-I=' .. p.quoted(dir))
end
return result
end
--
-- Decorate import file search paths for the DMD command line.
--
function ldc.getstringimportdirs(cfg, dirs)
local result = {}
for _, dir in ipairs(dirs) do
dir = project.getrelative(cfg.project, dir)
table.insert(result, '-J=' .. p.quoted(dir))
end
return result
end
--
-- Returns the target name specific to compiler
--
function ldc.gettarget(name)
return "-of=" .. name
end
--
-- Return a list of LDFLAGS for a specific configuration.
--
ldc.ldflags = {
architecture = {
x86 = { "-m32" },
x86_64 = { "-m64" },
},
kind = {
SharedLib = "-shared",
StaticLib = "-lib",
},
}
function ldc.getldflags(cfg)
local flags = config.mapFlags(cfg, ldc.ldflags)
return flags
end
--
-- Return a list of decorated additional libraries directories.
--
ldc.libraryDirectories = {
architecture = {
x86 = "-L=-L/usr/lib",
x86_64 = "-L=-L/usr/lib64",
}
}
function ldc.getLibraryDirectories(cfg)
local flags = config.mapFlags(cfg, ldc.libraryDirectories)
-- Scan the list of linked libraries. If any are referenced with
-- paths, add those to the list of library search paths
for _, dir in ipairs(config.getlinks(cfg, "system", "directory")) do
table.insert(flags, '-L=-L' .. project.getrelative(cfg.project, dir))
end
return flags
end
--
-- Return the list of libraries to link, decorated with flags as needed.
--
function ldc.getlinks(cfg, systemonly)
local result = {}
local links
if not systemonly then
links = config.getlinks(cfg, "siblings", "object")
for _, link in ipairs(links) do
-- skip external project references, since I have no way
-- to know the actual output target path
if not link.project.external then
if link.kind == p.STATICLIB then
-- Don't use "-l" flag when linking static libraries; instead use
-- path/libname.a to avoid linking a shared library of the same
-- name if one is present
table.insert(result, "-L=" .. project.getrelative(cfg.project, link.linktarget.abspath))
else
table.insert(result, "-L=-l" .. link.linktarget.basename)
end
end
end
end
-- The "-l" flag is fine for system libraries
links = config.getlinks(cfg, "system", "fullpath")
for _, link in ipairs(links) do
if path.isframework(link) then
table.insert(result, "-framework " .. path.getbasename(link))
elseif path.isobjectfile(link) then
table.insert(result, "-L=" .. link)
else
table.insert(result, "-L=-l" .. path.getbasename(link))
end
end
return result
end
--
-- Returns makefile-specific configuration rules.
--
ldc.makesettings = {
}
function ldc.getmakesettings(cfg)
local settings = config.mapFlags(cfg, ldc.makesettings)
return table.concat(settings)
end
--
-- Retrieves the executable command name for a tool, based on the
-- provided configuration and the operating environment.
--
-- @param cfg
-- The configuration to query.
-- @param tool
-- The tool to fetch, one of "dc" for the D compiler, or "ar" for the static linker.
-- @return
-- The executable command name for a tool, or nil if the system's
-- default value should be used.
--
ldc.tools = {
dc = "ldc2",
ar = "ar",
}
function ldc.gettoolname(cfg, tool)
return ldc.tools[tool]
end