Newer
Older
dub_jkp / source / dub / compilers / buildsettings.d
@Remi Thebault Remi Thebault on 18 May 2023 20 KB Fix flags Json serialization
  1. /**
  2. Build settings definitions.
  3.  
  4. Copyright: © 2013-2014 rejectedsoftware e.K.
  5. License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file.
  6. Authors: Sönke Ludwig
  7. */
  8. module dub.compilers.buildsettings;
  9.  
  10. import dub.internal.vibecompat.inet.path;
  11.  
  12. import dub.internal.configy.Attributes;
  13.  
  14. import std.array : array;
  15. import std.algorithm : filter, any;
  16. import std.path : globMatch;
  17. import std.typecons : BitFlags;
  18. import std.algorithm.iteration : uniq;
  19. import std.range : chain;
  20.  
  21. /// BuildPlatform specific settings, like needed libraries or additional
  22. /// include paths.
  23. struct BuildSettings {
  24. import dub.internal.vibecompat.data.serialization : byName;
  25.  
  26. TargetType targetType;
  27. string targetPath;
  28. string targetName;
  29. string workingDirectory;
  30. string mainSourceFile;
  31. string[] dflags;
  32. string[] lflags;
  33. string[] libs;
  34. string[] linkerFiles;
  35. string[] sourceFiles;
  36. string[] injectSourceFiles;
  37. string[] copyFiles;
  38. string[] extraDependencyFiles;
  39. string[] versions;
  40. string[] debugVersions;
  41. string[] versionFilters;
  42. string[] debugVersionFilters;
  43. string[] importPaths;
  44. string[] cImportPaths;
  45. string[] stringImportPaths;
  46. string[] importFiles;
  47. string[] stringImportFiles;
  48. string[] preGenerateCommands;
  49. string[] postGenerateCommands;
  50. string[] preBuildCommands;
  51. string[] postBuildCommands;
  52. string[] preRunCommands;
  53. string[] postRunCommands;
  54. string[string] environments;
  55. string[string] buildEnvironments;
  56. string[string] runEnvironments;
  57. string[string] preGenerateEnvironments;
  58. string[string] postGenerateEnvironments;
  59. string[string] preBuildEnvironments;
  60. string[string] postBuildEnvironments;
  61. string[string] preRunEnvironments;
  62. string[string] postRunEnvironments;
  63. @byName Flags!BuildRequirement requirements;
  64. @byName Flags!BuildOption options;
  65.  
  66. BuildSettings dup()
  67. const {
  68. import std.traits: FieldNameTuple;
  69. import std.algorithm: map;
  70. import std.typecons: tuple;
  71. import std.array: assocArray;
  72. BuildSettings ret;
  73. foreach (m; FieldNameTuple!BuildSettings) {
  74. static if (is(typeof(__traits(getMember, ret, m) = __traits(getMember, this, m).dup)))
  75. __traits(getMember, ret, m) = __traits(getMember, this, m).dup;
  76. else static if (is(typeof(add(__traits(getMember, ret, m), __traits(getMember, this, m)))))
  77. add(__traits(getMember, ret, m), __traits(getMember, this, m));
  78. else static if (is(typeof(__traits(getMember, ret, m) = __traits(getMember, this, m))))
  79. __traits(getMember, ret, m) = __traits(getMember, this, m);
  80. else static assert(0, "Cannot duplicate BuildSettings." ~ m);
  81. }
  82. assert(ret.targetType == targetType);
  83. assert(ret.targetName == targetName);
  84. assert(ret.importPaths == importPaths);
  85. assert(ret.cImportPaths == cImportPaths);
  86. return ret;
  87. }
  88.  
  89. /**
  90. * Merges $(LREF bs) onto `this` BuildSettings instance. This is called for
  91. * sourceLibrary dependencies when they are included in the build to be
  92. * merged into the root package build settings as well as configuring
  93. * targets for different build types such as `release` or `unittest-cov`.
  94. */
  95. void add(in BuildSettings bs)
  96. {
  97. addDFlags(bs.dflags);
  98. addLFlags(bs.lflags);
  99. addLibs(bs.libs);
  100. addLinkerFiles(bs.linkerFiles);
  101. addSourceFiles(bs.sourceFiles);
  102. addInjectSourceFiles(bs.injectSourceFiles);
  103. addCopyFiles(bs.copyFiles);
  104. addExtraDependencyFiles(bs.extraDependencyFiles);
  105. addVersions(bs.versions);
  106. addDebugVersions(bs.debugVersions);
  107. addVersionFilters(bs.versionFilters);
  108. addDebugVersionFilters(bs.debugVersionFilters);
  109. addImportPaths(bs.importPaths);
  110. addCImportPaths(bs.cImportPaths);
  111. addStringImportPaths(bs.stringImportPaths);
  112. addImportFiles(bs.importFiles);
  113. addStringImportFiles(bs.stringImportFiles);
  114. addPreGenerateCommands(bs.preGenerateCommands);
  115. addPostGenerateCommands(bs.postGenerateCommands);
  116. addPreBuildCommands(bs.preBuildCommands);
  117. addPostBuildCommands(bs.postBuildCommands);
  118. addPreRunCommands(bs.preRunCommands);
  119. addPostRunCommands(bs.postRunCommands);
  120. addEnvironments(bs.environments);
  121. addBuildEnvironments(bs.buildEnvironments);
  122. addRunEnvironments(bs.runEnvironments);
  123. addPreGenerateEnvironments(bs.preGenerateEnvironments);
  124. addPostGenerateEnvironments(bs.postGenerateEnvironments);
  125. addPreBuildEnvironments(bs.preBuildEnvironments);
  126. addPostBuildEnvironments(bs.postBuildEnvironments);
  127. addPreRunEnvironments(bs.preRunEnvironments);
  128. addPostRunEnvironments(bs.postRunEnvironments);
  129. addRequirements(bs.requirements);
  130. addOptions(bs.options);
  131. }
  132.  
  133. void addDFlags(in string[] value...) { dflags = chain(dflags, value.dup).uniq.array; }
  134. void prependDFlags(in string[] value...) { prepend(dflags, value); }
  135. void removeDFlags(in string[] value...) { remove(dflags, value); }
  136. void addLFlags(in string[] value...) { lflags ~= value; }
  137. void prependLFlags(in string[] value...) { prepend(lflags, value, false); }
  138. void addLibs(in string[] value...) { add(libs, value); }
  139. void addLinkerFiles(in string[] value...) { add(linkerFiles, value); }
  140. void addSourceFiles(in string[] value...) { add(sourceFiles, value); }
  141. void prependSourceFiles(in string[] value...) { prepend(sourceFiles, value); }
  142. void removeSourceFiles(in string[] value...) { removePaths(sourceFiles, value); }
  143. void addInjectSourceFiles(in string[] value...) { add(injectSourceFiles, value); }
  144. void addCopyFiles(in string[] value...) { add(copyFiles, value); }
  145. void addExtraDependencyFiles(in string[] value...) { add(extraDependencyFiles, value); }
  146. void addVersions(in string[] value...) { add(versions, value); }
  147. void addDebugVersions(in string[] value...) { add(debugVersions, value); }
  148. void addVersionFilters(in string[] value...) { add(versionFilters, value); }
  149. void addDebugVersionFilters(in string[] value...) { add(debugVersionFilters, value); }
  150. void addImportPaths(in string[] value...) { add(importPaths, value); }
  151. void addCImportPaths(in string[] value...) { add(cImportPaths, value); }
  152. void addStringImportPaths(in string[] value...) { add(stringImportPaths, value); }
  153. void prependStringImportPaths(in string[] value...) { prepend(stringImportPaths, value); }
  154. void addImportFiles(in string[] value...) { add(importFiles, value); }
  155. void addStringImportFiles(in string[] value...) { addSI(stringImportFiles, value); }
  156. void addPreGenerateCommands(in string[] value...) { add(preGenerateCommands, value, false); }
  157. void addPostGenerateCommands(in string[] value...) { add(postGenerateCommands, value, false); }
  158. void addPreBuildCommands(in string[] value...) { add(preBuildCommands, value, false); }
  159. void addPostBuildCommands(in string[] value...) { add(postBuildCommands, value, false); }
  160. void addPreRunCommands(in string[] value...) { add(preRunCommands, value, false); }
  161. void addPostRunCommands(in string[] value...) { add(postRunCommands, value, false); }
  162. void addEnvironments(in string[string] value) { add(environments, value); }
  163. void updateEnvironments(in string[string] value) { update(environments, value); }
  164. void addBuildEnvironments(in string[string] value) { add(buildEnvironments, value); }
  165. void updateBuildEnvironments(in string[string] value) { update(buildEnvironments, value); }
  166. void addRunEnvironments(in string[string] value) { add(runEnvironments, value); }
  167. void updateRunEnvironments(in string[string] value) { update(runEnvironments, value); }
  168. void addPreGenerateEnvironments(in string[string] value) { add(preGenerateEnvironments, value); }
  169. void updatePreGenerateEnvironments(in string[string] value) { update(preGenerateEnvironments, value); }
  170. void addPostGenerateEnvironments(in string[string] value) { add(postGenerateEnvironments, value); }
  171. void updatePostGenerateEnvironments(in string[string] value) { update(postGenerateEnvironments, value); }
  172. void addPreBuildEnvironments(in string[string] value) { add(preBuildEnvironments, value); }
  173. void updatePreBuildEnvironments(in string[string] value) { update(preBuildEnvironments, value); }
  174. void addPostBuildEnvironments(in string[string] value) { add(postBuildEnvironments, value); }
  175. void updatePostBuildEnvironments(in string[string] value) { update(postBuildEnvironments, value); }
  176. void addPreRunEnvironments(in string[string] value) { add(preRunEnvironments, value); }
  177. void updatePreRunEnvironments(in string[string] value) { update(preRunEnvironments, value); }
  178. void addPostRunEnvironments(in string[string] value) { add(postRunEnvironments, value); }
  179. void updatePostRunEnvironments(in string[string] value) { update(postRunEnvironments, value); }
  180. void addRequirements(in BuildRequirement[] value...) { foreach (v; value) this.requirements |= v; }
  181. void addRequirements(in Flags!BuildRequirement value) { this.requirements |= value; }
  182. void addOptions(in BuildOption[] value...) { foreach (v; value) this.options |= v; }
  183. void addOptions(in Flags!BuildOption value) { this.options |= value; }
  184. void removeOptions(in BuildOption[] value...) { foreach (v; value) this.options &= ~v; }
  185. void removeOptions(in Flags!BuildOption value) { this.options &= ~value; }
  186.  
  187. private:
  188. static auto filterDuplicates(T)(ref string[] arr, in T vals, bool noDuplicates = true)
  189. {
  190. return noDuplicates
  191. ? vals.filter!(filtered => !arr.any!(item => item == filtered)).array
  192. : vals;
  193. }
  194.  
  195. // Append `vals` to `arr` without adding duplicates.
  196. static void add(ref string[] arr, in string[] vals, bool noDuplicates = true)
  197. {
  198. // vals might contain duplicates, add each val individually
  199. foreach (val; vals)
  200. arr ~= filterDuplicates(arr, [val], noDuplicates);
  201. }
  202. // Append `vals` to `aa`
  203. static void add(ref string[string] aa, in string[string] vals)
  204. {
  205. // vals might contain duplicated keys, add each val individually
  206. foreach (key, val; vals)
  207. if (key !in aa)
  208. aa[key] = val;
  209. }
  210. // Update `vals` to `aa`
  211. static void update(ref string[string] aa, in string[string] vals)
  212. {
  213. // If there are duplicate keys, they will be ignored and overwritten.
  214. foreach (key, val; vals)
  215. aa[key] = val;
  216. }
  217.  
  218. unittest
  219. {
  220. auto ary = ["-dip1000", "-vgc"];
  221. BuildSettings.add(ary, ["-dip1000", "-vgc"]);
  222. assert(ary == ["-dip1000", "-vgc"]);
  223. BuildSettings.add(ary, ["-dip1001", "-vgc"], false);
  224. assert(ary == ["-dip1000", "-vgc", "-dip1001", "-vgc"]);
  225. BuildSettings.add(ary, ["-dupflag", "-notdupflag", "-dupflag"]);
  226. assert(ary == ["-dip1000", "-vgc", "-dip1001", "-vgc", "-dupflag", "-notdupflag"]);
  227. }
  228.  
  229. // Prepend `arr` by `vals` without adding duplicates.
  230. static void prepend(ref string[] arr, in string[] vals, bool noDuplicates = true)
  231. {
  232. import std.range : retro;
  233. // vals might contain duplicates, add each val individually
  234. foreach (val; vals.retro)
  235. arr = filterDuplicates(arr, [val], noDuplicates) ~ arr;
  236. }
  237.  
  238. unittest
  239. {
  240. auto ary = ["-dip1000", "-vgc"];
  241. BuildSettings.prepend(ary, ["-dip1000", "-vgc"]);
  242. assert(ary == ["-dip1000", "-vgc"]);
  243. BuildSettings.prepend(ary, ["-dip1001", "-vgc"], false);
  244. assert(ary == ["-dip1001", "-vgc", "-dip1000", "-vgc"]);
  245. BuildSettings.prepend(ary, ["-dupflag", "-notdupflag", "-dupflag"]);
  246. assert(ary == ["-notdupflag", "-dupflag", "-dip1001", "-vgc", "-dip1000", "-vgc"]);
  247. }
  248.  
  249. // add string import files (avoids file name duplicates in addition to path duplicates)
  250. static void addSI(ref string[] arr, in string[] vals)
  251. {
  252. bool[string] existing;
  253. foreach (v; arr) existing[NativePath(v).head.name] = true;
  254. foreach (v; vals) {
  255. auto s = NativePath(v).head.name;
  256. if (s !in existing) {
  257. existing[s] = true;
  258. arr ~= v;
  259. }
  260. }
  261. }
  262.  
  263. unittest
  264. {
  265. auto ary = ["path/foo.txt"];
  266. BuildSettings.addSI(ary, ["path2/foo2.txt"]);
  267. assert(ary == ["path/foo.txt", "path2/foo2.txt"]);
  268. BuildSettings.addSI(ary, ["path2/foo.txt"]); // no duplicate basenames
  269. assert(ary == ["path/foo.txt", "path2/foo2.txt"]);
  270. }
  271.  
  272. static bool pathMatch(string path, string pattern)
  273. {
  274. import std.functional : memoize;
  275.  
  276. alias nativePath = memoize!((string stringPath) => NativePath(stringPath));
  277.  
  278. return nativePath(path) == nativePath(pattern) || globMatch(path, pattern);
  279. }
  280.  
  281. static void removeValuesFromArray(alias Match)(ref string[] arr, in string[] vals)
  282. {
  283. bool matches(string s)
  284. {
  285. return vals.any!(item => Match(s, item));
  286. }
  287. arr = arr.filter!(s => !matches(s)).array;
  288. }
  289.  
  290. static void removePaths(ref string[] arr, in string[] vals)
  291. {
  292. removeValuesFromArray!(pathMatch)(arr, vals);
  293. }
  294.  
  295. unittest
  296. {
  297. auto ary = ["path1", "root/path1", "root/path2", "root2/path1"];
  298. BuildSettings.removePaths(ary, ["path1"]);
  299. assert(ary == ["root/path1", "root/path2", "root2/path1"]);
  300. BuildSettings.removePaths(ary, ["*/path1"]);
  301. assert(ary == ["root/path2"]);
  302. BuildSettings.removePaths(ary, ["foo", "bar", "root/path2"]);
  303. assert(ary == []);
  304. }
  305.  
  306. static void remove(ref string[] arr, in string[] vals)
  307. {
  308. removeValuesFromArray!((a, b) => a == b)(arr, vals);
  309. }
  310.  
  311. unittest
  312. {
  313. import std.string : join;
  314.  
  315. auto ary = ["path1", "root/path1", "root/path2", "root2/path1"];
  316. BuildSettings.remove(ary, ["path1"]);
  317. assert(ary == ["root/path1", "root/path2", "root2/path1"]);
  318. BuildSettings.remove(ary, ["root/path*"]);
  319. assert(ary == ["root/path1", "root/path2", "root2/path1"]);
  320. BuildSettings.removePaths(ary, ["foo", "root/path2", "bar", "root2/path1"]);
  321. assert(ary == ["root/path1"]);
  322. BuildSettings.remove(ary, ["root/path1", "foo"]);
  323. assert(ary == []);
  324. }
  325. }
  326.  
  327. enum BuildSetting {
  328. dflags = 1<<0,
  329. lflags = 1<<1,
  330. libs = 1<<2,
  331. sourceFiles = 1<<3,
  332. copyFiles = 1<<4,
  333. versions = 1<<5,
  334. debugVersions = 1<<6,
  335. importPaths = 1<<7,
  336. cImportPaths = 1<<8,
  337. stringImportPaths = 1<<9,
  338. options = 1<<10,
  339. none = 0,
  340. commandLine = dflags|copyFiles,
  341. commandLineSeparate = commandLine|lflags,
  342. all = dflags|lflags|libs|sourceFiles|copyFiles|versions|debugVersions|importPaths|cImportPaths|stringImportPaths|options,
  343. noOptions = all & ~options
  344. }
  345.  
  346. enum TargetType {
  347. autodetect,
  348. none,
  349. executable,
  350. library,
  351. sourceLibrary,
  352. dynamicLibrary,
  353. staticLibrary,
  354. object
  355. }
  356.  
  357. enum BuildRequirement {
  358. none = 0, /// No special requirements
  359. allowWarnings = 1<<0, /// Warnings do not abort compilation
  360. silenceWarnings = 1<<1, /// Don't show warnings
  361. disallowDeprecations = 1<<2, /// Using deprecated features aborts compilation
  362. silenceDeprecations = 1<<3, /// Don't show deprecation warnings
  363. disallowInlining = 1<<4, /// Avoid function inlining, even in release builds
  364. disallowOptimization = 1<<5, /// Avoid optimizations, even in release builds
  365. requireBoundsCheck = 1<<6, /// Always perform bounds checks
  366. requireContracts = 1<<7, /// Leave assertions and contracts enabled in release builds
  367. relaxProperties = 1<<8, /// DEPRECATED: Do not enforce strict property handling (-property)
  368. noDefaultFlags = 1<<9, /// Do not issue any of the default build flags (e.g. -debug, -w, -property etc.) - use only for development purposes
  369. }
  370.  
  371. enum BuildOption {
  372. none = 0, /// Use compiler defaults
  373. debugMode = 1<<0, /// Compile in debug mode (enables contracts, -debug)
  374. releaseMode = 1<<1, /// Compile in release mode (disables assertions and bounds checks, -release)
  375. coverage = 1<<2, /// Enable code coverage analysis (-cov)
  376. debugInfo = 1<<3, /// Enable symbolic debug information (-g)
  377. debugInfoC = 1<<4, /// Enable symbolic debug information in C compatible form (-gc)
  378. alwaysStackFrame = 1<<5, /// Always generate a stack frame (-gs)
  379. stackStomping = 1<<6, /// Perform stack stomping (-gx)
  380. inline = 1<<7, /// Perform function inlining (-inline)
  381. noBoundsCheck = 1<<8, /// Disable all bounds checking (-noboundscheck)
  382. optimize = 1<<9, /// Enable optimizations (-O)
  383. profile = 1<<10, /// Emit profiling code (-profile)
  384. unittests = 1<<11, /// Compile unit tests (-unittest)
  385. verbose = 1<<12, /// Verbose compiler output (-v)
  386. ignoreUnknownPragmas = 1<<13, /// Ignores unknown pragmas during compilation (-ignore)
  387. syntaxOnly = 1<<14, /// Don't generate object files (-o-)
  388. warnings = 1<<15, /// Enable warnings (-wi)
  389. warningsAsErrors = 1<<16, /// Treat warnings as errors (-w)
  390. ignoreDeprecations = 1<<17, /// Do not warn about using deprecated features (-d)
  391. deprecationWarnings = 1<<18, /// Warn about using deprecated features (-dw)
  392. deprecationErrors = 1<<19, /// Stop compilation upon usage of deprecated features (-de)
  393. property = 1<<20, /// DEPRECATED: Enforce property syntax (-property)
  394. profileGC = 1<<21, /// Profile runtime allocations
  395. pic = 1<<22, /// Generate position independent code
  396. betterC = 1<<23, /// Compile in betterC mode (-betterC)
  397. lowmem = 1<<24, /// Compile in low-memory mode (-lowmem)
  398. coverageCTFE = 1<<25, /// Enable code coverage analysis including at compile-time (-cov=ctfe)
  399. color = 1<<26, /// Colorize output (-color)
  400.  
  401. // for internal usage
  402. _docs = 1<<27, // Write ddoc to docs
  403. _ddox = 1<<28, // Compile docs.json
  404. }
  405.  
  406. struct Flags (T) {
  407. import dub.internal.vibecompat.data.serialization : ignore;
  408. import dub.internal.vibecompat.data.json : Json;
  409.  
  410. @ignore BitFlags!T values;
  411.  
  412. public this(T opt) @safe pure nothrow @nogc
  413. {
  414. this.values = opt;
  415. }
  416.  
  417. public this(BitFlags!T v) @safe pure nothrow @nogc
  418. {
  419. this.values = v;
  420. }
  421.  
  422. alias values this;
  423.  
  424. public Json toJson() const
  425. {
  426. import std.conv : to;
  427. import std.traits : EnumMembers;
  428.  
  429. auto json = Json.emptyArray;
  430.  
  431. static foreach (em; EnumMembers!T) {
  432. static if (em != 0) {
  433. if (values & em) {
  434. json ~= em.to!string;
  435. }
  436. }
  437. }
  438.  
  439. return json;
  440. }
  441.  
  442. public static Flags!T fromJson(Json json)
  443. {
  444. import std.conv : to;
  445. import std.exception : enforce;
  446.  
  447. BitFlags!T flags;
  448.  
  449. enforce(json.type == Json.Type.array, "Should be an array");
  450. foreach (jval; json) {
  451. flags |= jval.get!string.to!T;
  452. }
  453.  
  454. return Flags!T(flags);
  455. }
  456.  
  457. /**
  458. * Reads a list of flags from a JSON/YAML document and converts them
  459. * to our internal representation.
  460. *
  461. * Flags inside of dub code are stored as a `BitFlags`,
  462. * but they are specified in the recipe using an array of their name.
  463. * This routine handles the conversion from `string[]` to `BitFlags!T`.
  464. */
  465. public static Flags!T fromYAML (scope ConfigParser!(Flags!T) p)
  466. {
  467. import dub.internal.dyaml.node;
  468. import std.exception;
  469. import std.conv;
  470.  
  471. enforce(p.node.nodeID == NodeID.sequence, "Should be a sequence");
  472. typeof(return) res;
  473. foreach (str; p.node.sequence)
  474. res |= str.as!string.to!T;
  475. return res;
  476. }
  477. }
  478.  
  479. unittest
  480. {
  481. import dub.internal.vibecompat.data.json;
  482.  
  483. auto opts = Flags!BuildOption(BuildOption.debugMode | BuildOption.debugInfo | BuildOption.warningsAsErrors);
  484. const str = serializeToJsonString(opts);
  485. assert(str == `["debugMode","debugInfo","warningsAsErrors"]`);
  486. assert(deserializeJson!(typeof(opts))(str) == opts);
  487. }
  488.  
  489. unittest
  490. {
  491. import dub.internal.configy.Read;
  492.  
  493. static struct Config
  494. {
  495. Flags!BuildRequirement flags;
  496. }
  497.  
  498. auto c = parseConfigString!Config(`
  499. {
  500. "flags": [ "allowWarnings", "noDefaultFlags", "disallowInlining" ]
  501. }
  502. `, __FILE__);
  503. assert(c.flags.allowWarnings);
  504. c.flags.allowWarnings = false;
  505. assert(c.flags.noDefaultFlags);
  506. c.flags.noDefaultFlags = false;
  507. assert(c.flags.disallowInlining);
  508. c.flags.disallowInlining = false;
  509. assert(c.flags == c.flags.init);
  510. }
  511.  
  512. /**
  513. All build options that will be inherited upwards in the dependency graph
  514.  
  515. Build options in this category fulfill one of the following properties:
  516. $(UL
  517. $(LI The option affects the semantics of the generated code)
  518. $(LI The option affects if a certain piece of code is valid or not)
  519. $(LI The option enabled meta information in dependent projects that are useful for the dependee (e.g. debug information))
  520. )
  521. */
  522. enum Flags!BuildOption inheritedBuildOptions =
  523. BuildOption.debugMode | BuildOption.releaseMode
  524. | BuildOption.coverage | BuildOption.coverageCTFE | BuildOption.debugInfo | BuildOption.debugInfoC
  525. | BuildOption.alwaysStackFrame | BuildOption.stackStomping | BuildOption.inline
  526. | BuildOption.noBoundsCheck | BuildOption.profile | BuildOption.ignoreUnknownPragmas
  527. | BuildOption.syntaxOnly | BuildOption.warnings | BuildOption.warningsAsErrors
  528. | BuildOption.ignoreDeprecations | BuildOption.deprecationWarnings
  529. | BuildOption.deprecationErrors | BuildOption.property | BuildOption.profileGC
  530. | BuildOption.pic;
  531.  
  532. deprecated("Use `Flags!BuildOption` instead")
  533. public alias BuildOptions = Flags!BuildOption;
  534.  
  535. deprecated("Use `Flags!BuildRequirement` instead")
  536. public alias BuildRequirements = Flags!BuildRequirement;