ldc.lua 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. --
  2. -- d/tools/ldc.lua
  3. -- Provides LDC-specific configuration strings.
  4. -- Copyright (c) 2013-2015 Andrew Gough, Manu Evans, and the Premake project
  5. --
  6. local p = premake
  7. p.tools.ldc = { }
  8. local ldc = p.tools.ldc
  9. local project = p.project
  10. local config = p.config
  11. local d = p.modules.d
  12. --
  13. -- Set default tools
  14. --
  15. ldc.namestyle = "posix"
  16. --
  17. -- Returns list of D compiler flags for a configuration.
  18. --
  19. ldc.dflags = {
  20. architecture = {
  21. x86 = "-m32",
  22. x86_64 = "-m64",
  23. ARM = "-march=arm",
  24. ARM64 = "-march=aarch64",
  25. -- ppc = "-march=ppc32",
  26. -- ppc64 = "-march=ppc64",
  27. -- spu = "-march=cellspu",
  28. -- mips = "-march=mips", -- -march=mipsel?
  29. },
  30. flags = {
  31. OmitDefaultLibrary = "-mscrtlib=",
  32. CodeCoverage = "-cov",
  33. Color = "-enable-color",
  34. Documentation = "-D",
  35. FatalWarnings = "-w", -- Use LLVM flag? : "-fatal-assembler-warnings",
  36. GenerateHeader = "-H",
  37. GenerateJSON = "-X",
  38. LowMem = "-lowmem",
  39. RetainPaths = "-op",
  40. SymbolsLikeC = "-gc",
  41. UnitTest = "-unittest",
  42. Verbose = "-v",
  43. AllInstantiate = "-allinst",
  44. BetterC = "-betterC",
  45. Main = "-main",
  46. PerformSyntaxCheckOnly = "-o-",
  47. ShowGC = "-vgc",
  48. IgnorePragma = "-ignore",
  49. },
  50. boundscheck = {
  51. Off = "-boundscheck=off",
  52. On = "-boundscheck=on",
  53. SafeOnly = "-boundscheck=safeonly",
  54. },
  55. checkaction = {
  56. D = "-checkaction=D",
  57. C = "-checkaction=C",
  58. Halt = "-checkaction=halt",
  59. Context = "-checkaction=context",
  60. },
  61. cppdialect = {
  62. ["C++latest"] = "-extern-std=c++17", -- TODO: keep this up to date >_<
  63. ["C++98"] = "-extern-std=c++98",
  64. ["C++0x"] = "-extern-std=c++11",
  65. ["C++11"] = "-extern-std=c++11",
  66. ["C++1y"] = "-extern-std=c++14",
  67. ["C++14"] = "-extern-std=c++14",
  68. ["C++1z"] = "-extern-std=c++17",
  69. ["C++17"] = "-extern-std=c++17",
  70. ["C++2a"] = "-extern-std=c++20",
  71. ["C++20"] = "-extern-std=c++20",
  72. ["gnu++98"] = "-extern-std=c++98",
  73. ["gnu++0x"] = "-extern-std=c++11",
  74. ["gnu++11"] = "-extern-std=c++11",
  75. ["gnu++1y"] = "-extern-std=c++14",
  76. ["gnu++14"] = "-extern-std=c++14",
  77. ["gnu++1z"] = "-extern-std=c++17",
  78. ["gnu++17"] = "-extern-std=c++17",
  79. ["gnu++2a"] = "-extern-std=c++20",
  80. ["gnu++20"] = "-extern-std=c++20",
  81. },
  82. deprecatedfeatures = {
  83. Allow = "-d",
  84. Warn = "-dw",
  85. Error = "-de",
  86. },
  87. floatingpoint = {
  88. Fast = "-fp-contract=fast -enable-unsafe-fp-math",
  89. -- Strict = "-ffloat-store",
  90. },
  91. optimize = {
  92. Off = "-O0",
  93. On = "-O2",
  94. Debug = "-O0",
  95. Full = "-O3",
  96. Size = "-Oz",
  97. Speed = "-O3",
  98. },
  99. pic = {
  100. On = "-relocation-model=pic",
  101. },
  102. vectorextensions = {
  103. AVX = "-mattr=+avx",
  104. AVX2 = "-mattr=+avx2",
  105. SSE = "-mattr=+sse",
  106. SSE2 = "-mattr=+sse2",
  107. SSE3 = "-mattr=+sse3",
  108. SSSE3 = "-mattr=+ssse3",
  109. ["SSE4.1"] = "-mattr=+sse4.1",
  110. ["SSE4.2"] = "-mattr=+sse4.2",
  111. },
  112. warnings = {
  113. Default = "-wi",
  114. High = "-wi",
  115. Extra = "-wi", -- TODO: is there a way to get extra warnings?
  116. Everything = "-wi",
  117. },
  118. symbols = {
  119. On = "-g",
  120. FastLink = "-g",
  121. Full = "-g",
  122. }
  123. }
  124. function ldc.getdflags(cfg)
  125. local flags = config.mapFlags(cfg, ldc.dflags)
  126. if config.isDebugBuild(cfg) then
  127. table.insert(flags, "-d-debug")
  128. else
  129. table.insert(flags, "-release")
  130. end
  131. if not cfg.flags.OmitDefaultLibrary then
  132. local releaseruntime = not config.isDebugBuild(cfg)
  133. local staticruntime = true
  134. if cfg.staticruntime == "Off" then
  135. staticruntime = false
  136. end
  137. if cfg.runtime == "Debug" then
  138. releaseruntime = false
  139. elseif cfg.runtime == "Release" then
  140. releaseruntime = true
  141. end
  142. if (cfg.staticruntime and cfg.staticruntime ~= "Default") or (cfg.runtime and cfg.runtime ~= "Default") then
  143. if staticruntime == true and releaseruntime == true then
  144. table.insert(flags, "-mscrtlib=libcmt")
  145. elseif staticruntime == true and releaseruntime == false then
  146. table.insert(flags, "-mscrtlib=libcmtd")
  147. elseif staticruntime == false and releaseruntime == true then
  148. table.insert(flags, "-mscrtlib=msvcrt")
  149. elseif staticruntime == false and releaseruntime == false then
  150. table.insert(flags, "-mscrtlib=msvcrtd")
  151. end
  152. end
  153. end
  154. if cfg.flags.Documentation then
  155. if cfg.docname then
  156. table.insert(flags, "-Df=" .. p.quoted(cfg.docname))
  157. end
  158. if cfg.docdir then
  159. table.insert(flags, "-Dd=" .. p.quoted(cfg.docdir))
  160. end
  161. end
  162. if cfg.flags.GenerateHeader then
  163. if cfg.headername then
  164. table.insert(flags, "-Hf=" .. p.quoted(cfg.headername))
  165. end
  166. if cfg.headerdir then
  167. table.insert(flags, "-Hd=" .. p.quoted(cfg.headerdir))
  168. end
  169. end
  170. if #cfg.computetargets > 0 then
  171. table.insert(flags, "-mdcompute-targets=" .. table.concat(cfg.computetargets, ','))
  172. end
  173. if #cfg.isaextensions > 0 then
  174. local isaMap = {
  175. MOVBE = "movbe",
  176. POPCNT = "popcnt",
  177. PCLMUL = "pclmul",
  178. LZCNT = "lzcnt",
  179. BMI = "bmi",
  180. BMI2 = "bmi2",
  181. F16C = "f16c",
  182. AES = "aes",
  183. FMA = "fma",
  184. FMA4 = "fma4",
  185. RDRND = "rdrnd",
  186. }
  187. for _, ext in ipairs(cfg.transition) do
  188. if isaMap[ext] ~= nil then
  189. table.insert(flags, "-mattr=+" .. isaMap[ext])
  190. end
  191. end
  192. end
  193. if #cfg.preview > 0 then
  194. for _, opt in ipairs(cfg.preview) do
  195. table.insert(flags, "-preview=" .. opt)
  196. end
  197. end
  198. if #cfg.revert > 0 then
  199. for _, opt in ipairs(cfg.revert) do
  200. table.insert(flags, "-revert=" .. opt)
  201. end
  202. end
  203. if #cfg.transition > 0 then
  204. for _, opt in ipairs(cfg.transition) do
  205. table.insert(flags, "-transition=" .. opt)
  206. end
  207. end
  208. return flags
  209. end
  210. --
  211. -- Decorate versions for the DMD command line.
  212. --
  213. function ldc.getversions(versions, level)
  214. local result = {}
  215. for _, version in ipairs(versions) do
  216. table.insert(result, '-d-version=' .. version)
  217. end
  218. if level then
  219. table.insert(result, '-d-version=' .. level)
  220. end
  221. return result
  222. end
  223. --
  224. -- Decorate debug constants for the DMD command line.
  225. --
  226. function ldc.getdebug(constants, level)
  227. local result = {}
  228. for _, constant in ipairs(constants) do
  229. table.insert(result, '-d-debug=' .. constant)
  230. end
  231. if level then
  232. table.insert(result, '-d-debug=' .. level)
  233. end
  234. return result
  235. end
  236. --
  237. -- Decorate import file search paths for the DMD command line.
  238. --
  239. function ldc.getimportdirs(cfg, dirs)
  240. local result = {}
  241. for _, dir in ipairs(dirs) do
  242. dir = project.getrelative(cfg.project, dir)
  243. table.insert(result, '-I=' .. p.quoted(dir))
  244. end
  245. return result
  246. end
  247. --
  248. -- Decorate import file search paths for the DMD command line.
  249. --
  250. function ldc.getstringimportdirs(cfg, dirs)
  251. local result = {}
  252. for _, dir in ipairs(dirs) do
  253. dir = project.getrelative(cfg.project, dir)
  254. table.insert(result, '-J=' .. p.quoted(dir))
  255. end
  256. return result
  257. end
  258. --
  259. -- Returns the target name specific to compiler
  260. --
  261. function ldc.gettarget(name)
  262. return "-of=" .. name
  263. end
  264. --
  265. -- Return a list of LDFLAGS for a specific configuration.
  266. --
  267. ldc.ldflags = {
  268. architecture = {
  269. x86 = { "-m32" },
  270. x86_64 = { "-m64" },
  271. },
  272. kind = {
  273. SharedLib = "-shared",
  274. StaticLib = "-lib",
  275. },
  276. }
  277. function ldc.getldflags(cfg)
  278. local flags = config.mapFlags(cfg, ldc.ldflags)
  279. return flags
  280. end
  281. --
  282. -- Return a list of decorated additional libraries directories.
  283. --
  284. ldc.libraryDirectories = {
  285. architecture = {
  286. x86 = "-L=-L/usr/lib",
  287. x86_64 = "-L=-L/usr/lib64",
  288. }
  289. }
  290. function ldc.getLibraryDirectories(cfg)
  291. local flags = config.mapFlags(cfg, ldc.libraryDirectories)
  292. -- Scan the list of linked libraries. If any are referenced with
  293. -- paths, add those to the list of library search paths
  294. for _, dir in ipairs(config.getlinks(cfg, "system", "directory")) do
  295. table.insert(flags, '-L=-L' .. project.getrelative(cfg.project, dir))
  296. end
  297. return flags
  298. end
  299. --
  300. -- Return the list of libraries to link, decorated with flags as needed.
  301. --
  302. function ldc.getlinks(cfg, systemonly)
  303. local result = {}
  304. local links
  305. if not systemonly then
  306. links = config.getlinks(cfg, "siblings", "object")
  307. for _, link in ipairs(links) do
  308. -- skip external project references, since I have no way
  309. -- to know the actual output target path
  310. if not link.project.external then
  311. if link.kind == p.STATICLIB then
  312. -- Don't use "-l" flag when linking static libraries; instead use
  313. -- path/libname.a to avoid linking a shared library of the same
  314. -- name if one is present
  315. table.insert(result, "-L=" .. project.getrelative(cfg.project, link.linktarget.abspath))
  316. else
  317. table.insert(result, "-L=-l" .. link.linktarget.basename)
  318. end
  319. end
  320. end
  321. end
  322. -- The "-l" flag is fine for system libraries
  323. links = config.getlinks(cfg, "system", "fullpath")
  324. for _, link in ipairs(links) do
  325. if path.isframework(link) then
  326. table.insert(result, "-framework " .. path.getbasename(link))
  327. elseif path.isobjectfile(link) then
  328. table.insert(result, "-L=" .. link)
  329. else
  330. table.insert(result, "-L=-l" .. path.getbasename(link))
  331. end
  332. end
  333. return result
  334. end
  335. --
  336. -- Returns makefile-specific configuration rules.
  337. --
  338. ldc.makesettings = {
  339. }
  340. function ldc.getmakesettings(cfg)
  341. local settings = config.mapFlags(cfg, ldc.makesettings)
  342. return table.concat(settings)
  343. end
  344. --
  345. -- Retrieves the executable command name for a tool, based on the
  346. -- provided configuration and the operating environment.
  347. --
  348. -- @param cfg
  349. -- The configuration to query.
  350. -- @param tool
  351. -- The tool to fetch, one of "dc" for the D compiler, or "ar" for the static linker.
  352. -- @return
  353. -- The executable command name for a tool, or nil if the system's
  354. -- default value should be used.
  355. --
  356. ldc.tools = {
  357. dc = "ldc2",
  358. ar = "ar",
  359. }
  360. function ldc.gettoolname(cfg, tool)
  361. return ldc.tools[tool]
  362. end