menv.ck 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812
  1. /*++
  2. Copyright (c) 2017 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. env.ck
  9. Abstract:
  10. This build module contains the environment and functions used throughout
  11. the Minoca OS build.
  12. Author:
  13. Evan Green 1-Feb-2017
  14. Environment:
  15. Build
  16. --*/
  17. //
  18. // -------------------------------------------------------------------- Imports
  19. //
  20. from mingen import config;
  21. from os import getenv, basename;
  22. //
  23. // -------------------------------------------------------------------- Globals
  24. //
  25. var mconfig;
  26. //
  27. // ------------------------------------------------------------------ Functions
  28. //
  29. function
  30. initListFromEnvironment (
  31. name,
  32. default
  33. )
  34. /*++
  35. Routine Description:
  36. This routine gets an environment variable. It either returns that
  37. environment variable wrapped in a list, or the given default.
  38. Arguments:
  39. name - Supplies the name of the environment variable.
  40. default - Supplies the default value to return if not set.
  41. Return Value:
  42. Returns eithe the provided default or has the contents of the environment
  43. variable wrapped in a list.
  44. --*/
  45. {
  46. var value = getenv(name);
  47. if (value != null) {
  48. return [value];
  49. }
  50. return default;
  51. }
  52. function
  53. getTools (
  54. )
  55. /*++
  56. Routine Description:
  57. This routine is called as part of setupEnv, at the end. It returns the
  58. basic set of tools used by the environment.
  59. Arguments:
  60. None.
  61. Return Value:
  62. Returns a list of the basic tools used in the environment.
  63. --*/
  64. {
  65. var buildCflagsLine = "$BUILD_BASE_CPPFLAGS $CPPFLAGS " +
  66. "$BUILD_BASE_CFLAGS $CFLAGS -MMD -MF $OUT.d ";
  67. var buildAsflagsLine = buildCflagsLine +
  68. "$BUILD_BASE_ASFLAGS $ASFLAGS ";
  69. var buildLdflagsLine = "$BUILD_BASE_LDFLAGS $LDFLAGS ";
  70. var cflagsLine = "$BASE_CPPFLAGS $CPPFLAGS $BASE_CFLAGS $CFLAGS "
  71. "-MMD -MF $OUT.d ";
  72. var asflagsLine = cflagsLine + "$BASE_ASFLAGS $ASFLAGS ";
  73. var entries;
  74. var ldflagsLine = "-Wl,-Map=$OUT.map $BASE_LDFLAGS $LDFLAGS ";
  75. var symlinkCommand = "ln -sf $SYMLINK_IN $OUT";
  76. var buildLdLine = "$BUILD_CC " + buildLdflagsLine +
  77. "-o $OUT $IN -Bdynamic $DYNLIBS";
  78. var tools;
  79. if (mconfig.build_os == "Windows") {
  80. symlinkCommand = "cp $IN $OUT";
  81. }
  82. //
  83. // On Mac OS there shouldn't be a -Bdynamic flag to indicate the start of
  84. // the dynamic libraries section.
  85. //
  86. if (mconfig.build_os == "Darwin") {
  87. buildLdLine = "$BUILD_CC " + buildLdflagsLine +
  88. "-o $OUT $IN $DYNLIBS";
  89. //
  90. // Create a .map file (except on Mac, which doesn't support it).
  91. //
  92. } else {
  93. buildLdflagsLine = "-Wl,-Map=$OUT.map " + buildLdflagsLine;
  94. }
  95. //
  96. // Define the tools used.
  97. //
  98. tools = [
  99. //
  100. // C compiler for target binaries.
  101. //
  102. {
  103. "type": "tool",
  104. "name": "cc",
  105. "command": "$CC " + cflagsLine + "-c -o $OUT $IN",
  106. "description": "Compiling - $IN",
  107. "depsformat": "gcc",
  108. "depfile": "$OUT.d"
  109. },
  110. //
  111. // C++ compiler for target binaries.
  112. //
  113. {
  114. "type": "tool",
  115. "name": "cxx",
  116. "command": "$CXX " + cflagsLine + "-c -o $OUT $IN",
  117. "description": "Compiling - $IN",
  118. "depsformat": "gcc",
  119. "depfile": "$OUT.d"
  120. },
  121. //
  122. // Linker for target binaries.
  123. //
  124. {
  125. "type": "tool",
  126. "name": "ld",
  127. "command": "$CC " + ldflagsLine + "-o $OUT $IN -Bdynamic $DYNLIBS",
  128. "description": "Linking - $OUT",
  129. },
  130. //
  131. // Static archiver for target binaries.
  132. //
  133. {
  134. "type": "tool",
  135. "name": "ar",
  136. "command": "$AR rcs $OUT $IN",
  137. "description": "Building Library - $OUT",
  138. },
  139. //
  140. // Assembler for target binaries.
  141. //
  142. {
  143. "type": "tool",
  144. "name": "as",
  145. "command": "$CC " + asflagsLine + "-c -o $OUT $IN",
  146. "description": "Assembling - $IN",
  147. "depsformat": "gcc",
  148. "depfile": "$OUT.d"
  149. },
  150. //
  151. // Objcopy for target binaries.
  152. //
  153. {
  154. "type": "tool",
  155. "name": "objcopy",
  156. "command": "$SHELL -c \"cd `dirname $IN` && "
  157. "$OBJCOPY $OBJCOPY_FLAGS `basename $IN` $OUT\"",
  158. "description": "Objectifying - $IN"
  159. },
  160. //
  161. // Strip for target binaries.
  162. //
  163. {
  164. "type": "tool",
  165. "name": "strip",
  166. "command": "$STRIP $STRIP_FLAGS -o $OUT $IN",
  167. "description": "Stripping - $OUT",
  168. },
  169. //
  170. // C compiler for the build machine.
  171. //
  172. {
  173. "type": "tool",
  174. "name": "build_cc",
  175. "command": "$BUILD_CC " + buildCflagsLine + "-c -o $OUT $IN",
  176. "description": "Compiling - $IN",
  177. "depsformat": "gcc",
  178. "depfile": "$OUT.d"
  179. },
  180. //
  181. // C++ compiler for the build machine.
  182. //
  183. {
  184. "type": "tool",
  185. "name": "build_cxx",
  186. "command": "$BUILD_CXX " + buildCflagsLine + "-c -o $OUT $IN",
  187. "description": "Compiling - $IN",
  188. "depsformat": "gcc",
  189. "depfile": "$OUT.d"
  190. },
  191. //
  192. // Linker for the build machine.
  193. //
  194. {
  195. "type": "tool",
  196. "name": "build_ld",
  197. "command": "$BUILD_CC " + buildLdflagsLine +
  198. "-o $OUT $IN -Bdynamic $DYNLIBS",
  199. "description": "Linking - $OUT",
  200. },
  201. //
  202. // Static archiver for the build machine.
  203. //
  204. {
  205. "type": "tool",
  206. "name": "build_ar",
  207. "command": "$BUILD_AR rcs $OUT $IN",
  208. "description": "Building Library - $OUT",
  209. },
  210. //
  211. // Assembler for the build machine.
  212. //
  213. {
  214. "type": "tool",
  215. "name": "build_as",
  216. "command": "$BUILD_CC " + buildAsflagsLine + "-c -o $OUT $IN",
  217. "description": "Assembling - $IN",
  218. "depsformat": "gcc",
  219. "depfile": "$OUT.d"
  220. },
  221. //
  222. // Strip for the build machine.
  223. //
  224. {
  225. "type": "tool",
  226. "name": "build_strip",
  227. "command": "$BUILD_STRIP $STRIP_FLAGS -o $OUT $IN",
  228. "description": "Stripping - $OUT",
  229. },
  230. //
  231. // Windows resource compiler for the build machine.
  232. //
  233. {
  234. "type": "tool",
  235. "name": "build_rcc",
  236. "command": "$RCC -o $OUT $IN",
  237. "description": "Compiling Resource - $IN",
  238. },
  239. //
  240. // ACPI assembler used to build firmware images.
  241. //
  242. {
  243. "type": "tool",
  244. "name": "iasl",
  245. "command": "$SHELL -c \"$IASL $IASL_FLAGS -p $OUT $IN > $OUT.stdout\"",
  246. "description": "Compiling ASL - $IN"
  247. },
  248. //
  249. // Copy files from one location to another.
  250. //
  251. {
  252. "type": "tool",
  253. "name": "copy",
  254. "command": "$SHELL -c \"cp $CPFLAGS $IN $OUT && [ -z $CHMOD_FLAGS ] || "
  255. "chmod $CHMOD_FLAGS $OUT\"",
  256. "description": "Copying - $IN -> $OUT"
  257. },
  258. //
  259. // Create symbolic links (or just copy on Windows).
  260. //
  261. {
  262. "type": "tool",
  263. "name": "symlink",
  264. "command": symlinkCommand,
  265. "description": "Symlinking - $OUT"
  266. },
  267. //
  268. // Touch a file with the date.
  269. //
  270. {
  271. "type": "tool",
  272. "name": "stamp",
  273. "command": "$SHELL -c \"date > $OUT\"",
  274. "description": "Stamp - $OUT"
  275. },
  276. //
  277. // Touch to create a timestamped empty file.
  278. //
  279. {
  280. "type": "tool",
  281. "name": "touch",
  282. "command": "touch $OUT",
  283. "description": "Touch - $OUT"
  284. },
  285. //
  286. // Create a directory.
  287. //
  288. {
  289. "type": "tool",
  290. "name": "mkdir",
  291. "command": "mkdir -p $OUT",
  292. "description": "mkdir $OUT"
  293. },
  294. //
  295. // Generate a version.h.
  296. //
  297. {
  298. "type": "tool",
  299. "name": "gen_version",
  300. "command": "$SHELL $S/tasks/build/print_version.sh $OUT $FORM "
  301. "$MAJOR $MINOR $REVISION $RELEASE $SERIAL $BUILD_STRING",
  302. "description": "Versioning - $OUT"
  303. }];
  304. return tools;
  305. }
  306. function
  307. setupEnv (
  308. )
  309. /*++
  310. Routine Description:
  311. This routine is called once to set up the build environment.
  312. Arguments:
  313. None.
  314. Return Value:
  315. Returns the basic set of tools used by the environment.
  316. --*/
  317. {
  318. var archVariant;
  319. //
  320. // Prefer Ninja files.
  321. //
  322. config.format ?= "ninja";
  323. //
  324. // Set up the Minoca config dictionary.
  325. //
  326. mconfig = {};
  327. mconfig.build_os = config.build_os;
  328. mconfig.build_machine = config.build_machine;
  329. mconfig.build_variant = "";
  330. if (mconfig.build_machine == "i686") {
  331. mconfig.build_arch = "x86";
  332. } else if (mconfig.build_machine == "i586") {
  333. mconfig.build_arch = "x86";
  334. mconfig.build_variant = "q";
  335. } else if ((mconfig.build_machine == "armv7") ||
  336. (mconfig.build_machine == "armv6")) {
  337. mconfig.build_arch = mconfig.build_machine;
  338. } else if (mconfig.build_machine == "x86_64") {
  339. mconfig.build_arch = "x64";
  340. }
  341. mconfig.arch = getenv("ARCH");
  342. mconfig.arch ?= mconfig.build_arch;
  343. mconfig.arch ?= "x86";
  344. mconfig.debug = getenv("DEBUG");
  345. mconfig.debug ?= "dbg";
  346. mconfig.variant = getenv("VARIANT");
  347. mconfig.variant ?= mconfig.build_variant;
  348. mconfig.release_level = "SystemReleaseDevelopment";
  349. mconfig.cflags = initListFromEnvironment("CFLAGS",
  350. ["-O2", "-Wall", "-Werror"]);
  351. mconfig.cppflags = initListFromEnvironment("CPPFLAGS", []);
  352. mconfig.ldflags = initListFromEnvironment("LDFLAGS", []);
  353. mconfig.asflags = initListFromEnvironment("ASFLAGS", []);
  354. mconfig.stripflags = initListFromEnvironment("STRIP_FLAGS", []);
  355. mconfig.build_cc = getenv("BUILD_CC");
  356. mconfig.build_cc ?= "gcc";
  357. mconfig.build_ar = getenv("BUILD_AR");
  358. mconfig.build_ar ?= "ar";
  359. mconfig.build_strip = getenv("BUILD_STRIP");
  360. mconfig.build_strip ?= "strip";
  361. config.output ?= "$S/../" + mconfig.arch + mconfig.variant + mconfig.debug +
  362. "/obj/os";
  363. mconfig.outroot = "$O/../..";
  364. mconfig.binroot = mconfig.outroot + "/bin";
  365. mconfig.stripped = mconfig.binroot + "/stripped";
  366. mconfig.cc = getenv("CC");
  367. mconfig.ar = getenv("AR");
  368. mconfig.objcopy = getenv("OBJCOPY");
  369. mconfig.strip = getenv("STRIP");
  370. mconfig.rcc = getenv("RCC");
  371. mconfig.rcc ?= "windres";
  372. mconfig.iasl = getenv("IASL");
  373. mconfig.iasl ?= "iasl";
  374. mconfig.shell = getenv("SHELL");
  375. mconfig.shell ?= "sh";
  376. mconfig.target = null;
  377. //
  378. // Add in the command line variables, then define the derived variables.
  379. //
  380. for (key in config.cmdvars) {
  381. mconfig[key] = config.cmdvars[key];
  382. }
  383. archVariant = mconfig.arch + mconfig.variant;
  384. if (!mconfig.target) {
  385. if (archVariant == "x86") {
  386. mconfig.target = "i686-pc-minoca";
  387. } else if (archVariant == "x86q") {
  388. mconfig.target = "i586-pc-minoca";
  389. } else if ((mconfig.arch == "armv7") || (mconfig.arch == "armv6")) {
  390. mconfig.target = "arm-none-minoca";
  391. } else if (mconfig.arch == "x64") {
  392. mconfig.target = "x86_64-none-minoca";
  393. } else {
  394. Core.raise(ValueError("Unknown architecture" + mconfig.arch));
  395. }
  396. }
  397. mconfig.native = false;
  398. if ((mconfig.build_os == "Minoca") &&
  399. (mconfig.arch == mconfig.build_arch)) {
  400. mconfig.native = true;
  401. }
  402. if (mconfig.native) {
  403. mconfig.cc ?= mconfig.build_cc;
  404. mconfig.ar ?= mconfig.build_ar;
  405. mconfig.strip ?= mconfig.build_strip;
  406. mconfig.objcopy ?= "objcopy";
  407. } else {
  408. mconfig.cc ?= mconfig.target + "-gcc";
  409. mconfig.ar ?= mconfig.target + "-ar";
  410. mconfig.strip ?= mconfig.target + "-strip";
  411. mconfig.objcopy ?= mconfig.target + "-objcopy";
  412. }
  413. if (mconfig.debug == "dbg") {
  414. mconfig.cflags += ["-DDEBUG=1"];
  415. } else {
  416. mconfig.cflags += ["-Wno-unused-but-set-variable", "-DNDEBUG"];
  417. }
  418. mconfig.cflags += ["-fno-builtin",
  419. "-g",
  420. "-save-temps=obj",
  421. "-ffunction-sections",
  422. "-fdata-sections",
  423. "-fvisibility=hidden"];
  424. mconfig.cppflags += ["-I$S/include"];
  425. mconfig.build_cflags = [] + mconfig.cflags;
  426. mconfig.build_cppflags = [] + mconfig.cppflags;
  427. mconfig.cflags += ["-fpic"];
  428. //
  429. // Windows cannot handle -fpic, but everyone else can.
  430. //
  431. if (mconfig.build_os == "Windows") {
  432. mconfig.build_cflags += ["-mno-ms-bitfields"];
  433. } else {
  434. mconfig.build_cflags += ["-fpic"];
  435. }
  436. if (mconfig.build_os == "Darwin") {
  437. mconfig.build_cflags += ["-Wno-tautological-compare",
  438. "-Wno-parentheses-equality"];
  439. }
  440. //
  441. // Add some architecture variant flags.
  442. //
  443. if (archVariant == "x86q") {
  444. mconfig.cppflags += ["-Wa,-momit-lock-prefix=yes", "-march=i586"];
  445. } else if (archVariant == "armv6") {
  446. mconfig.cflags += ["-march=armv6zk", "-marm", "-mfpu=vfp"];
  447. }
  448. mconfig.build_asflags = [];
  449. mconfig.asflags += ["-Wa,-g"];
  450. mconfig.build_ldflags = initListFromEnvironment("BUILD_LDFLAGS",
  451. [] + mconfig.ldflags);
  452. mconfig.ldflags += ["-Wl,--gc-sections"];
  453. //
  454. // Mac OS cannot handle --gc-sections or strip -p.
  455. //
  456. if (mconfig.build_os != "Darwin") {
  457. mconfig.build_ldflags += ["-Wl,--gc-sections"];
  458. mconfig.stripflags += ["-p"];
  459. }
  460. //
  461. // Define the set of variables that get passed all the way through to the
  462. // final Make/ninja file. Passing these on as variables rather than
  463. // substituting during the mingen build process allows for a smaller
  464. // build file, and easier manual tweaking by the user.
  465. //
  466. config.vars = {
  467. "BUILD_CC": mconfig.build_cc,
  468. "BUILD_AR": mconfig.build_ar,
  469. "BUILD_STRIP": mconfig.build_strip,
  470. "CC": mconfig.cc,
  471. "AR": mconfig.ar,
  472. "STRIP": mconfig.strip,
  473. "OBJCOPY": mconfig.objcopy,
  474. "RCC": mconfig.rcc,
  475. "IASL": mconfig.iasl,
  476. "SHELL": mconfig.shell,
  477. "BASE_CFLAGS": mconfig.cflags,
  478. "BASE_CPPFLAGS": mconfig.cppflags,
  479. "BASE_LDFLAGS": mconfig.ldflags,
  480. "BASE_ASFLAGS": mconfig.asflags,
  481. "BUILD_BASE_CFLAGS": mconfig.build_cflags,
  482. "BUILD_BASE_CPPFLAGS": mconfig.build_cppflags,
  483. "BUILD_BASE_LDFLAGS": mconfig.build_ldflags,
  484. "BUILD_BASE_ASFLAGS": mconfig.build_asflags,
  485. "STRIP_FLAGS": mconfig.stripflags,
  486. "IASL_FLAGS": ["-we"]
  487. };
  488. if (config.verbose) {
  489. Core.print("Minoca Build Configuration:");
  490. for (key in mconfig) {
  491. Core.print("\t%s: %s" % [key, mconfig[key].__str()]);
  492. }
  493. }
  494. return getTools();
  495. }
  496. function
  497. addConfig (
  498. entry,
  499. name,
  500. value
  501. )
  502. /*++
  503. Routine Description:
  504. This routine adds a configure option to a list, ensuring that both the
  505. config dictionary and option already exist.
  506. Arguments:
  507. entry - Supplies the entry to add the configure option to.
  508. name - Supplies the name of the option to add.
  509. value - Supplies the new value to add to the list of options.
  510. Return Value:
  511. None.
  512. --*/
  513. {
  514. if (!entry.get("config")) {
  515. entry.config = {};
  516. }
  517. if (!entry.config.get(name)) {
  518. entry.config[name] = [];
  519. }
  520. entry.config[name] += [value];
  521. return;
  522. }
  523. function
  524. group (
  525. name,
  526. entries
  527. )
  528. /*++
  529. Routine Description:
  530. This routine creates a phony target that groups a bunch of different
  531. targets together under a common name.
  532. Arguments:
  533. name - Supplies the name of the new group target.
  534. entries - Supplies the list of entries.
  535. Return Value:
  536. Returns a list containing the entry for the group target.
  537. --*/
  538. {
  539. var entry = {
  540. "label": name,
  541. "type": "target",
  542. "tool": "phony",
  543. "inputs": entries,
  544. "config": {}
  545. };
  546. return [entry];
  547. }
  548. function
  549. touch (
  550. destination,
  551. destinationLabel,
  552. mode
  553. )
  554. /*++
  555. Routine Description:
  556. This routine creates an empty file target.
  557. Arguments:
  558. destination - Supplies the copy destination.
  559. destinationLabel - Supplies a label naming the target.
  560. mode - Supplies the chmod mode of the destination.
  561. Return Value:
  562. Returns a list containing the copy entry.
  563. --*/
  564. {
  565. var config = {};
  566. if (mode) {
  567. config["CHMOD_FLAGS"] = mode;
  568. }
  569. destinationLabel ?= destination;
  570. var entry = {
  571. "type": "target",
  572. "tool": "touch",
  573. "label": destinationLabel,
  574. "output": destination,
  575. "config": config
  576. };
  577. return [entry];
  578. }
  579. function
  580. makedir (
  581. destination,
  582. destinationLabel
  583. )
  584. /*++
  585. Routine Description:
  586. This routine creates an empty directory target.
  587. Arguments:
  588. destination - Supplies the copy destination.
  589. destinationLabel - Supplies a label naming the target.
  590. Return Value:
  591. Returns a list containing the copy entry.
  592. --*/
  593. {
  594. destinationLabel ?= destination;
  595. var entry = {
  596. "type": "target",
  597. "tool": "mkdir",
  598. "label": destinationLabel,
  599. "output": destination,
  600. };
  601. return [entry];
  602. }
  603. function
  604. copy (
  605. source,
  606. destination,
  607. destinationLabel,
  608. flags,
  609. mode
  610. )
  611. /*++
  612. Routine Description:
  613. This routine creates a target that copies a file from one place to another.
  614. Arguments:
  615. source - Supplies the source to copy.
  616. destination - Supplies the copy destination.
  617. destinationLabel - Supplies a label naming the copy target.
  618. flags - Supplies the flags to include in the copy.
  619. mode - Supplies the chmod mode of the destination.
  620. Return Value:
  621. Returns a list containing the copy entry.
  622. --*/
  623. {
  624. var config = {};
  625. if (flags) {
  626. config["CPFLAGS"] = flags;
  627. }
  628. if (mode) {
  629. config["CHMOD_FLAGS"] = mode;
  630. }
  631. var entry = {
  632. "type": "target",
  633. "tool": "copy",
  634. "label": destinationLabel,
  635. "inputs": [source],
  636. "output": destination,
  637. "config": config
  638. };
  639. if (!destinationLabel) {
  640. entry["label"] = destination;
  641. }
  642. return [entry];
  643. }
  644. function
  645. strip (
  646. params
  647. )
  648. /*++
  649. Routine Description:
  650. This routine converts an entry to a strip entry, where the target will be
  651. stripped.
  652. Arguments:
  653. params - Supplies the existing entry.
  654. Return Value:
  655. Returns a list containing the strip entry.
  656. --*/
  657. {
  658. params.type = "target";
  659. params.tool = "strip";
  660. if (params.get("build")) {
  661. params.tool = "build_strip";
  662. }
  663. return [params];
  664. }
  665. function
  666. binplace (
  667. params
  668. )
  669. /*++
  670. Routine Description:
  671. This routine replaces the current target with a copied version in the
  672. final bin directory. This will also create a stripped version in the
  673. stripped directory unless told not to.
  674. Arguments:
  675. params - Supplies the existing entry.
  676. Return Value:
  677. Returns a list containing the strip entry.
  678. --*/
  679. {
  680. var build = params.get("build");
  681. var copiedEntry;
  682. var cpflags = params.get("cpflags");;
  683. var destination;
  684. var entries;
  685. var fileName;
  686. var label = params.get("label");
  687. var mode = params.get("mode");
  688. var newOriginalLabel;
  689. var originalTarget;
  690. var source = params.get("output");
  691. var StrippedEntry;
  692. var strippedOutput;
  693. label ?= source;
  694. source ?= label;
  695. if ((!label) || (!source)) {
  696. Core.raise(ValueError("Label or output must be defined"));
  697. }
  698. //
  699. // Set the output since the label is going to be renamed and create the
  700. // copy target.
  701. //
  702. params.output = source;
  703. params.type = "target";
  704. fileName = basename(source);
  705. destination = params.get("binplace");
  706. if (!destination) {
  707. destination = "bin";
  708. }
  709. destination = mconfig.outroot + "/" + destination + "/" + fileName;
  710. newOriginalLabel = label + "_orig";
  711. originalTarget = ":" + newOriginalLabel;
  712. copiedEntry = copy(originalTarget, destination, label, cpflags, mode)[0];
  713. //
  714. // The original label was given to the copied destination, so tack a _orig
  715. // on the source label.
  716. //
  717. params.label = newOriginalLabel;
  718. entries = [copiedEntry, params];
  719. //
  720. // Unless asked not to, create a stripped entry as well.
  721. //
  722. if (!params.get("nostrip")) {
  723. if (build) {
  724. strippedOutput = mconfig.stripped + "/build/" + fileName;
  725. } else {
  726. strippedOutput = mconfig.stripped + "/" + fileName;
  727. }
  728. StrippedEntry = {
  729. "label": label + "_stripped",
  730. "inputs": [originalTarget],
  731. "output": strippedOutput,
  732. "build": build,
  733. };
  734. //
  735. // Make the binplaced copy depend on the stripped version.
  736. //
  737. copiedEntry.implicit = [":" + StrippedEntry["label"]];
  738. entries += strip(StrippedEntry);
  739. }
  740. return entries;
  741. }
  742. function
  743. compiledSources (
  744. params
  745. )
  746. /*++
  747. Routine Description:
  748. This routine compiles a group of object file targets from source files.
  749. Arguments:
  750. params - Supplies the entry with inputs filled out.
  751. Return Value:
  752. Returns the list containing a list of object names, and a list of object
  753. targets.
  754. --*/
  755. {
  756. var build = params.get("build");
  757. var entries = [];
  758. var ext;
  759. var includes = params.get("includes");
  760. var inputParts;
  761. var inputs = params.inputs;
  762. var objName;
  763. var obj;
  764. var objs = [];
  765. var sourcesConfig = params.get("sources_config");
  766. var prefix = params.get("prefix");
  767. var suffix;
  768. var tool;
  769. if (includes) {
  770. sourcesConfig ?= {};
  771. if (!sourcesConfig.get("CPPFLAGS")) {
  772. sourcesConfig.CPPFLAGS = [];
  773. }
  774. for (include in includes) {
  775. sourcesConfig["CPPFLAGS"] += ["-I" + include];
  776. }
  777. }
  778. if (inputs.length() == 0) {
  779. Core.raise(ValueError("Compilation must have inputs"));
  780. }
  781. for (input in inputs) {
  782. inputParts = input.rsplit(".", 1);
  783. try {
  784. ext = inputParts[1];
  785. } except IndexError {
  786. ext = "";
  787. }
  788. suffix = ".o";
  789. if (ext == "c") {
  790. tool = "cc";
  791. } else if (ext == "cc") {
  792. tool = "cxx";
  793. } else if (ext == "S") {
  794. tool = "as";
  795. } else if (ext == "rc") {
  796. tool = "rcc";
  797. suffix = ".rsc";
  798. } else {
  799. objs += [input];
  800. continue;
  801. }
  802. if (build) {
  803. tool = "build_" + tool;
  804. }
  805. objName = inputParts[0] + suffix;
  806. if (objName[0] == ":") {
  807. objName = objName[1...-1];
  808. }
  809. if (prefix) {
  810. objName = prefix + "/" + objName;
  811. }
  812. obj = {
  813. "type": "target",
  814. "label": objName,
  815. "output": objName,
  816. "inputs": [input],
  817. "tool": tool,
  818. "config": sourcesConfig,
  819. };
  820. entries += [obj];
  821. objs += [":" + objName];
  822. }
  823. if (prefix) {
  824. if (!params.get("output")) {
  825. params.output = params.label;
  826. }
  827. params.output = prefix + "/" + params.output;
  828. }
  829. return [objs, entries];
  830. }
  831. function
  832. executable (
  833. params
  834. )
  835. /*++
  836. Routine Description:
  837. This routine links a set of sources into some sort of executable or shared
  838. object.
  839. Arguments:
  840. params - Supplies the entry with inputs filled out.
  841. Return Value:
  842. Returns the list of the linked entry.
  843. --*/
  844. {
  845. var build = params.get("build");
  846. var entry = params.get("entry");
  847. var compilation = compiledSources(params);
  848. var linkerScript = params.get("linker_script");
  849. var objs = compilation[0];
  850. var entries = compilation[1];
  851. var textAddress = params.get("text_address");;
  852. params.type = "target";
  853. params.inputs = objs;
  854. params.tool = "ld";
  855. if (build) {
  856. params.tool = "build_ld";
  857. }
  858. //
  859. // Convert options for text_address, linker_script, and entry to actual
  860. // LDFLAGS.
  861. //
  862. if (textAddress) {
  863. addConfig(params, "LDFLAGS", "-Wl,-Ttext-segment=" + textAddress);
  864. addConfig(params, "LDFLAGS", "-Wl,-Ttext=" + textAddress);
  865. }
  866. if (linkerScript) {
  867. addConfig(params, "LDFLAGS", "-Wl,-T" + linkerScript);
  868. }
  869. if (entry != null) {
  870. addConfig(params, "LDFLAGS", "-Wl,-e" + entry);
  871. addConfig(params, "LDFLAGS", "-Wl,-u" + entry);
  872. }
  873. if (params.get("binplace")) {
  874. entries += binplace(params);
  875. } else {
  876. entries += [params];
  877. }
  878. return entries;
  879. }
  880. function
  881. application (
  882. params
  883. )
  884. /*++
  885. Routine Description:
  886. This routine creates a position independent application.
  887. Arguments:
  888. params - Supplies the entry with inputs filled out.
  889. Return Value:
  890. Returns the list of the application entry.
  891. --*/
  892. {
  893. var build = params.get("build");
  894. var exename = params.get("output");
  895. exename ?= params.get("label");
  896. if (!exename) {
  897. Core.raise(ValueError("Missing output or label"));
  898. }
  899. if (build && (mconfig.build_os == "Windows")) {
  900. params.output = exename + ".exe";
  901. }
  902. if (build && (mconfig.build_os == "Darwin")) {
  903. addConfig(params, "LDFLAGS", "-Wl,-pie");
  904. } else {
  905. addConfig(params, "LDFLAGS", "-pie");
  906. }
  907. if ((!build) && (params.get("binplace") == null)) {
  908. params.binplace = "bin";
  909. }
  910. return executable(params);
  911. }
  912. function
  913. sharedLibrary (
  914. params
  915. )
  916. /*++
  917. Routine Description:
  918. This routine creates a shared library or DLL.
  919. Arguments:
  920. params - Supplies the entry with inputs filled out.
  921. Return Value:
  922. Returns the list of the application entry.
  923. --*/
  924. {
  925. var build = params.get("build");
  926. var majorVersion = params.get("major_version");
  927. var minorVersion = params.get("minor_version");
  928. var soname = params.get("soname");
  929. soname ?= params.get("output");
  930. soname ?= params.get("label");
  931. if (!soname) {
  932. Core.raise(ValueError(
  933. "One of output, label, or soname must be defined."));
  934. }
  935. //
  936. // Darwin shared libraries build with a whole different ballgame of options.
  937. //
  938. if (build && (mconfig.build_os == "Darwin")) {
  939. majorVersion ?= "0";
  940. minorVersion ?= "0";
  941. soname += ".%s.dylib" % majorVersion;
  942. addConfig(params,
  943. "LDFLAGS",
  944. "-undefined dynamic_lookup -dynamiclib");
  945. addConfig(params,
  946. "LDFLAGS",
  947. "-current_version %s.%s" % [majorVersion, minorVersion]);
  948. addConfig(params,
  949. "LDFLAGS",
  950. "-compatibility_version %s.%d" % [majorVersion, 0]);
  951. } else {
  952. addConfig(params, "LDFLAGS", "-shared");
  953. if ((!build) || (mconfig.build_os != "Windows")) {
  954. soname += ".so";
  955. if (majorVersion != null) {
  956. soname += "." + majorVersion;
  957. }
  958. addConfig(params, "LDFLAGS", "-Wl,-soname=" + soname);
  959. } else {
  960. soname += ".dll";
  961. }
  962. }
  963. params.output = soname;
  964. if ((!build) && (params.get("binplace") == null)) {
  965. params.binplace = "bin";
  966. }
  967. return executable(params);
  968. }
  969. function
  970. staticLibrary (
  971. params
  972. )
  973. /*++
  974. Routine Description:
  975. This routine creates a static library.
  976. Arguments:
  977. params - Supplies the entry with inputs filled out.
  978. Return Value:
  979. Returns the list of the application entry.
  980. --*/
  981. {
  982. var build = params.get("build");
  983. var compilation = compiledSources(params);
  984. var objs = compilation[0];
  985. var output;
  986. var entries = compilation[1];
  987. params.type = "target";
  988. output = params.get("output");
  989. output ?= params.get("label");
  990. if (!output) {
  991. Core.raise(ValueError("output or label must be defined"));
  992. }
  993. params.output = output + ".a";
  994. params.inputs = objs;
  995. params.tool = "ar";
  996. if (build) {
  997. params.tool = "build_ar";
  998. }
  999. if (params.get("binplace")) {
  1000. entries += binplace(params);
  1001. } else {
  1002. entries += [params];
  1003. }
  1004. return entries;
  1005. }
  1006. function
  1007. compiledAsl (
  1008. inputs
  1009. )
  1010. /*++
  1011. Routine Description:
  1012. This routine creates a list of compiled .aml files from a list of .asl
  1013. files.
  1014. Arguments:
  1015. params - Supplies the entry with inputs filled out.
  1016. Return Value:
  1017. Returns a list where the first element is a list of all the resulting
  1018. target names, and the second element is a list of the target entries.
  1019. --*/
  1020. {
  1021. var entries = [];
  1022. var ext;
  1023. var inputParts;
  1024. var objName;
  1025. var obj;
  1026. var objs = [];
  1027. if (inputs.length() == 0) {
  1028. Core.raise(ValueError("Compilation must have inputs"));
  1029. }
  1030. for (input in inputs) {
  1031. inputParts = input.rsplit(".", 1);
  1032. ext = inputParts[1];
  1033. objName = inputParts[0] + ".aml";
  1034. obj = {
  1035. "type": "target",
  1036. "label": objName,
  1037. "output": objName,
  1038. "inputs": [input],
  1039. "tool": "iasl"
  1040. };
  1041. entries += [obj];
  1042. objs += [":" + objName];
  1043. }
  1044. return [objs, entries];
  1045. }
  1046. function
  1047. objectifiedBinaries (
  1048. params
  1049. )
  1050. /*++
  1051. Routine Description:
  1052. This routine creates a group of object file targets from binary files.
  1053. Arguments:
  1054. params - Supplies the entry with inputs filled out.
  1055. Return Value:
  1056. Returns a list of object names in the first element and the object file
  1057. target entries in the second element.
  1058. --*/
  1059. {
  1060. var build = params.get("build");
  1061. var entries = [];
  1062. var inputs = params.inputs;
  1063. var obj;
  1064. var objcopyConfig = params.get("config");
  1065. var objName;
  1066. var objs = [];
  1067. var prefix = params.get("prefix");
  1068. var tool;
  1069. if (inputs.length() == 0) {
  1070. Core.raise(ValueError("Compilation must have inputs"));
  1071. }
  1072. for (input in inputs) {
  1073. tool = "objcopy";
  1074. if (build) {
  1075. tool = "build_objcopy";;
  1076. }
  1077. objName = input + ".o";
  1078. if (prefix) {
  1079. objName = prefix + "/" + objName;
  1080. }
  1081. obj = {
  1082. "type": "target",
  1083. "label": objName,
  1084. "output": objName,
  1085. "inputs": [input],
  1086. "tool": tool,
  1087. "config": objcopyConfig,
  1088. };
  1089. entries += [obj];
  1090. objs += [":" + objName];
  1091. }
  1092. if (prefix) {
  1093. params.output ?= params.label;
  1094. params.output = prefix + "/" + params.output;
  1095. }
  1096. return [objs, entries];
  1097. }
  1098. function
  1099. objectifiedBinary (
  1100. params
  1101. )
  1102. /*++
  1103. Routine Description:
  1104. This routine creates a single object file from a binary file.
  1105. Arguments:
  1106. params - Supplies the entry with inputs filled out.
  1107. Return Value:
  1108. Returns a list of the object file.
  1109. --*/
  1110. {
  1111. return objectifiedBinaries(params)[1];
  1112. }
  1113. function
  1114. objectifiedLibrary (
  1115. params
  1116. )
  1117. /*++
  1118. Routine Description:
  1119. This routine creates a library from a set of objectified files.
  1120. Arguments:
  1121. params - Supplies the entry with inputs filled out.
  1122. Return Value:
  1123. Returns a list of the object file.
  1124. --*/
  1125. {
  1126. var build = params.get("build");
  1127. var compilation = objectifiedBinaries(params);
  1128. var objs = compilation[0];
  1129. var entries = compilation[1];
  1130. var output = params.get("output");
  1131. params.type = "target";
  1132. output ?= params.label;
  1133. params.output = output + ".a";
  1134. params.inputs = objs;
  1135. params.tool = "ar";
  1136. if (build) {
  1137. params.tool = "build_ar";
  1138. }
  1139. entries += [params];
  1140. return entries;
  1141. }
  1142. //
  1143. // Create a flat binary from an executable image.
  1144. //
  1145. function
  1146. flattenedBinary (
  1147. params
  1148. )
  1149. /*++
  1150. Routine Description:
  1151. This routine creates a flat binary from an executable image.
  1152. Arguments:
  1153. params - Supplies the entry with inputs filled out.
  1154. Return Value:
  1155. Returns a list of the flat binary.
  1156. --*/
  1157. {
  1158. var entries;
  1159. params.type = "target";
  1160. params.tool = "objcopy";
  1161. addConfig(params, "OBJCOPY_FLAGS", "-O binary");
  1162. if (params.get("binplace")) {
  1163. params.nostrip = true;
  1164. entries = binplace(params);
  1165. } else {
  1166. entries = [params];
  1167. }
  1168. return entries;
  1169. }
  1170. function
  1171. driver (
  1172. params
  1173. )
  1174. /*++
  1175. Routine Description:
  1176. This routine creates a Minoca kernel driver.
  1177. Arguments:
  1178. params - Supplies the entry with inputs filled out.
  1179. Return Value:
  1180. Returns a list of the driver entry.
  1181. --*/
  1182. {
  1183. var soname = params.get("output");
  1184. if (!params.get("entry")) {
  1185. params.entry = "DriverEntry";
  1186. }
  1187. params.binplace = "bin";
  1188. soname ?= params.get("label");
  1189. if (soname != "kernel") {
  1190. soname += ".drv";
  1191. params.output = soname;
  1192. params.inputs += ["kernel:kernel"];
  1193. }
  1194. addConfig(params, "LDFLAGS", "-shared");
  1195. addConfig(params, "LDFLAGS", "-Wl,-soname=" + soname);
  1196. addConfig(params, "LDFLAGS", "-nostdlib");
  1197. return executable(params);
  1198. }
  1199. function
  1200. uefiRuntimeFfs (
  1201. name
  1202. )
  1203. /*++
  1204. Routine Description:
  1205. This routine creates a runtime driver .FFS file from an ELF file.
  1206. Arguments:
  1207. params - Supplies the entry with inputs filled out.
  1208. Return Value:
  1209. Returns a list of the .FFS entry.
  1210. --*/
  1211. {
  1212. var elfconvConfig;
  1213. var ffs;
  1214. var pe;
  1215. elfconvConfig = {
  1216. "ELFCONV_FLAGS": "-t efiruntimedriver"
  1217. };
  1218. pe = {
  1219. "type": "target",
  1220. "label": name,
  1221. "inputs": [":" + name + ".elf"],
  1222. "implicit": ["uefi/tools/elfconv:elfconv"],
  1223. "tool": "elfconv",
  1224. "config": elfconvConfig
  1225. };
  1226. ffs = {
  1227. "type": "target",
  1228. "label": name + ".ffs",
  1229. "inputs": [":" + name],
  1230. "implicit": ["uefi/tools/genffs:genffs"],
  1231. "tool": "genffs_runtime"
  1232. };
  1233. return [pe, ffs];
  1234. }
  1235. function
  1236. uefiFwvol (
  1237. path,
  1238. name,
  1239. ffs
  1240. )
  1241. /*++
  1242. Routine Description:
  1243. This routine creates a UEFI firmware volume object file based on a platform
  1244. name and a list of FFS inputs.
  1245. Arguments:
  1246. path - Supplies the path to the source. The object directory version of
  1247. this path will be added to the include path.
  1248. name - Supplies the name of the firmware volume.
  1249. ffs - Supplies the FFS inputs.
  1250. Return Value:
  1251. Returns a list of the firmware volume entry.
  1252. --*/
  1253. {
  1254. var fwv;
  1255. var fwvO;
  1256. var fwvName = name + "fwv";
  1257. var fwvS;
  1258. fwv = {
  1259. "type": "target",
  1260. "label": fwvName,
  1261. "inputs": ffs,
  1262. "implicit": ["uefi/tools/genfv:genfv"],
  1263. "tool": "genfv"
  1264. };
  1265. fwvS = {
  1266. "inputs": [fwvName + ".S"],
  1267. "includes": ["$O/" + path]
  1268. };
  1269. fwvO = compiledSources(fwvS);
  1270. fwvO = fwvO[1][0];
  1271. fwvO["implicit"] = [":" + fwvName];
  1272. return [fwv, fwvO];
  1273. }
  1274. //
  1275. // Define a function that creates a version.h file target.
  1276. //
  1277. function
  1278. createVersionHeader (
  1279. major,
  1280. minor,
  1281. revision
  1282. )
  1283. /*++
  1284. Routine Description:
  1285. This routine creates a version.h header that includes aspects of the
  1286. build environment.
  1287. Arguments:
  1288. major - Supplies the major number.
  1289. minor - Supplies the minor number.
  1290. revision - Supplies the revision.
  1291. Return Value:
  1292. Returns a list of the firmware volume entry.
  1293. --*/
  1294. {
  1295. var versionConfig;
  1296. var versionH;
  1297. versionConfig = {
  1298. "FORM": "header",
  1299. "MAJOR": major,
  1300. "MINOR": minor,
  1301. "REVISION": revision,
  1302. "RELEASE": mconfig.release_level
  1303. };
  1304. versionH = {
  1305. "type": "target",
  1306. "output": "version.h",
  1307. "inputs": ["$S/.git/HEAD"],
  1308. "tool": "gen_version",
  1309. "config": versionConfig
  1310. };
  1311. return [versionH];
  1312. }