mkfiles.pl 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093
  1. #!/usr/bin/env perl
  2. #
  3. # Cross-platform Makefile generator.
  4. #
  5. # Reads the file `Recipe' to determine the list of generated
  6. # executables and their component objects. Then reads the source
  7. # files to compute #include dependencies. Finally, writes out the
  8. # various target Makefiles.
  9. # PuTTY specifics which could still do with removing:
  10. # - Mac makefile is not portabilised at all. Include directories
  11. # are hardwired, and also the libraries are fixed. This is
  12. # mainly because I was too scared to go anywhere near it.
  13. # - sbcsgen.pl is still run at startup.
  14. #
  15. # FIXME: no attempt made to handle !forceobj in the project files.
  16. use warnings;
  17. use FileHandle;
  18. use File::Basename;
  19. use Cwd;
  20. use Digest::SHA qw(sha512_hex);
  21. if ($#ARGV >= 0 and ($ARGV[0] eq "-u" or $ARGV[0] eq "-U")) {
  22. # Convenience for Unix users: -u means that after we finish what
  23. # we're doing here, we also run mkauto.sh and then 'configure' in
  24. # the Unix subdirectory. So it's a one-stop shop for regenerating
  25. # the actual end-product Unix makefile.
  26. #
  27. # Arguments supplied after -u go to configure.
  28. #
  29. # -U is identical, but runs 'configure' at the _top_ level, for
  30. # people who habitually do that.
  31. $do_unix = ($ARGV[0] eq "-U" ? 2 : 1);
  32. shift @ARGV;
  33. @confargs = @ARGV;
  34. }
  35. open IN, "Recipe" or do {
  36. # We want to deal correctly with being run from one of the
  37. # subdirs in the source tree. So if we can't find Recipe here,
  38. # try one level up.
  39. chdir "..";
  40. open IN, "Recipe" or die "unable to open Recipe file\n";
  41. };
  42. # HACK: One of the source files in `charset' is auto-generated by
  43. # sbcsgen.pl, and licence.h is likewise generated by licence.pl. We
  44. # need to generate those _now_, before attempting dependency analysis.
  45. eval 'chdir "charset"; require "./sbcsgen.pl"; chdir ".."; select STDOUT;';
  46. eval 'require "./licence.pl"; select STDOUT;';
  47. @srcdirs = ("./");
  48. $divert = undef; # ref to scalar in which text is currently being put
  49. $help = ""; # list of newline-free lines of help text
  50. $project_name = "project"; # this is a good enough default
  51. %makefiles = (); # maps makefile types to output makefile pathnames
  52. %makefile_extra = (); # maps makefile types to extra Makefile text
  53. %programs = (); # maps prog name + type letter to listref of objects/resources
  54. %groups = (); # maps group name to listref of objects/resources
  55. while (<IN>) {
  56. chomp;
  57. @_ = split;
  58. # If we're gathering help text, keep doing so.
  59. if (defined $divert) {
  60. if ((defined $_[0]) && $_[0] eq "!end") {
  61. $divert = undef;
  62. } else {
  63. ${$divert} .= "$_\n";
  64. }
  65. next;
  66. }
  67. # Skip comments and blank lines.
  68. next if /^\s*#/ or scalar @_ == 0;
  69. if ($_[0] eq "!begin" and $_[1] eq "help") { $divert = \$help; next; }
  70. if ($_[0] eq "!end") { $divert = undef; next; }
  71. if ($_[0] eq "!name") { $project_name = $_[1]; next; }
  72. if ($_[0] eq "!srcdir") { push @srcdirs, $_[1]; next; }
  73. if ($_[0] eq "!makefile" and &mfval($_[1])) { $makefiles{$_[1]}=$_[2]; next;}
  74. if ($_[0] eq "!specialobj" and &mfval($_[1])) { $specialobj{$_[1]}->{$_[2]} = 1; next;}
  75. if ($_[0] eq "!cflags" and &mfval($_[1])) {
  76. ($rest = $_) =~ s/^\s*\S+\s+\S+\s+\S+\s*//; # find rest of input line
  77. if ($rest eq "") {
  78. # Make sure this file doesn't get lumped together with any
  79. # other file's cflags.
  80. $rest = "F" . $_[2];
  81. } else {
  82. # Give this file a specific set of cflags, but permit it to
  83. # go together with other files using the same set.
  84. $rest = "C" . $rest;
  85. }
  86. $cflags{$_[1]}->{$_[2]} = $rest;
  87. next;
  88. }
  89. if ($_[0] eq "!forceobj") { $forceobj{$_[1]} = 1; next; }
  90. if ($_[0] eq "!begin") {
  91. if ($_[1] =~ /^>(.*)/) {
  92. $divert = \$auxfiles{$1};
  93. } elsif (&mfval($_[1])) {
  94. $sect = $_[2] ? $_[2] : "end";
  95. $divert = \($makefile_extra{$_[1]}->{$sect});
  96. } else {
  97. $dummy = '';
  98. $divert = \$dummy;
  99. }
  100. next;
  101. }
  102. # If we're gathering help/verbatim text, keep doing so.
  103. if (defined $divert) { ${$divert} .= "$_\n"; next; }
  104. # Ignore blank lines.
  105. next if scalar @_ == 0;
  106. # Now we have an ordinary line. See if it's an = line, a : line
  107. # or a + line.
  108. @objs = @_;
  109. if ($_[0] eq "+") {
  110. $listref = $lastlistref;
  111. $prog = undef;
  112. die "$.: unexpected + line\n" if !defined $lastlistref;
  113. } elsif ($#_ >= 1 && $_[1] eq "=") {
  114. $groups{$_[0]} = [] if !defined $groups{$_[0]};
  115. $listref = $groups{$_[0]};
  116. $prog = undef;
  117. shift @objs; # eat the group name
  118. } elsif ($#_ >= 1 && $_[1] eq ":") {
  119. $listref = [];
  120. $prog = $_[0];
  121. shift @objs; # eat the program name
  122. } else {
  123. die "$.: unrecognised line type\n";
  124. }
  125. shift @objs; # eat the +, the = or the :
  126. while (scalar @objs > 0) {
  127. $i = shift @objs;
  128. if ($groups{$i}) {
  129. foreach $j (@{$groups{$i}}) { unshift @objs, $j; }
  130. } elsif (($i =~ /^\[([A-Z]*)\]$/) and defined $prog) {
  131. $type = substr($i,1,(length $i)-2);
  132. die "unrecognised program type for $prog [$type]\n"
  133. if ! grep { $type eq $_ } qw(G C X U MX XT UT);
  134. } else {
  135. push @$listref, $i;
  136. }
  137. }
  138. if ($prog and $type) {
  139. die "multiple program entries for $prog [$type]\n"
  140. if defined $programs{$prog . "," . $type};
  141. $programs{$prog . "," . $type} = $listref;
  142. }
  143. $lastlistref = $listref;
  144. }
  145. close IN;
  146. foreach $aux (sort keys %auxfiles) {
  147. open AUX, ">$aux";
  148. print AUX $auxfiles{$aux};
  149. close AUX;
  150. }
  151. # Now retrieve the complete list of objects and resource files, and
  152. # construct dependency data for them. While we're here, expand the
  153. # object list for each program, and complain if its type isn't set.
  154. @prognames = sort keys %programs;
  155. %depends = ();
  156. @scanlist = ();
  157. foreach $i (@prognames) {
  158. ($prog, $type) = split ",", $i;
  159. # Strip duplicate object names.
  160. $prev = '';
  161. @list = grep { $status = ($prev ne $_); $prev=$_; $status }
  162. sort @{$programs{$i}};
  163. $programs{$i} = [@list];
  164. foreach $j (@list) {
  165. # Dependencies for "x" start with "x.c" or "x.m" (depending on
  166. # which one exists).
  167. # Dependencies for "x.res" start with "x.rc".
  168. # Dependencies for "x.rsrc" start with "x.r".
  169. # Both types of file are pushed on the list of files to scan.
  170. # Libraries (.lib) don't have dependencies at all.
  171. if ($j =~ /^(.*)\.res$/) {
  172. $file = "$1.rc";
  173. $depends{$j} = [$file];
  174. push @scanlist, $file;
  175. } elsif ($j =~ /^(.*)\.rsrc$/) {
  176. $file = "$1.r";
  177. $depends{$j} = [$file];
  178. push @scanlist, $file;
  179. } elsif ($j !~ /\./) {
  180. $file = "$j.c";
  181. $file = "$j.m" unless &findfile($file);
  182. $depends{$j} = [$file];
  183. push @scanlist, $file;
  184. }
  185. }
  186. }
  187. # Scan each file on @scanlist and find further inclusions.
  188. # Inclusions are given by lines of the form `#include "otherfile"'
  189. # (system headers are automatically ignored by this because they'll
  190. # be given in angle brackets). Files included by this method are
  191. # added back on to @scanlist to be scanned in turn (if not already
  192. # done).
  193. #
  194. # Resource scripts (.rc) can also include a file by means of:
  195. # - a line # ending `ICON "filename"';
  196. # - a line ending `RT_MANIFEST "filename"'.
  197. # Files included by this method are not added to @scanlist because
  198. # they can never include further files.
  199. #
  200. # In this pass we write out a hash %further which maps a source
  201. # file name into a listref containing further source file names.
  202. %further = ();
  203. %allsourcefiles = (); # this is wanted by some makefiles
  204. while (scalar @scanlist > 0) {
  205. $file = shift @scanlist;
  206. next if defined $further{$file}; # skip if we've already done it
  207. $further{$file} = [];
  208. $dirfile = &findfile($file);
  209. $allsourcefiles{$dirfile} = 1;
  210. open IN, "$dirfile" or die "unable to open source file $file\n";
  211. while (<IN>) {
  212. chomp;
  213. /^\s*#include\s+\"([^\"]+)\"/ and do {
  214. push @{$further{$file}}, $1;
  215. push @scanlist, $1;
  216. next;
  217. };
  218. /(RT_MANIFEST|ICON)\s+\"([^\"]+)\"\s*$/ and do {
  219. push @{$further{$file}}, $2;
  220. next;
  221. }
  222. }
  223. close IN;
  224. }
  225. # Now we're ready to generate the final dependencies section. For
  226. # each key in %depends, we must expand the dependencies list by
  227. # iteratively adding entries from %further.
  228. foreach $i (keys %depends) {
  229. %dep = ();
  230. @scanlist = @{$depends{$i}};
  231. foreach $i (@scanlist) { $dep{$i} = 1; }
  232. while (scalar @scanlist > 0) {
  233. $file = shift @scanlist;
  234. foreach $j (@{$further{$file}}) {
  235. if (!$dep{$j}) {
  236. $dep{$j} = 1;
  237. push @{$depends{$i}}, $j;
  238. push @scanlist, $j;
  239. }
  240. }
  241. }
  242. # printf "%s: %s\n", $i, join ' ',@{$depends{$i}};
  243. }
  244. # Validation of input.
  245. sub mfval($) {
  246. my ($type) = @_;
  247. # Returns true if the argument is a known makefile type. Otherwise,
  248. # prints a warning and returns false;
  249. if (grep { $type eq $_ }
  250. ("vc","vcproj","cygwin","lcc","devcppproj","gtk","unix",
  251. "am","osx","vstudio10","vstudio12","clangcl")) {
  252. return 1;
  253. }
  254. warn "$.:unknown makefile type '$type'\n";
  255. return 0;
  256. }
  257. # Utility routines while writing out the Makefiles.
  258. sub def {
  259. my ($x) = shift @_;
  260. return (defined $x) ? $x : "";
  261. }
  262. sub dirpfx {
  263. my ($path) = shift @_;
  264. my ($sep) = shift @_;
  265. my $ret = "";
  266. my $i;
  267. while (($i = index $path, $sep) >= 0 ||
  268. ($j = index $path, "/") >= 0) {
  269. if ($i >= 0 and ($j < 0 or $i < $j)) {
  270. $path = substr $path, ($i + length $sep);
  271. } else {
  272. $path = substr $path, ($j + 1);
  273. }
  274. $ret .= "..$sep";
  275. }
  276. return $ret;
  277. }
  278. sub findfile {
  279. my ($name) = @_;
  280. my $dir = '';
  281. my $i;
  282. my $outdir = undef;
  283. unless (defined $findfilecache{$name}) {
  284. $i = 0;
  285. foreach $dir (@srcdirs) {
  286. if (-f "$dir$name") {
  287. $outdir = $dir;
  288. $i++;
  289. $outdir =~ s/^\.\///;
  290. }
  291. }
  292. die "multiple instances of source file $name\n" if $i > 1;
  293. $findfilecache{$name} = (defined $outdir ? $outdir . $name : undef);
  294. }
  295. return $findfilecache{$name};
  296. }
  297. sub objects {
  298. my ($prog, $otmpl, $rtmpl, $ltmpl, $prefix, $dirsep) = @_;
  299. my @ret;
  300. my ($i, $x, $y);
  301. ($otmpl, $rtmpl, $ltmpl) = map { defined $_ ? $_ : "" } ($otmpl, $rtmpl, $ltmpl);
  302. @ret = ();
  303. foreach $i (@{$programs{$prog}}) {
  304. $x = "";
  305. if ($i =~ /^(.*)\.(res|rsrc)/) {
  306. $y = $1;
  307. ($x = $rtmpl) =~ s/X/$y/;
  308. } elsif ($i =~ /^(.*)\.lib/) {
  309. $y = $1;
  310. ($x = $ltmpl) =~ s/X/$y/;
  311. } elsif ($i !~ /\./) {
  312. ($x = $otmpl) =~ s/X/$i/;
  313. }
  314. push @ret, $x if $x ne "";
  315. }
  316. return join " ", @ret;
  317. }
  318. sub special {
  319. my ($prog, $suffix) = @_;
  320. my @ret;
  321. my ($i, $x, $y);
  322. ($otmpl, $rtmpl, $ltmpl) = map { defined $_ ? $_ : "" } ($otmpl, $rtmpl, $ltmpl);
  323. @ret = ();
  324. foreach $i (@{$programs{$prog}}) {
  325. if (substr($i, (length $i) - (length $suffix)) eq $suffix) {
  326. push @ret, $i;
  327. }
  328. }
  329. return (scalar @ret) ? (join " ", @ret) : undef;
  330. }
  331. sub splitline {
  332. my ($line, $width, $splitchar) = @_;
  333. my $result = "";
  334. my $len;
  335. $len = (defined $width ? $width : 76);
  336. $splitchar = (defined $splitchar ? $splitchar : '\\');
  337. while (length $line > $len) {
  338. $line =~ /^(.{0,$len})\s(.*)$/ or $line =~ /^(.{$len,})?\s(.*)$/;
  339. $result .= $1;
  340. $result .= " ${splitchar}\n\t\t" if $2 ne '';
  341. $line = $2;
  342. $len = 60;
  343. }
  344. return $result . $line;
  345. }
  346. sub deps {
  347. my ($otmpl, $rtmpl, $prefix, $dirsep, $mftyp, $depchar, $splitchar) = @_;
  348. my ($i, $x, $y);
  349. my @deps;
  350. my @ret;
  351. @ret = ();
  352. $depchar ||= ':';
  353. foreach $i (sort keys %depends) {
  354. next if $specialobj{$mftyp}->{$i};
  355. if ($i =~ /^(.*)\.(res|rsrc)/) {
  356. next if !defined $rtmpl;
  357. $y = $1;
  358. ($x = $rtmpl) =~ s/X/$y/;
  359. } else {
  360. ($x = $otmpl) =~ s/X/$i/;
  361. }
  362. @deps = @{$depends{$i}};
  363. @deps = map {
  364. $_ = &findfile($_);
  365. s/\//$dirsep/g;
  366. $_ = $prefix . $_;
  367. } @deps;
  368. push @ret, {obj => $x, obj_orig => $i, deps => [@deps]};
  369. }
  370. return @ret;
  371. }
  372. sub prognames {
  373. my ($types) = @_;
  374. my ($n, $prog, $type);
  375. my @ret;
  376. @ret = ();
  377. foreach $n (@prognames) {
  378. ($prog, $type) = split ",", $n;
  379. push @ret, $n if index(":$types:", ":$type:") >= 0;
  380. }
  381. return @ret;
  382. }
  383. sub progrealnames {
  384. my ($types) = @_;
  385. my ($n, $prog, $type);
  386. my @ret;
  387. @ret = ();
  388. foreach $n (@prognames) {
  389. ($prog, $type) = split ",", $n;
  390. push @ret, $prog if index(":$types:", ":$type:") >= 0;
  391. }
  392. return @ret;
  393. }
  394. sub manpages {
  395. my ($types,$suffix) = @_;
  396. # assume that all UNIX programs have a man page
  397. if($suffix eq "1" && $types =~ /:X:/) {
  398. return map("$_.1", &progrealnames($types));
  399. }
  400. return ();
  401. }
  402. $orig_dir = cwd;
  403. # Now we're ready to output the actual Makefiles.
  404. if (defined $makefiles{'clangcl'}) {
  405. $dirpfx = &dirpfx($makefiles{'clangcl'}, "/");
  406. ##-- Makefile for cross-compiling using clang-cl, lld-link, and
  407. ## MinGW's windres for resource compilation.
  408. #
  409. # This makefile allows a complete Linux-based cross-compile, but
  410. # using the real Visual Studio header files and libraries. In
  411. # order to run it, you will need:
  412. #
  413. # - clang-cl, llvm-rc and lld-link on your PATH.
  414. # * I built these from the up-to-date LLVM project trunk git
  415. # repositories, as of 2018-05-29.
  416. # - case-mashed copies of the Visual Studio include directories.
  417. # * On a real VS installation, run vcvars32.bat and look at
  418. # the resulting value of %INCLUDE%. Take a full copy of each
  419. # of those directories, and inside the copy, for each
  420. # include file that has an uppercase letter in its name,
  421. # make a lowercased symlink to it. Additionally, one of the
  422. # directories will contain files called driverspecs.h and
  423. # specstrings.h, and those will need symlinks called
  424. # DriverSpecs.h and SpecStrings.h.
  425. # * Now, on Linux, define the environment variable INCLUDE to
  426. # be a list, separated by *semicolons* (in the Windows
  427. # style), of those directories, but before all of them you
  428. # must also include lib/clang/5.0.0/include from the clang
  429. # installation area (which contains in particular a
  430. # clang-compatible stdarg.h overriding the Visual Studio
  431. # one).
  432. # - similarly case-mashed copies of the library directories.
  433. # * Again, on a real VS installation, run vcvars32 or
  434. # vcvarsx86_amd64 (as appropriate), look at %LIB%, make a
  435. # copy of each directory, and provide symlinks within that
  436. # directory so that all the files can be opened as
  437. # lowercase.
  438. # * Then set LIB to be a semicolon-separated list of those
  439. # directories (but you'll need to change which set of
  440. # directories depending on whether you want to do a 32-bit
  441. # or 64-bit build).
  442. # - for a 64-bit build, set 'Platform=x64' in the environment as
  443. # well, or else on the make command line.
  444. # * This is a variable understood only by this makefile - none
  445. # of the tools we invoke will know it - but it's consistent
  446. # with the way the VS scripts like vcvarsx86_amd64.bat set
  447. # things up, and since the environment has to change
  448. # _anyway_ between 32- and 64-bit builds (different set of
  449. # paths in $LIB) it's reasonable to have the choice of
  450. # compilation target driven by another environment variable
  451. # set in parallel with that one.
  452. # - for older versions of the VS libraries you may also have to
  453. # set EXTRA_console and/or EXTRA_windows to the name of an
  454. # object file manually extracted from one of those libraries.
  455. # * This is because old VS seems to manage its startup code by
  456. # having libcmt.lib contain lots of *crt0.obj objects, one
  457. # for each possible user entry point (main, WinMain and the
  458. # wide-char versions of both), of which the linker arranges
  459. # to include the right one by special-case code. But lld
  460. # only seems to mimic half of that code - it does include
  461. # the right crt0 object, but it doesn't also deliberately
  462. # _avoid_ including the _wrong_ ones, and since all those
  463. # objects define a common set of global symbols for other
  464. # parts of the library to use, lld may well select an
  465. # arbitrary one of them the first time it sees a reference
  466. # to one of those global symbols, and then later also select
  467. # the _right_ one for the application's entry point, causing
  468. # a multiple-definitions crash.
  469. # * So the workaround is to explicitly include the right
  470. # *crt0.obj file on the linker command line before lld even
  471. # begins searching libraries. Hence, for a console
  472. # application, you might extract crt0.obj from the library
  473. # in question and set EXTRA_console=crt0.obj, and for a GUI
  474. # application, do the same with wincrt0.obj. Then this
  475. # makefile will include the right one of those objects
  476. # alongside the matching /subsystem linker option.
  477. # - also for older versions of the VS libraries, you may also
  478. # have to set EXTRA_libs to include extra library files.
  479. open OUT, ">$makefiles{'clangcl'}"; select OUT;
  480. print
  481. "# Makefile for cross-compiling $project_name using clang-cl, lld-link,\n".
  482. "# and llvm-rc, using GNU make on Linux.\n".
  483. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  484. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  485. print $help;
  486. print
  487. "\n".
  488. "CCCMD = clang-cl\n".
  489. "RCCMD = llvm-rc\n".
  490. "ifeq (\$(Platform),x64)\n".
  491. "CCTARGET = x86_64-pc-windows-msvc18.0.0\n".
  492. "PLATFORMCFLAGS =\n".
  493. "else ifeq (\$(Platform),arm)\n".
  494. "CCTARGET = arm-pc-windows-msvc18.0.0\n".
  495. "PLATFORMCFLAGS = /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE /GS-\n".
  496. "else ifeq (\$(Platform),arm64)\n".
  497. "CCTARGET = arm64-pc-windows-msvc18.0.0\n".
  498. "PLATFORMCFLAGS = /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE /GS-\n".
  499. "else\n".
  500. "CCTARGET = i386-pc-windows-msvc18.0.0\n".
  501. "PLATFORMCFLAGS =\n".
  502. "endif\n".
  503. "CC = \$(CCCMD)\n".
  504. "RC = \$(RCCMD) /c 1252 \n".
  505. "RCPREPROC = \$(CCCMD) /P /TC\n".
  506. "LD = lld-link\n".
  507. "\n".
  508. "# C compilation flags\n".
  509. &splitline("CFLAGS = --target=\$(CCTARGET) /nologo /W3 /O1 -Wvla " .
  510. (join " ", map {"-I$dirpfx$_"} @srcdirs) .
  511. " /D_WINDOWS /D_WIN32_WINDOWS=0x500 /DWINVER=0x500 ".
  512. "/D_CRT_SECURE_NO_WARNINGS /D_WINSOCK_DEPRECATED_NO_WARNINGS").
  513. " \$(PLATFORMCFLAGS)\n".
  514. "LFLAGS = /incremental:no /dynamicbase /nxcompat\n".
  515. &splitline("RCPPFLAGS = ".(join " ", map {"-I$dirpfx$_"} @srcdirs).
  516. " -DWIN32 -D_WIN32 -DWINVER=0x0400")." \$(RCFL)\n".
  517. "\n".
  518. &def($makefile_extra{'clangcl'}->{'vars'}) .
  519. "\n".
  520. "\n";
  521. print &splitline("all:" . join "", map { " \$(BUILDDIR)$_.exe" } &progrealnames("G:C"));
  522. print "\n\n";
  523. foreach $p (&prognames("G:C")) {
  524. ($prog, $type) = split ",", $p;
  525. $objstr = &objects($p, "\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", undef);
  526. print &splitline("\$(BUILDDIR)$prog.exe: " . $objstr), "\n";
  527. $objstr = &objects($p, "\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", "X.lib");
  528. $subsys = ($type eq "G") ? "windows" : "console";
  529. print &splitline("\t\$(LD) \$(LFLAGS) \$(XLFLAGS) ".
  530. "/out:\$(BUILDDIR)$prog.exe ".
  531. "/lldmap:\$(BUILDDIR)$prog.map ".
  532. "/subsystem:$subsys\$(SUBSYSVER) ".
  533. "\$(EXTRA_$subsys) $objstr \$(EXTRA_libs)")."\n\n";
  534. }
  535. my $rc_pp_rules = "";
  536. foreach $d (&deps("\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", $dirpfx, "/", "vc")) {
  537. $extradeps = $forceobj{$d->{obj_orig}} ? ["*.c","*.h","*.rc"] : [];
  538. my $rule;
  539. my @deps = @{$d->{deps}};
  540. my @incdeps = grep { m!\.rc2?$! } @deps;
  541. my @rcdeps = grep { ! m!\.rc2$! } @deps;
  542. if ($d->{obj} =~ /\.res$/) {
  543. my $rc = $deps[0];
  544. my $rcpp = $rc;
  545. $rcpp =~ s!.*/!!;
  546. $rcpp =~ s/\.rc$/.rcpp/;
  547. $rcpp = "\$(BUILDDIR)" . $rcpp;
  548. $rule = "\$(RC) ".$rcpp." /FO ".$d->{obj};
  549. $rc_pp_rules .= &splitline(
  550. sprintf("%s: %s", $rcpp, join " ", @incdeps)) ."\n" .
  551. "\t\$(RCPREPROC) \$(RCPPFLAGS) /Fi\$\@ \$<\n\n";
  552. $rcdeps[0] = $rcpp;
  553. } else {
  554. $rule = "\$(CC) /Fo\$(BUILDDIR) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) /c \$<";
  555. }
  556. print &splitline(sprintf("%s: %s", $d->{obj},
  557. join " ", @$extradeps, @rcdeps)), "\n";
  558. print "\t" . $rule . "\n\n";
  559. }
  560. print "\n" . $rc_pp_rules;
  561. print &def($makefile_extra{'clangcl'}->{'end'});
  562. print "\nclean:\n".
  563. &splitline("\trm -f \$(BUILDDIR)*.obj \$(BUILDDIR)*.exe ".
  564. "\$(BUILDDIR)*.rcpp \$(BUILDDIR)*.res \$(BUILDDIR)*.map ".
  565. "\$(BUILDDIR)*.exe.manifest")."\n";
  566. select STDOUT; close OUT;
  567. }
  568. if (defined $makefiles{'cygwin'}) {
  569. $dirpfx = &dirpfx($makefiles{'cygwin'}, "/");
  570. ##-- MinGW/CygWin makefile (called 'cygwin' for historical reasons)
  571. open OUT, ">$makefiles{'cygwin'}"; select OUT;
  572. print
  573. "# Makefile for $project_name under MinGW, Cygwin, or Winelib.\n".
  574. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  575. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  576. # gcc command line option is -D not /D
  577. ($_ = $help) =~ s/([=" ])\/D/$1-D/gs;
  578. print $_;
  579. print
  580. "\n".
  581. "# You can define this path to point at your tools if you need to\n".
  582. "# TOOLPATH = c:\\cygwin\\bin\\ # or similar, if you're running Windows\n".
  583. "# TOOLPATH = /pkg/mingw32msvc/i386-mingw32msvc/bin/\n".
  584. "# TOOLPATH = i686-w64-mingw32-\n".
  585. "CC = \$(TOOLPATH)gcc\n".
  586. "RC = \$(TOOLPATH)windres\n".
  587. "# Uncomment the following two lines to compile under Winelib\n".
  588. "# CC = winegcc\n".
  589. "# RC = wrc\n".
  590. "# You may also need to tell windres where to find include files:\n".
  591. "# RCINC = --include-dir c:\\cygwin\\include\\\n".
  592. "\n".
  593. &splitline("CFLAGS = -Wall -O2 -std=gnu99 -Wvla -D_WINDOWS".
  594. " -DWIN32S_COMPAT -D_NO_OLDNAMES -D__USE_MINGW_ANSI_STDIO=1 " .
  595. (join " ", map {"-I$dirpfx$_"} @srcdirs)) .
  596. "\n".
  597. "LDFLAGS = -s\n".
  598. &splitline("RCFLAGS = \$(RCINC) --define WIN32=1 --define _WIN32=1 ".
  599. "--define WINVER=0x0400 ".(join " ", map {"-I$dirpfx$_"} @srcdirs))."\n".
  600. "\n".
  601. &def($makefile_extra{'cygwin'}->{'vars'}) .
  602. "\n".
  603. ".SUFFIXES:\n".
  604. "\n";
  605. print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
  606. print "\n\n";
  607. foreach $p (&prognames("G:C")) {
  608. ($prog, $type) = split ",", $p;
  609. $objstr = &objects($p, "X.o", "X.res.o", undef);
  610. print &splitline($prog . ".exe: " . $objstr), "\n";
  611. my $mw = $type eq "G" ? " -mwindows" : "";
  612. $libstr = &objects($p, undef, undef, "-lX");
  613. print &splitline("\t\$(CC)" . $mw . " \$(LDFLAGS) -o \$@ " .
  614. "-Wl,-Map,$prog.map " .
  615. $objstr . " $libstr", 69), "\n\n";
  616. }
  617. foreach $d (&deps("X.o", "X.res.o", $dirpfx, "/", "cygwin")) {
  618. if ($forceobj{$d->{obj_orig}}) {
  619. printf ("%s: FORCE\n", $d->{obj});
  620. } else {
  621. print &splitline(sprintf("%s: %s", $d->{obj},
  622. join " ", @{$d->{deps}})), "\n";
  623. }
  624. if ($d->{obj} =~ /\.res\.o$/) {
  625. print "\t\$(RC) \$(RCFL) \$(RCFLAGS) ".$d->{deps}->[0]." -o ".$d->{obj}."\n\n";
  626. } else {
  627. print "\t\$(CC) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) -c ".$d->{deps}->[0]."\n\n";
  628. }
  629. }
  630. print "\n";
  631. print &def($makefile_extra{'cygwin'}->{'end'});
  632. print "\nclean:\n".
  633. "\trm -f *.o *.exe *.res.o *.so *.map\n".
  634. "\n".
  635. "FORCE:\n";
  636. select STDOUT; close OUT;
  637. }
  638. if (defined $makefiles{'vc'}) {
  639. $dirpfx = &dirpfx($makefiles{'vc'}, "\\");
  640. ##-- Visual C++ makefile
  641. open OUT, ">$makefiles{'vc'}"; select OUT;
  642. print
  643. "# Makefile for $project_name under Visual C.\n".
  644. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  645. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  646. print $help;
  647. print
  648. "\n".
  649. "# If you rename this file to `Makefile', you should change this line,\n".
  650. "# so that the .rsp files still depend on the correct makefile.\n".
  651. "MAKEFILE = Makefile.vc\n".
  652. "\n".
  653. "# C compilation flags\n".
  654. "CFLAGS = /nologo /W3 /O1 " .
  655. (join " ", map {"-I$dirpfx$_"} @srcdirs) .
  656. " /D_WINDOWS /D_WIN32_WINDOWS=0x500 /DWINVER=0x500 /D_CRT_SECURE_NO_WARNINGS /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE\n".
  657. "LFLAGS = /incremental:no /dynamicbase /nxcompat\n".
  658. "RCFLAGS = ".(join " ", map {"-I$dirpfx$_"} @srcdirs).
  659. " -DWIN32 -D_WIN32 -DWINVER=0x0400\n".
  660. "\n".
  661. &def($makefile_extra{'vc'}->{'vars'}) .
  662. "\n".
  663. "\n";
  664. print &splitline("all:" . join "", map { " \$(BUILDDIR)$_.exe" } &progrealnames("G:C"));
  665. print "\n\n";
  666. foreach $p (&prognames("G:C")) {
  667. ($prog, $type) = split ",", $p;
  668. $objstr = &objects($p, "\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", undef);
  669. print &splitline("\$(BUILDDIR)$prog.exe: " . $objstr), "\n";
  670. $objstr = &objects($p, "\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", "X.lib");
  671. $subsys = ($type eq "G") ? "windows" : "console";
  672. $inlinefilename = "link_$prog";
  673. print "\ttype <<$inlinefilename\n";
  674. @objlist = split " ", $objstr;
  675. @objlines = ("");
  676. foreach $i (@objlist) {
  677. if (length($objlines[$#objlines] . " $i") > 72) {
  678. push @objlines, "";
  679. }
  680. $objlines[$#objlines] .= " $i";
  681. }
  682. for ($i=0; $i<=$#objlines; $i++) {
  683. print "$objlines[$i]\n";
  684. }
  685. print "<<\n";
  686. print "\tlink \$(LFLAGS) \$(XLFLAGS) -out:\$(BUILDDIR)$prog.exe -map:\$(BUILDDIR)$prog.map -nologo -subsystem:$subsys\$(SUBSYSVER) \@$inlinefilename\n\n";
  687. }
  688. foreach $d (&deps("\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", $dirpfx, "\\", "vc")) {
  689. $extradeps = $forceobj{$d->{obj_orig}} ? ["*.c","*.h","*.rc"] : [];
  690. print &splitline(sprintf("%s: %s", $d->{obj},
  691. join " ", @$extradeps, @{$d->{deps}})), "\n";
  692. if ($d->{obj} =~ /.res$/) {
  693. print "\trc /Fo@{[$d->{obj}]} \$(RCFL) -r \$(RCFLAGS) ".$d->{deps}->[0],"\n\n";
  694. }
  695. }
  696. print "\n";
  697. foreach $real_srcdir ("", @srcdirs) {
  698. $srcdir = $real_srcdir;
  699. if ($srcdir ne "") {
  700. $srcdir =~ s!/!\\!g;
  701. $srcdir = $dirpfx . $srcdir;
  702. $srcdir =~ s!\\\.\\!\\!;
  703. $srcdir = "{$srcdir}";
  704. }
  705. # The double colon at the end of the line makes this a
  706. # 'batch-mode inference rule', which means that nmake will
  707. # aggregate multiple invocations of the rule and issue just
  708. # one cl command with multiple source-file arguments. That
  709. # noticeably speeds up builds, since starting up the cl
  710. # process is a noticeable overhead and now has to be done far
  711. # fewer times.
  712. print "${srcdir}.c.obj::\n\tcl /Fo\$(BUILDDIR) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) /c \$<\n\n";
  713. }
  714. print &def($makefile_extra{'vc'}->{'end'});
  715. print "\nclean: tidy\n".
  716. "\t-del \$(BUILDDIR)*.exe\n\n".
  717. "tidy:\n".
  718. "\t-del \$(BUILDDIR)*.obj\n".
  719. "\t-del \$(BUILDDIR)*.res\n".
  720. "\t-del \$(BUILDDIR)*.pch\n".
  721. "\t-del \$(BUILDDIR)*.aps\n".
  722. "\t-del \$(BUILDDIR)*.ilk\n".
  723. "\t-del \$(BUILDDIR)*.pdb\n".
  724. "\t-del \$(BUILDDIR)*.rsp\n".
  725. "\t-del \$(BUILDDIR)*.dsp\n".
  726. "\t-del \$(BUILDDIR)*.dsw\n".
  727. "\t-del \$(BUILDDIR)*.ncb\n".
  728. "\t-del \$(BUILDDIR)*.opt\n".
  729. "\t-del \$(BUILDDIR)*.plg\n".
  730. "\t-del \$(BUILDDIR)*.map\n".
  731. "\t-del \$(BUILDDIR)*.idb\n".
  732. "\t-del \$(BUILDDIR)debug.log\n";
  733. select STDOUT; close OUT;
  734. }
  735. if (defined $makefiles{'vcproj'}) {
  736. $dirpfx = &dirpfx($makefiles{'vcproj'}, "\\");
  737. ##-- MSVC 6 Workspace and projects
  738. #
  739. # Note: All files created in this section are written in binary
  740. # mode, because although MSVC's command-line make can deal with
  741. # LF-only line endings, MSVC project files really _need_ to be
  742. # CRLF. Hence, in order for mkfiles.pl to generate usable project
  743. # files even when run from Unix, I make sure all files are binary
  744. # and explicitly write the CRLFs.
  745. #
  746. # Create directories if necessary
  747. mkdir $makefiles{'vcproj'}
  748. if(! -d $makefiles{'vcproj'});
  749. chdir $makefiles{'vcproj'};
  750. @deps = &deps("X.obj", "X.res", $dirpfx, "\\", "vcproj");
  751. %all_object_deps = map {$_->{obj} => $_->{deps}} @deps;
  752. # Create the project files
  753. # Get names of all Windows projects (GUI and console)
  754. my @prognames = &prognames("G:C");
  755. foreach $progname (@prognames) {
  756. create_vc_project(\%all_object_deps, $progname);
  757. }
  758. # Create the workspace file
  759. open OUT, ">$project_name.dsw"; binmode OUT; select OUT;
  760. print
  761. "Microsoft Developer Studio Workspace File, Format Version 6.00\r\n".
  762. "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r\n".
  763. "\r\n".
  764. "###############################################################################\r\n".
  765. "\r\n";
  766. # List projects
  767. foreach $progname (@prognames) {
  768. ($windows_project, $type) = split ",", $progname;
  769. print "Project: \"$windows_project\"=\".\\$windows_project\\$windows_project.dsp\" - Package Owner=<4>\r\n";
  770. }
  771. print
  772. "\r\n".
  773. "Package=<5>\r\n".
  774. "{{{\r\n".
  775. "}}}\r\n".
  776. "\r\n".
  777. "Package=<4>\r\n".
  778. "{{{\r\n".
  779. "}}}\r\n".
  780. "\r\n".
  781. "###############################################################################\r\n".
  782. "\r\n".
  783. "Global:\r\n".
  784. "\r\n".
  785. "Package=<5>\r\n".
  786. "{{{\r\n".
  787. "}}}\r\n".
  788. "\r\n".
  789. "Package=<3>\r\n".
  790. "{{{\r\n".
  791. "}}}\r\n".
  792. "\r\n".
  793. "###############################################################################\r\n".
  794. "\r\n";
  795. select STDOUT; close OUT;
  796. chdir $orig_dir;
  797. sub create_vc_project {
  798. my ($all_object_deps, $progname) = @_;
  799. # Construct program's dependency info
  800. %seen_objects = ();
  801. %lib_files = ();
  802. %source_files = ();
  803. %header_files = ();
  804. %resource_files = ();
  805. @object_files = split " ", &objects($progname, "X.obj", "X.res", "X.lib");
  806. foreach $object_file (@object_files) {
  807. next if defined $seen_objects{$object_file};
  808. $seen_objects{$object_file} = 1;
  809. if($object_file =~ /\.lib$/io) {
  810. $lib_files{$object_file} = 1;
  811. next;
  812. }
  813. $object_deps = $all_object_deps{$object_file};
  814. foreach $object_dep (@$object_deps) {
  815. if($object_dep =~ /\.c$/io) {
  816. $source_files{$object_dep} = 1;
  817. next;
  818. }
  819. if($object_dep =~ /\.h$/io) {
  820. $header_files{$object_dep} = 1;
  821. next;
  822. }
  823. if($object_dep =~ /\.(rc|ico)$/io) {
  824. $resource_files{$object_dep} = 1;
  825. next;
  826. }
  827. }
  828. }
  829. $libs = join " ", sort keys %lib_files;
  830. @source_files = sort keys %source_files;
  831. @header_files = sort keys %header_files;
  832. @resources = sort keys %resource_files;
  833. ($windows_project, $type) = split ",", $progname;
  834. mkdir $windows_project
  835. if(! -d $windows_project);
  836. chdir $windows_project;
  837. $subsys = ($type eq "G") ? "windows" : "console";
  838. open OUT, ">$windows_project.dsp"; binmode OUT; select OUT;
  839. print
  840. "# Microsoft Developer Studio Project File - Name=\"$windows_project\" - Package Owner=<4>\r\n".
  841. "# Microsoft Developer Studio Generated Build File, Format Version 6.00\r\n".
  842. "# ** DO NOT EDIT **\r\n".
  843. "\r\n".
  844. "# TARGTYPE \"Win32 (x86) Application\" 0x0101\r\n".
  845. "\r\n".
  846. "CFG=$windows_project - Win32 Debug\r\n".
  847. "!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r\n".
  848. "!MESSAGE use the Export Makefile command and run\r\n".
  849. "!MESSAGE \r\n".
  850. "!MESSAGE NMAKE /f \"$windows_project.mak\".\r\n".
  851. "!MESSAGE \r\n".
  852. "!MESSAGE You can specify a configuration when running NMAKE\r\n".
  853. "!MESSAGE by defining the macro CFG on the command line. For example:\r\n".
  854. "!MESSAGE \r\n".
  855. "!MESSAGE NMAKE /f \"$windows_project.mak\" CFG=\"$windows_project - Win32 Debug\"\r\n".
  856. "!MESSAGE \r\n".
  857. "!MESSAGE Possible choices for configuration are:\r\n".
  858. "!MESSAGE \r\n".
  859. "!MESSAGE \"$windows_project - Win32 Release\" (based on \"Win32 (x86) Application\")\r\n".
  860. "!MESSAGE \"$windows_project - Win32 Debug\" (based on \"Win32 (x86) Application\")\r\n".
  861. "!MESSAGE \r\n".
  862. "\r\n".
  863. "# Begin Project\r\n".
  864. "# PROP AllowPerConfigDependencies 0\r\n".
  865. "# PROP Scc_ProjName \"\"\r\n".
  866. "# PROP Scc_LocalPath \"\"\r\n".
  867. "CPP=cl.exe\r\n".
  868. "MTL=midl.exe\r\n".
  869. "RSC=rc.exe\r\n".
  870. "\r\n".
  871. "!IF \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
  872. "\r\n".
  873. "# PROP BASE Use_MFC 0\r\n".
  874. "# PROP BASE Use_Debug_Libraries 0\r\n".
  875. "# PROP BASE Output_Dir \"Release\"\r\n".
  876. "# PROP BASE Intermediate_Dir \"Release\"\r\n".
  877. "# PROP BASE Target_Dir \"\"\r\n".
  878. "# PROP Use_MFC 0\r\n".
  879. "# PROP Use_Debug_Libraries 0\r\n".
  880. "# PROP Output_Dir \"Release\"\r\n".
  881. "# PROP Intermediate_Dir \"Release\"\r\n".
  882. "# PROP Ignore_Export_Lib 0\r\n".
  883. "# PROP Target_Dir \"\"\r\n".
  884. "# ADD BASE CPP /nologo /W3 /GX /O2 ".
  885. (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
  886. " /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
  887. "# ADD CPP /nologo /W3 /GX /O2 ".
  888. (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
  889. " /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
  890. "# ADD BASE MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
  891. "# ADD MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
  892. "# ADD BASE RSC /l 0x809 /d \"NDEBUG\"\r\n".
  893. "# ADD RSC /l 0x809 /d \"NDEBUG\"\r\n".
  894. "BSC32=bscmake.exe\r\n".
  895. "# ADD BASE BSC32 /nologo\r\n".
  896. "# ADD BSC32 /nologo\r\n".
  897. "LINK32=link.exe\r\n".
  898. "# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:$subsys /machine:I386\r\n".
  899. "# ADD LINK32 $libs /nologo /subsystem:$subsys /machine:I386\r\n".
  900. "# SUBTRACT LINK32 /pdb:none\r\n".
  901. "\r\n".
  902. "!ELSEIF \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
  903. "\r\n".
  904. "# PROP BASE Use_MFC 0\r\n".
  905. "# PROP BASE Use_Debug_Libraries 1\r\n".
  906. "# PROP BASE Output_Dir \"Debug\"\r\n".
  907. "# PROP BASE Intermediate_Dir \"Debug\"\r\n".
  908. "# PROP BASE Target_Dir \"\"\r\n".
  909. "# PROP Use_MFC 0\r\n".
  910. "# PROP Use_Debug_Libraries 1\r\n".
  911. "# PROP Output_Dir \"Debug\"\r\n".
  912. "# PROP Intermediate_Dir \"Debug\"\r\n".
  913. "# PROP Ignore_Export_Lib 0\r\n".
  914. "# PROP Target_Dir \"\"\r\n".
  915. "# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od ".
  916. (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
  917. " /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
  918. "# ADD CPP /nologo /W3 /Gm /GX /ZI /Od ".
  919. (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
  920. " /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
  921. "# ADD BASE MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
  922. "# ADD MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
  923. "# ADD BASE RSC /l 0x809 /d \"_DEBUG\"\r\n".
  924. "# ADD RSC /l 0x809 /d \"_DEBUG\"\r\n".
  925. "BSC32=bscmake.exe\r\n".
  926. "# ADD BASE BSC32 /nologo\r\n".
  927. "# ADD BSC32 /nologo\r\n".
  928. "LINK32=link.exe\r\n".
  929. "# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:$subsys /debug /machine:I386 /pdbtype:sept\r\n".
  930. "# ADD LINK32 $libs /nologo /subsystem:$subsys /debug /machine:I386 /pdbtype:sept\r\n".
  931. "# SUBTRACT LINK32 /pdb:none\r\n".
  932. "\r\n".
  933. "!ENDIF \r\n".
  934. "\r\n".
  935. "# Begin Target\r\n".
  936. "\r\n".
  937. "# Name \"$windows_project - Win32 Release\"\r\n".
  938. "# Name \"$windows_project - Win32 Debug\"\r\n".
  939. "# Begin Group \"Source Files\"\r\n".
  940. "\r\n".
  941. "# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\"\r\n";
  942. foreach $source_file (@source_files) {
  943. print
  944. "# Begin Source File\r\n".
  945. "\r\n".
  946. "SOURCE=..\\..\\$source_file\r\n";
  947. if($source_file =~ /ssh\.c/io) {
  948. # Disable 'Edit and continue' as Visual Studio can't handle the macros
  949. print
  950. "\r\n".
  951. "!IF \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
  952. "\r\n".
  953. "!ELSEIF \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
  954. "\r\n".
  955. "# ADD CPP /Zi\r\n".
  956. "\r\n".
  957. "!ENDIF \r\n".
  958. "\r\n";
  959. }
  960. print "# End Source File\r\n";
  961. }
  962. print
  963. "# End Group\r\n".
  964. "# Begin Group \"Header Files\"\r\n".
  965. "\r\n".
  966. "# PROP Default_Filter \"h;hpp;hxx;hm;inl\"\r\n";
  967. foreach $header_file (@header_files) {
  968. print
  969. "# Begin Source File\r\n".
  970. "\r\n".
  971. "SOURCE=..\\..\\$header_file\r\n".
  972. "# End Source File\r\n";
  973. }
  974. print
  975. "# End Group\r\n".
  976. "# Begin Group \"Resource Files\"\r\n".
  977. "\r\n".
  978. "# PROP Default_Filter \"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\r\n";
  979. foreach $resource_file (@resources) {
  980. print
  981. "# Begin Source File\r\n".
  982. "\r\n".
  983. "SOURCE=..\\..\\$resource_file\r\n".
  984. "# End Source File\r\n";
  985. }
  986. print
  987. "# End Group\r\n".
  988. "# End Target\r\n".
  989. "# End Project\r\n";
  990. select STDOUT; close OUT;
  991. chdir "..";
  992. }
  993. }
  994. if (defined $makefiles{'vstudio10'} || defined $makefiles{'vstudio12'}) {
  995. ##-- Visual Studio 2010+ Solution and Projects
  996. if (defined $makefiles{'vstudio10'}) {
  997. create_vs_solution('vstudio10', "2010", "11.00", "v100");
  998. }
  999. if (defined $makefiles{'vstudio12'}) {
  1000. create_vs_solution('vstudio12', "2012", "12.00", "v110");
  1001. }
  1002. sub create_vs_solution {
  1003. my ($makefilename, $name, $version, $toolsver) = @_;
  1004. $dirpfx = &dirpfx($makefiles{$makefilename}, "\\");
  1005. @deps = &deps("X.obj", "X.res", $dirpfx, "\\", $makefilename);
  1006. %all_object_deps = map {$_->{obj} => $_->{deps}} @deps;
  1007. my @prognames = &prognames("G:C");
  1008. # Create the solution file.
  1009. mkdir $makefiles{$makefilename}
  1010. if(! -f $makefiles{$makefilename});
  1011. chdir $makefiles{$makefilename};
  1012. open OUT, ">$project_name.sln"; select OUT;
  1013. print
  1014. "Microsoft Visual Studio Solution File, Format Version $version\n" .
  1015. "# Visual Studio $name\n";
  1016. my %projguids = ();
  1017. foreach $progname (@prognames) {
  1018. ($windows_project, $type) = split ",", $progname;
  1019. $projguids{$windows_project} = $guid =
  1020. &invent_guid("project:$progname");
  1021. print
  1022. "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$windows_project\", \"$windows_project\\$windows_project.vcxproj\", \"{$guid}\"\n" .
  1023. "EndProject\n";
  1024. }
  1025. print
  1026. "Global\n" .
  1027. " GlobalSection(SolutionConfigurationPlatforms) = preSolution\n" .
  1028. " Debug|Win32 = Debug|Win32\n" .
  1029. " Release|Win32 = Release|Win32\n" .
  1030. " EndGlobalSection\n" .
  1031. " GlobalSection(ProjectConfigurationPlatforms) = postSolution\n" ;
  1032. foreach my $projguid (values %projguids) {
  1033. print
  1034. " {$projguid}.Debug|Win32.ActiveCfg = Debug|Win32\n" .
  1035. " {$projguid}.Debug|Win32.Build.0 = Debug|Win32\n" .
  1036. " {$projguid}.Release|Win32.ActiveCfg = Release|Win32\n" .
  1037. " {$projguid}.Release|Win32.Build.0 = Release|Win32\n";
  1038. }
  1039. print
  1040. " EndGlobalSection\n" .
  1041. " GlobalSection(SolutionProperties) = preSolution\n" .
  1042. " HideSolutionNode = FALSE\n" .
  1043. " EndGlobalSection\n" .
  1044. "EndGlobal\n";
  1045. select STDOUT; close OUT;
  1046. foreach $progname (@prognames) {
  1047. ($windows_project, $type) = split ",", $progname;
  1048. create_vs_project(\%all_object_deps, $windows_project, $type, $projguids{$windows_project}, $toolsver);
  1049. }
  1050. chdir $orig_dir;
  1051. }
  1052. sub create_vs_project {
  1053. my ($all_object_deps, $windows_project, $type, $projguid, $toolsver) = @_;
  1054. # Break down the project's dependency information into the appropriate
  1055. # groups.
  1056. %seen_objects = ();
  1057. %lib_files = ();
  1058. %source_files = ();
  1059. %header_files = ();
  1060. %resource_files = ();
  1061. %icon_files = ();
  1062. @object_files = split " ", &objects($progname, "X.obj", "X.res", "X.lib");
  1063. foreach $object_file (@object_files) {
  1064. next if defined $seen_objects{$object_file};
  1065. $seen_objects{$object_file} = 1;
  1066. if($object_file =~ /\.lib$/io) {
  1067. $lib_files{$object_file} = 1;
  1068. next;
  1069. }
  1070. $object_deps = $all_object_deps{$object_file};
  1071. foreach $object_dep (@$object_deps) {
  1072. if($object_dep eq $object_deps->[0]) {
  1073. if($object_dep =~ /\.c$/io) {
  1074. $source_files{$object_dep} = 1;
  1075. } elsif($object_dep =~ /\.rc$/io) {
  1076. $resource_files{$object_dep} = 1;
  1077. }
  1078. } elsif ($object_dep =~ /\.[ch]$/io) {
  1079. $header_files{$object_dep} = 1;
  1080. } elsif ($object_dep =~ /\.ico$/io) {
  1081. $icon_files{$object_dep} = 1;
  1082. }
  1083. }
  1084. }
  1085. $libs = join ";", sort keys %lib_files;
  1086. @source_files = sort keys %source_files;
  1087. @header_files = sort keys %header_files;
  1088. @resources = sort keys %resource_files;
  1089. @icons = sort keys %icon_files;
  1090. $subsystem = ($type eq "G") ? "Windows" : "Console";
  1091. mkdir $windows_project
  1092. if(! -d $windows_project);
  1093. chdir $windows_project;
  1094. open OUT, ">$windows_project.vcxproj"; select OUT;
  1095. open FILTERS, ">$windows_project.vcxproj.filters";
  1096. # The bulk of the project file is just boilerplate stuff, so we
  1097. # can mostly just dump it out here. Note, buried in the ClCompile
  1098. # item definition, that we use a debug information format of
  1099. # ProgramDatabase, which disables the edit-and-continue support
  1100. # that breaks most of the project builds.
  1101. print
  1102. "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .
  1103. "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" .
  1104. " <ItemGroup Label=\"ProjectConfigurations\">\n" .
  1105. " <ProjectConfiguration Include=\"Debug|Win32\">\n" .
  1106. " <Configuration>Debug</Configuration>\n" .
  1107. " <Platform>Win32</Platform>\n" .
  1108. " </ProjectConfiguration>\n" .
  1109. " <ProjectConfiguration Include=\"Release|Win32\">\n" .
  1110. " <Configuration>Release</Configuration>\n" .
  1111. " <Platform>Win32</Platform>\n" .
  1112. " </ProjectConfiguration>\n" .
  1113. " </ItemGroup>\n" .
  1114. " <PropertyGroup Label=\"Globals\">\n" .
  1115. " <SccProjectName />\n" .
  1116. " <SccLocalPath />\n" .
  1117. " <ProjectGuid>{$projguid}</ProjectGuid>\n" .
  1118. " </PropertyGroup>\n" .
  1119. " <Import Project=\"\$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n" .
  1120. " <PropertyGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n" .
  1121. " <ConfigurationType>Application</ConfigurationType>\n" .
  1122. " <UseOfMfc>false</UseOfMfc>\n" .
  1123. " <CharacterSet>MultiByte</CharacterSet>\n" .
  1124. " <PlatformToolset>$toolsver</PlatformToolset>\n" .
  1125. " </PropertyGroup>\n" .
  1126. " <PropertyGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n" .
  1127. " <ConfigurationType>Application</ConfigurationType>\n" .
  1128. " <UseOfMfc>false</UseOfMfc>\n" .
  1129. " <CharacterSet>MultiByte</CharacterSet>\n" .
  1130. " <PlatformToolset>$toolsver</PlatformToolset>\n" .
  1131. " </PropertyGroup>\n" .
  1132. " <Import Project=\"\$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n" .
  1133. " <ImportGroup Label=\"ExtensionTargets\">\n" .
  1134. " </ImportGroup>\n" .
  1135. " <ImportGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n" .
  1136. " <Import Project=\"\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props\" Condition=\"exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n" .
  1137. " </ImportGroup>\n" .
  1138. " <ImportGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n" .
  1139. " <Import Project=\"\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props\" Condition=\"exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n" .
  1140. " </ImportGroup>\n" .
  1141. " <PropertyGroup Label=\"UserMacros\" />\n" .
  1142. " <PropertyGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Release|Win32'\">\n" .
  1143. " <OutDir>.\\Release\\</OutDir>\n" .
  1144. " <IntDir>.\\Release\\</IntDir>\n" .
  1145. " <LinkIncremental>false</LinkIncremental>\n" .
  1146. " </PropertyGroup>\n" .
  1147. " <PropertyGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">\n" .
  1148. " <OutDir>.\\Debug\\</OutDir>\n" .
  1149. " <IntDir>.\\Debug\\</IntDir>\n" .
  1150. " <LinkIncremental>true</LinkIncremental>\n" .
  1151. " </PropertyGroup>\n" .
  1152. " <ItemDefinitionGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Release|Win32'\">\n" .
  1153. " <ClCompile>\n" .
  1154. " <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n" .
  1155. " <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n" .
  1156. " <StringPooling>true</StringPooling>\n" .
  1157. " <FunctionLevelLinking>true</FunctionLevelLinking>\n" .
  1158. " <Optimization>MaxSpeed</Optimization>\n" .
  1159. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1160. " <WarningLevel>Level3</WarningLevel>\n" .
  1161. " <AdditionalIncludeDirectories>" . (join ";", map {"..\\..\\$dirpfx$_"} @srcdirs) . ";%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" .
  1162. " <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;POSIX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1163. " <AssemblerListingLocation>.\\Release\\</AssemblerListingLocation>\n" .
  1164. " <PrecompiledHeaderOutputFile>.\\Release\\$windows_project.pch</PrecompiledHeaderOutputFile>\n" .
  1165. " <ObjectFileName>.\\Release\\</ObjectFileName>\n" .
  1166. " <ProgramDataBaseFileName>.\\Release\\</ProgramDataBaseFileName>\n" .
  1167. " </ClCompile>\n" .
  1168. " <Midl>\n" .
  1169. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1170. " <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1171. " <TypeLibraryName>.\\Release\\$windows_project.tlb</TypeLibraryName>\n" .
  1172. " <MkTypLibCompatible>true</MkTypLibCompatible>\n" .
  1173. " <TargetEnvironment>Win32</TargetEnvironment>\n" .
  1174. " </Midl>\n" .
  1175. " <ResourceCompile>\n" .
  1176. " <Culture>0x0809</Culture>\n" .
  1177. " <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1178. " </ResourceCompile>\n" .
  1179. " <Bscmake>\n" .
  1180. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1181. " <OutputFile>.\\Release\\$windows_project.bsc</OutputFile>\n" .
  1182. " </Bscmake>\n" .
  1183. " <Link>\n" .
  1184. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1185. " <SubSystem>$subsystem</SubSystem>\n" .
  1186. " <OutputFile>.\\Release\\$windows_project.exe</OutputFile>\n" .
  1187. " <AdditionalDependencies>$libs;%(AdditionalDependencies)</AdditionalDependencies>\n" .
  1188. " </Link>\n" .
  1189. " </ItemDefinitionGroup>\n" .
  1190. " <ItemDefinitionGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">\n" .
  1191. " <ClCompile>\n" .
  1192. " <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n" .
  1193. " <InlineFunctionExpansion>Default</InlineFunctionExpansion>\n" .
  1194. " <FunctionLevelLinking>false</FunctionLevelLinking>\n" .
  1195. " <Optimization>Disabled</Optimization>\n" .
  1196. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1197. " <WarningLevel>Level3</WarningLevel>\n" .
  1198. " <MinimalRebuild>true</MinimalRebuild>\n" .
  1199. " <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n" .
  1200. " <AdditionalIncludeDirectories>" . (join ";", map {"..\\..\\$dirpfx$_"} @srcdirs) . ";%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" .
  1201. " <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POSIX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1202. " <AssemblerListingLocation>.\\Debug\\</AssemblerListingLocation>\n" .
  1203. " <PrecompiledHeaderOutputFile>.\\Debug\\$windows_project.pch</PrecompiledHeaderOutputFile>\n" .
  1204. " <ObjectFileName>.\\Debug\\</ObjectFileName>\n" .
  1205. " <ProgramDataBaseFileName>.\\Debug\\</ProgramDataBaseFileName>\n" .
  1206. " <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n" .
  1207. " </ClCompile>\n" .
  1208. " <Midl>\n" .
  1209. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1210. " <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1211. " <TypeLibraryName>.\\Debug\\$windows_project.tlb</TypeLibraryName>\n" .
  1212. " <MkTypLibCompatible>true</MkTypLibCompatible>\n" .
  1213. " <TargetEnvironment>Win32</TargetEnvironment>\n" .
  1214. " </Midl>\n" .
  1215. " <ResourceCompile>\n" .
  1216. " <Culture>0x0809</Culture>\n" .
  1217. " <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1218. " </ResourceCompile>\n" .
  1219. " <Bscmake>\n" .
  1220. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1221. " <OutputFile>.\\Debug\\$windows_project.bsc</OutputFile>\n" .
  1222. " </Bscmake>\n" .
  1223. " <Link>\n" .
  1224. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1225. " <GenerateDebugInformation>true</GenerateDebugInformation>\n" .
  1226. " <SubSystem>$subsystem</SubSystem>\n" .
  1227. " <OutputFile>\$(TargetPath)</OutputFile>\n" .
  1228. " <AdditionalDependencies>$libs;%(AdditionalDependencies)</AdditionalDependencies>\n" .
  1229. " </Link>\n" .
  1230. " </ItemDefinitionGroup>\n";
  1231. # The VC++ projects don't have physical structure to them, instead
  1232. # the files are organized by logical "filters" that are stored in
  1233. # a separate file, so different users can organize things differently.
  1234. # The filters file contains a copy of the ItemGroup elements from
  1235. # the main project file that list the included items, but tack
  1236. # on a filter name where needed.
  1237. print FILTERS
  1238. "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .
  1239. "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n";
  1240. print " <ItemGroup>\n";
  1241. print FILTERS " <ItemGroup>\n";
  1242. foreach $icon_file (@icons) {
  1243. $icon_file =~ s/..\\windows\\//;
  1244. print " <CustomBuild Include=\"..\\..\\$icon_file\" />\n";
  1245. print FILTERS
  1246. " <CustomBuild Include=\"..\\..\\$icon_file\">\n" .
  1247. " <Filter>Resource Files</Filter>\n" .
  1248. " </CustomBuild>\n";
  1249. }
  1250. print FILTERS " </ItemGroup>\n";
  1251. print " </ItemGroup>\n";
  1252. print " <ItemGroup>\n";
  1253. print FILTERS " <ItemGroup>\n";
  1254. foreach $resource_file (@resources) {
  1255. $resource_file =~ s/..\\windows\\//;
  1256. print
  1257. " <ResourceCompile Include=\"..\\..\\$resource_file\">\n" .
  1258. " <AdditionalIncludeDirectories Condition=\"'\$(Configuration)|\$(Platform)'=='Release|Win32'\">..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" .
  1259. " <AdditionalIncludeDirectories Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" .
  1260. " </ResourceCompile>\n";
  1261. print FILTERS
  1262. " <ResourceCompile Include=\"..\\..\\$resource_file\">\n" .
  1263. " <Filter>Resource Files</Filter>\n" .
  1264. " </ResourceCompile>\n";
  1265. }
  1266. print FILTERS " </ItemGroup>\n";
  1267. print " </ItemGroup>\n";
  1268. print " <ItemGroup>\n";
  1269. print FILTERS " <ItemGroup>\n";
  1270. foreach $source_file (@source_files) {
  1271. $source_file =~ s/..\\windows\\//;
  1272. print " <ClCompile Include=\"..\\..\\$source_file\" />\n";
  1273. print FILTERS
  1274. " <ClCompile Include=\"..\\..\\$source_file\">\n" .
  1275. " <Filter>Source Files</Filter>\n" .
  1276. " </ClCompile>";
  1277. }
  1278. print FILTERS " </ItemGroup>\n";
  1279. print " </ItemGroup>\n";
  1280. print " <ItemGroup>\n";
  1281. print FILTERS " <ItemGroup>\n";
  1282. foreach $header_file (@header_files) {
  1283. $header_file =~ s/..\\windows\\//;
  1284. print " <ClInclude Include=\"..\\..\\$header_file\" />\n";
  1285. print FILTERS
  1286. " <ClInclude Include=\"..\\..\\$header_file\">\n" .
  1287. " <Filter>Header Files</Filter>\n" .
  1288. " </ClInclude>";
  1289. }
  1290. print FILTERS " </ItemGroup>\n";
  1291. print " </ItemGroup>\n";
  1292. print
  1293. " <Import Project=\"\$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n" .
  1294. "</Project>";
  1295. print FILTERS
  1296. " <ItemGroup>\n" .
  1297. " <Filter Include=\"Source Files\">\n" .
  1298. " <UniqueIdentifier>{" . &invent_guid("sources:$windows_project") . "}</UniqueIdentifier>\n" .
  1299. " </Filter>\n" .
  1300. " <Filter Include=\"Header Files\">\n" .
  1301. " <UniqueIdentifier>{" . &invent_guid("headers:$windows_project") . "}</UniqueIdentifier>\n" .
  1302. " </Filter>\n" .
  1303. " <Filter Include=\"Resource Files\">\n" .
  1304. " <UniqueIdentifier>{" . &invent_guid("resources:$windows_project") . "}</UniqueIdentifier>\n" .
  1305. " </Filter>\n" .
  1306. " </ItemGroup>\n" .
  1307. "</Project>";
  1308. select STDOUT; close OUT; close FILTERS;
  1309. chdir "..";
  1310. }
  1311. }
  1312. if (defined $makefiles{'gtk'}) {
  1313. $dirpfx = &dirpfx($makefiles{'gtk'}, "/");
  1314. ##-- X/GTK/Unix makefile
  1315. open OUT, ">$makefiles{'gtk'}"; select OUT;
  1316. print
  1317. "# Makefile for $project_name under X/GTK and Unix.\n".
  1318. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  1319. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  1320. # gcc command line option is -D not /D
  1321. ($_ = $help) =~ s/([=" ])\/D/$1-D/gs;
  1322. print $_;
  1323. print
  1324. "\n".
  1325. "# You can define this path to point at your tools if you need to\n".
  1326. "# TOOLPATH = /opt/gcc/bin\n".
  1327. "CC = \$(TOOLPATH)cc\n".
  1328. "# If necessary set the path to krb5-config here\n".
  1329. "KRB5CONFIG=krb5-config\n".
  1330. "# You can manually set this to `gtk-config' or `pkg-config gtk+-1.2'\n".
  1331. "# (depending on what works on your system) if you want to enforce\n".
  1332. "# building with GTK 1.2, or you can set it to `pkg-config gtk+-2.0 x11'\n".
  1333. "# if you want to enforce 2.0. The default is to try 2.0 and fall back\n".
  1334. "# to 1.2 if it isn't found.\n".
  1335. "GTK_CONFIG = sh -c 'pkg-config gtk+-3.0 x11 \$\$0 2>/dev/null || pkg-config gtk+-2.0 x11 \$\$0 2>/dev/null || gtk-config \$\$0'\n".
  1336. "\n".
  1337. "-include Makefile.local\n".
  1338. "\n".
  1339. "unexport CFLAGS # work around a weird issue with krb5-config\n".
  1340. "\n".
  1341. &splitline("CFLAGS = -O2 -Wall -std=gnu99 -Wvla -g " .
  1342. (join " ", map {"-I$dirpfx$_"} @srcdirs) .
  1343. " \$(shell \$(GTK_CONFIG) --cflags)").
  1344. " -D _FILE_OFFSET_BITS=64\n".
  1345. "XLDFLAGS = \$(LDFLAGS) \$(shell \$(GTK_CONFIG) --libs)\n".
  1346. "ULDFLAGS = \$(LDFLAGS)\n".
  1347. "ifeq (,\$(findstring NO_GSSAPI,\$(COMPAT)))\n".
  1348. "ifeq (,\$(findstring STATIC_GSSAPI,\$(COMPAT)))\n".
  1349. "XLDFLAGS+= -ldl\n".
  1350. "ULDFLAGS+= -ldl\n".
  1351. "else\n".
  1352. "CFLAGS+= -DNO_LIBDL \$(shell \$(KRB5CONFIG) --cflags gssapi)\n".
  1353. "XLDFLAGS+= \$(shell \$(KRB5CONFIG) --libs gssapi)\n".
  1354. "ULDFLAGS+= \$(shell \$(KRB5CONFIG) --libs gssapi)\n".
  1355. "endif\n".
  1356. "endif\n".
  1357. "INSTALL=install\n".
  1358. "INSTALL_PROGRAM=\$(INSTALL)\n".
  1359. "INSTALL_DATA=\$(INSTALL)\n".
  1360. "prefix=/usr/local\n".
  1361. "exec_prefix=\$(prefix)\n".
  1362. "bindir=\$(exec_prefix)/bin\n".
  1363. "mandir=\$(prefix)/man\n".
  1364. "man1dir=\$(mandir)/man1\n".
  1365. "\n".
  1366. &def($makefile_extra{'gtk'}->{'vars'}) .
  1367. "\n".
  1368. ".SUFFIXES:\n".
  1369. "\n".
  1370. "\n";
  1371. print &splitline("all:" . join "", map { " $_" }
  1372. &progrealnames("X:XT:U:UT"));
  1373. print "\n\n";
  1374. foreach $p (&prognames("X:XT:U:UT")) {
  1375. ($prog, $type) = split ",", $p;
  1376. ($ldflags = $type) =~ s/T$//;
  1377. $objstr = &objects($p, "X.o", undef, undef);
  1378. print &splitline($prog . ": " . $objstr), "\n";
  1379. $libstr = &objects($p, undef, undef, "-lX");
  1380. print &splitline("\t\$(CC) -o \$@ " .
  1381. $objstr . " \$(${ldflags}LDFLAGS) $libstr", 69), "\n\n";
  1382. }
  1383. foreach $d (&deps("X.o", undef, $dirpfx, "/", "gtk")) {
  1384. if ($forceobj{$d->{obj_orig}}) {
  1385. printf("%s: FORCE\n", $d->{obj});
  1386. } else {
  1387. print &splitline(sprintf("%s: %s", $d->{obj},
  1388. join " ", @{$d->{deps}})), "\n";
  1389. }
  1390. print &splitline("\t\$(CC) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) -c $d->{deps}->[0]\n");
  1391. }
  1392. print "\n";
  1393. print &def($makefile_extra{'gtk'}->{'end'});
  1394. print "\nclean:\n".
  1395. "\trm -f *.o". (join "", map { " $_" } &progrealnames("X:XT:U:UT")) . "\n";
  1396. print "\nFORCE:\n";
  1397. select STDOUT; close OUT;
  1398. }
  1399. if (defined $makefiles{'unix'}) {
  1400. $dirpfx = &dirpfx($makefiles{'unix'}, "/");
  1401. ##-- GTK-free pure-Unix makefile for non-GUI apps only
  1402. open OUT, ">$makefiles{'unix'}"; select OUT;
  1403. print
  1404. "# Makefile for $project_name under Unix.\n".
  1405. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  1406. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  1407. # gcc command line option is -D not /D
  1408. ($_ = $help) =~ s/([=" ])\/D/$1-D/gs;
  1409. print $_;
  1410. print
  1411. "\n".
  1412. "# You can define this path to point at your tools if you need to\n".
  1413. "# TOOLPATH = /opt/gcc/bin\n".
  1414. "CC = \$(TOOLPATH)cc\n".
  1415. "\n".
  1416. "-include Makefile.local\n".
  1417. "\n".
  1418. "unexport CFLAGS # work around a weird issue with krb5-config\n".
  1419. "\n".
  1420. &splitline("CFLAGS = -O2 -Wall -std=gnu99 -Wvla -g " .
  1421. (join " ", map {"-I$dirpfx$_"} @srcdirs)).
  1422. " -D _FILE_OFFSET_BITS=64\n".
  1423. "ULDFLAGS = \$(LDFLAGS)\n".
  1424. "INSTALL=install\n".
  1425. "INSTALL_PROGRAM=\$(INSTALL)\n".
  1426. "INSTALL_DATA=\$(INSTALL)\n".
  1427. "prefix=/usr/local\n".
  1428. "exec_prefix=\$(prefix)\n".
  1429. "bindir=\$(exec_prefix)/bin\n".
  1430. "mandir=\$(prefix)/man\n".
  1431. "man1dir=\$(mandir)/man1\n".
  1432. "\n".
  1433. &def($makefile_extra{'unix'}->{'vars'}) .
  1434. "\n".
  1435. ".SUFFIXES:\n".
  1436. "\n".
  1437. "\n";
  1438. print &splitline("all:" . join "", map { " $_" } &progrealnames("U:UT"));
  1439. print "\n\n";
  1440. foreach $p (&prognames("U:UT")) {
  1441. ($prog, $type) = split ",", $p;
  1442. ($ldflags = $type) =~ s/T$//;
  1443. $objstr = &objects($p, "X.o", undef, undef);
  1444. print &splitline($prog . ": " . $objstr), "\n";
  1445. $libstr = &objects($p, undef, undef, "-lX");
  1446. print &splitline("\t\$(CC) -o \$@ " .
  1447. $objstr . " \$(${ldflags}LDFLAGS) $libstr", 69), "\n\n";
  1448. }
  1449. foreach $d (&deps("X.o", undef, $dirpfx, "/", "unix")) {
  1450. if ($forceobj{$d->{obj_orig}}) {
  1451. printf("%s: FORCE\n", $d->{obj});
  1452. } else {
  1453. print &splitline(sprintf("%s: %s", $d->{obj},
  1454. join " ", @{$d->{deps}})), "\n";
  1455. }
  1456. print &splitline("\t\$(CC) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) -c $d->{deps}->[0]\n");
  1457. }
  1458. print "\n";
  1459. print &def($makefile_extra{'unix'}->{'end'});
  1460. print "\nclean:\n".
  1461. "\trm -f *.o". (join "", map { " $_" } &progrealnames("U:UT")) . "\n";
  1462. print "\nFORCE:\n";
  1463. select STDOUT; close OUT;
  1464. }
  1465. if (defined $makefiles{'am'}) {
  1466. die "Makefile.am in a subdirectory is not supported\n"
  1467. if &dirpfx($makefiles{'am'}, "/") ne "";
  1468. ##-- Unix/autoconf Makefile.am
  1469. open OUT, ">$makefiles{'am'}"; select OUT;
  1470. print
  1471. "# Makefile.am for $project_name under Unix with Autoconf/Automake.\n".
  1472. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  1473. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n\n";
  1474. # 2014-02-22: as of automake-1.14 we begin to get complained at if
  1475. # we don't use this option
  1476. print "AUTOMAKE_OPTIONS = subdir-objects\n\n";
  1477. # Complete list of source and header files. Not used by the
  1478. # auto-generated parts of this makefile, but Recipe might like to
  1479. # have it available as a variable so that mandatory-rebuild things
  1480. # (version.o) can conveniently be made to depend on it.
  1481. @sources = ("allsources", "=",
  1482. sort grep {$_ ne "empty.h"} keys %allsourcefiles);
  1483. print &splitline(join " ", @sources), "\n\n";
  1484. @cliprogs = ("bin_PROGRAMS", "=");
  1485. foreach $p (&prognames("U")) {
  1486. ($prog, $type) = split ",", $p;
  1487. push @cliprogs, $prog;
  1488. }
  1489. @allprogs = @cliprogs;
  1490. foreach $p (&prognames("X")) {
  1491. ($prog, $type) = split ",", $p;
  1492. push @allprogs, $prog;
  1493. }
  1494. print "if HAVE_GTK\n";
  1495. print &splitline(join " ", @allprogs), "\n";
  1496. print "else\n";
  1497. print &splitline(join " ", @cliprogs), "\n";
  1498. print "endif\n\n";
  1499. @noinstcliprogs = ("noinst_PROGRAMS", "=");
  1500. foreach $p (&prognames("UT")) {
  1501. ($prog, $type) = split ",", $p;
  1502. push @noinstcliprogs, $prog;
  1503. }
  1504. @noinstallprogs = @noinstcliprogs;
  1505. foreach $p (&prognames("XT")) {
  1506. ($prog, $type) = split ",", $p;
  1507. push @noinstallprogs, $prog;
  1508. }
  1509. print "if HAVE_GTK\n";
  1510. print &splitline(join " ", @noinstallprogs), "\n";
  1511. print "else\n";
  1512. print &splitline(join " ", @noinstcliprogs), "\n";
  1513. print "endif\n\n";
  1514. %objtosrc = ();
  1515. foreach $d (&deps("X", undef, "", "/", "am")) {
  1516. $objtosrc{$d->{obj}} = $d->{deps}->[0];
  1517. }
  1518. print &splitline(join " ", "AM_CPPFLAGS", "=",
  1519. map {"-I\$(srcdir)/$_"} @srcdirs), "\n";
  1520. @amcflags = ("\$(COMPAT)", "\$(XFLAGS)", "\$(WARNINGOPTS)");
  1521. print "if HAVE_GTK\n";
  1522. print &splitline(join " ", "AM_CFLAGS", "=",
  1523. "\$(GTK_CFLAGS)", @amcflags), "\n";
  1524. print "else\n";
  1525. print &splitline(join " ", "AM_CFLAGS", "=", @amcflags), "\n";
  1526. print "endif\n\n";
  1527. %amspeciallibs = ();
  1528. foreach $obj (sort { $a cmp $b } keys %{$cflags{'am'}}) {
  1529. my $flags = $cflags{'am'}->{$obj};
  1530. $flags = "" if $flags !~ s/^C//;
  1531. print "lib${obj}_a_SOURCES = ", $objtosrc{$obj}, "\n";
  1532. print &splitline(join " ", "lib${obj}_a_CFLAGS", "=", @amcflags,
  1533. $flags), "\n";
  1534. $amspeciallibs{$obj} = "lib${obj}.a";
  1535. }
  1536. print &splitline(join " ", "noinst_LIBRARIES", "=",
  1537. sort { $a cmp $b } values %amspeciallibs), "\n\n";
  1538. foreach $p (&prognames("X:XT:U:UT")) {
  1539. ($prog, $type) = split ",", $p;
  1540. print "if HAVE_GTK\n" if $type eq "X" || $type eq "XT";
  1541. @progsources = ("${prog}_SOURCES", "=");
  1542. %sourcefiles = ();
  1543. @ldadd = ();
  1544. $objstr = &objects($p, "X", undef, undef);
  1545. foreach $obj (split / /,$objstr) {
  1546. if ($amspeciallibs{$obj}) {
  1547. push @ldadd, $amspeciallibs{$obj};
  1548. } else {
  1549. $sourcefiles{$objtosrc{$obj}} = 1;
  1550. }
  1551. }
  1552. push @progsources, sort { $a cmp $b } keys %sourcefiles;
  1553. print &splitline(join " ", @progsources), "\n";
  1554. if ($type eq "X" || $type eq "XT") {
  1555. push @ldadd, "\$(GTK_LIBS)";
  1556. }
  1557. if (@ldadd) {
  1558. print &splitline(join " ", "${prog}_LDADD", "=", @ldadd), "\n";
  1559. }
  1560. print "endif\n" if $type eq "X" || $type eq "XT";
  1561. print "\n";
  1562. }
  1563. print &def($makefile_extra{'am'}->{'end'});
  1564. select STDOUT; close OUT;
  1565. }
  1566. if (defined $makefiles{'lcc'}) {
  1567. $dirpfx = &dirpfx($makefiles{'lcc'}, "\\");
  1568. ##-- lcc makefile
  1569. open OUT, ">$makefiles{'lcc'}"; select OUT;
  1570. print
  1571. "# Makefile for $project_name under lcc.\n".
  1572. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  1573. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  1574. # lcc command line option is -D not /D
  1575. ($_ = $help) =~ s/([=" ])\/D/$1-D/gs;
  1576. print $_;
  1577. print
  1578. "\n".
  1579. "# If you rename this file to `Makefile', you should change this line,\n".
  1580. "# so that the .rsp files still depend on the correct makefile.\n".
  1581. "MAKEFILE = Makefile.lcc\n".
  1582. "\n".
  1583. "# C compilation flags\n".
  1584. "CFLAGS = -D_WINDOWS " .
  1585. (join " ", map {"-I$dirpfx$_"} @srcdirs) .
  1586. "\n".
  1587. "# Resource compilation flags\n".
  1588. "RCFLAGS = ".(join " ", map {"-I$dirpfx$_"} @srcdirs)."\n".
  1589. "\n".
  1590. "# Get include directory for resource compiler\n".
  1591. "\n".
  1592. &def($makefile_extra{'lcc'}->{'vars'}) .
  1593. "\n";
  1594. print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
  1595. print "\n\n";
  1596. foreach $p (&prognames("G:C")) {
  1597. ($prog, $type) = split ",", $p;
  1598. $objstr = &objects($p, "X.obj", "X.res", undef);
  1599. print &splitline("$prog.exe: " . $objstr ), "\n";
  1600. $subsystemtype = '';
  1601. if ($type eq "G") { $subsystemtype = "-subsystem windows"; }
  1602. my $libss = "shell32.lib wsock32.lib ws2_32.lib winspool.lib winmm.lib imm32.lib";
  1603. print &splitline("\tlcclnk $subsystemtype -o $prog.exe $objstr $libss");
  1604. print "\n\n";
  1605. }
  1606. foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\", "lcc")) {
  1607. if ($forceobj{$d->{obj_orig}}) {
  1608. printf("%s: FORCE\n", $d->{obj});
  1609. } else {
  1610. print &splitline(sprintf("%s: %s", $d->{obj},
  1611. join " ", @{$d->{deps}})), "\n";
  1612. }
  1613. if ($d->{obj} =~ /\.obj$/) {
  1614. print &splitline("\tlcc -O -p6 \$(COMPAT)".
  1615. " \$(CFLAGS) \$(XFLAGS) ".$d->{deps}->[0],69)."\n";
  1616. } else {
  1617. print &splitline("\tlrc \$(RCFL) -r \$(RCFLAGS) ".
  1618. $d->{deps}->[0],69)."\n";
  1619. }
  1620. }
  1621. print "\n";
  1622. print &def($makefile_extra{'lcc'}->{'end'});
  1623. print "\nclean:\n".
  1624. "\t-del *.obj\n".
  1625. "\t-del *.exe\n".
  1626. "\t-del *.res\n".
  1627. "\n".
  1628. "FORCE:\n";
  1629. select STDOUT; close OUT;
  1630. }
  1631. if (defined $makefiles{'osx'}) {
  1632. $dirpfx = &dirpfx($makefiles{'osx'}, "/");
  1633. ##-- Mac OS X makefile
  1634. open OUT, ">$makefiles{'osx'}"; select OUT;
  1635. print
  1636. "# Makefile for $project_name under Mac OS X.\n".
  1637. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  1638. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  1639. # gcc command line option is -D not /D
  1640. ($_ = $help) =~ s/([=" ])\/D/$1-D/gs;
  1641. print $_;
  1642. print
  1643. "CC = \$(TOOLPATH)gcc\n".
  1644. "\n".
  1645. &splitline("CFLAGS = -O2 -Wall -std=gnu99 -Wvla -g " .
  1646. (join " ", map {"-I$dirpfx$_"} @srcdirs))."\n".
  1647. "MLDFLAGS = -framework Cocoa\n".
  1648. "ULDFLAGS =\n".
  1649. "\n" .
  1650. &def($makefile_extra{'osx'}->{'vars'}) .
  1651. "\n" .
  1652. &splitline("all:" . join "", map { " $_" } &progrealnames("MX:U:UT")) .
  1653. "\n";
  1654. foreach $p (&prognames("MX")) {
  1655. ($prog, $type) = split ",", $p;
  1656. $objstr = &objects($p, "X.o", undef, undef);
  1657. $icon = &special($p, ".icns");
  1658. $infoplist = &special($p, "info.plist");
  1659. print "${prog}.app:\n\tmkdir -p \$\@\n";
  1660. print "${prog}.app/Contents: ${prog}.app\n\tmkdir -p \$\@\n";
  1661. print "${prog}.app/Contents/MacOS: ${prog}.app/Contents\n\tmkdir -p \$\@\n";
  1662. $targets = "${prog}.app/Contents/MacOS/$prog";
  1663. if (defined $icon) {
  1664. print "${prog}.app/Contents/Resources: ${prog}.app/Contents\n\tmkdir -p \$\@\n";
  1665. print "${prog}.app/Contents/Resources/${prog}.icns: ${prog}.app/Contents/Resources $icon\n\tcp $icon \$\@\n";
  1666. $targets .= " ${prog}.app/Contents/Resources/${prog}.icns";
  1667. }
  1668. if (defined $infoplist) {
  1669. print "${prog}.app/Contents/Info.plist: ${prog}.app/Contents/Resources $infoplist\n\tcp $infoplist \$\@\n";
  1670. $targets .= " ${prog}.app/Contents/Info.plist";
  1671. }
  1672. $targets .= " \$(${prog}_extra)";
  1673. print &splitline("${prog}: $targets", 69) . "\n\n";
  1674. print &splitline("${prog}.app/Contents/MacOS/$prog: ".
  1675. "${prog}.app/Contents/MacOS " . $objstr), "\n";
  1676. $libstr = &objects($p, undef, undef, "-lX");
  1677. print &splitline("\t\$(CC) \$(MLDFLAGS) -o \$@ " .
  1678. $objstr . " $libstr", 69), "\n\n";
  1679. }
  1680. foreach $p (&prognames("U:UT")) {
  1681. ($prog, $type) = split ",", $p;
  1682. $objstr = &objects($p, "X.o", undef, undef);
  1683. print &splitline($prog . ": " . $objstr), "\n";
  1684. $libstr = &objects($p, undef, undef, "-lX");
  1685. print &splitline("\t\$(CC) \$(ULDFLAGS) -o \$@ " .
  1686. $objstr . " $libstr", 69), "\n\n";
  1687. }
  1688. foreach $d (&deps("X.o", undef, $dirpfx, "/", "osx")) {
  1689. if ($forceobj{$d->{obj_orig}}) {
  1690. printf("%s: FORCE\n", $d->{obj});
  1691. } else {
  1692. print &splitline(sprintf("%s: %s", $d->{obj},
  1693. join " ", @{$d->{deps}})), "\n";
  1694. }
  1695. $firstdep = $d->{deps}->[0];
  1696. if ($firstdep =~ /\.c$/) {
  1697. print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS) -c \$<\n";
  1698. } elsif ($firstdep =~ /\.m$/) {
  1699. print "\t\$(CC) -x objective-c \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS) -c \$<\n";
  1700. }
  1701. }
  1702. print "\n".&def($makefile_extra{'osx'}->{'end'});
  1703. print "\nclean:\n".
  1704. "\trm -f *.o *.dmg". (join "", map { " $_" } &progrealnames("U:UT")) . "\n".
  1705. "\trm -rf *.app\n".
  1706. "\n".
  1707. "FORCE:\n";
  1708. select STDOUT; close OUT;
  1709. }
  1710. if (defined $makefiles{'devcppproj'}) {
  1711. $dirpfx = &dirpfx($makefiles{'devcppproj'}, "\\");
  1712. $orig_dir = cwd;
  1713. ##-- Dev-C++ 5 projects
  1714. #
  1715. # Note: All files created in this section are written in binary
  1716. # mode to prevent any posibility of misinterpreted line endings.
  1717. # I don't know if Dev-C++ is as touchy as MSVC with LF-only line
  1718. # endings. But however, CRLF line endings are the common way on
  1719. # Win32 machines where Dev-C++ is running.
  1720. # Hence, in order for mkfiles.pl to generate CRLF project files
  1721. # even when run from Unix, I make sure all files are binary and
  1722. # explicitly write the CRLFs.
  1723. #
  1724. # Create directories if necessary
  1725. mkdir $makefiles{'devcppproj'}
  1726. if(! -d $makefiles{'devcppproj'});
  1727. chdir $makefiles{'devcppproj'};
  1728. @deps = &deps("X.obj", "X.res", $dirpfx, "\\", "devcppproj");
  1729. %all_object_deps = map {$_->{obj} => $_->{deps}} @deps;
  1730. # Make dir names FAT/NTFS compatible
  1731. my @srcdirs = @srcdirs;
  1732. for ($i=0; $i<@srcdirs; $i++) {
  1733. $srcdirs[$i] =~ s/\//\\/g;
  1734. $srcdirs[$i] =~ s/\\$//;
  1735. }
  1736. # Create the project files
  1737. # Get names of all Windows projects (GUI and console)
  1738. my @prognames = &prognames("G:C");
  1739. foreach $progname (@prognames) {
  1740. create_devcpp_project(\%all_object_deps, $progname);
  1741. }
  1742. chdir $orig_dir;
  1743. sub create_devcpp_project {
  1744. my ($all_object_deps, $progname) = @_;
  1745. # Construct program's dependency info (Taken from 'vcproj', seems to work right here, too.)
  1746. %seen_objects = ();
  1747. %lib_files = ();
  1748. %source_files = ();
  1749. %header_files = ();
  1750. %resource_files = ();
  1751. @object_files = split " ", &objects($progname, "X.obj", "X.res", "X.lib");
  1752. foreach $object_file (@object_files) {
  1753. next if defined $seen_objects{$object_file};
  1754. $seen_objects{$object_file} = 1;
  1755. if($object_file =~ /\.lib$/io) {
  1756. $lib_files{$object_file} = 1;
  1757. next;
  1758. }
  1759. $object_deps = $all_object_deps{$object_file};
  1760. foreach $object_dep (@$object_deps) {
  1761. if($object_dep =~ /\.c$/io) {
  1762. $source_files{$object_dep} = 1;
  1763. next;
  1764. }
  1765. if($object_dep =~ /\.h$/io) {
  1766. $header_files{$object_dep} = 1;
  1767. next;
  1768. }
  1769. if($object_dep =~ /\.(rc|ico)$/io) {
  1770. $resource_files{$object_dep} = 1;
  1771. next;
  1772. }
  1773. }
  1774. }
  1775. $libs = join " ", sort keys %lib_files;
  1776. @source_files = sort keys %source_files;
  1777. @header_files = sort keys %header_files;
  1778. @resources = sort keys %resource_files;
  1779. ($windows_project, $type) = split ",", $progname;
  1780. mkdir $windows_project
  1781. if(! -d $windows_project);
  1782. chdir $windows_project;
  1783. $subsys = ($type eq "G") ? "0" : "1"; # 0 = Win32 GUI, 1 = Win32 Console
  1784. open OUT, ">$windows_project.dev"; binmode OUT; select OUT;
  1785. print
  1786. "# DEV-C++ 5 Project File - $windows_project.dev\r\n".
  1787. "# ** DO NOT EDIT **\r\n".
  1788. "\r\n".
  1789. # No difference between DEBUG and RELEASE here as in 'vcproj', because
  1790. # Dev-C++ does not support multiple compilation profiles in one single project.
  1791. # (At least I can say this for Dev-C++ 5 Beta)
  1792. "[Project]\r\n".
  1793. "FileName=$windows_project.dev\r\n".
  1794. "Name=$windows_project\r\n".
  1795. "Ver=1\r\n".
  1796. "IsCpp=1\r\n".
  1797. "Type=$subsys\r\n".
  1798. # Multimon is disabled here, as Dev-C++ (Version 5 Beta) does not have multimon.h
  1799. "Compiler=-W -D__GNUWIN32__ -DWIN32 -DNDEBUG -D_WINDOWS -DNO_MULTIMON -D_MBCS_\@\@_\r\n".
  1800. "CppCompiler=-W -D__GNUWIN32__ -DWIN32 -DNDEBUG -D_WINDOWS -DNO_MULTIMON -D_MBCS_\@\@_\r\n".
  1801. "Includes=" . (join ";", map {"..\\..\\$dirpfx$_"} @srcdirs) . "\r\n".
  1802. "Linker=-ladvapi32 -lcomctl32 -lcomdlg32 -lgdi32 -limm32 -lshell32 -luser32 -lwinmm -lwinspool_\@\@_\r\n".
  1803. "Libs=\r\n".
  1804. "UnitCount=" . (@source_files + @header_files + @resources) . "\r\n".
  1805. "Folders=\"Header Files\",\"Resource Files\",\"Source Files\"\r\n".
  1806. "ObjFiles=\r\n".
  1807. "PrivateResource=${windows_project}_private.rc\r\n".
  1808. "ResourceIncludes=..\\..\\..\\WINDOWS\r\n".
  1809. "MakeIncludes=\r\n".
  1810. "Icon=\r\n". # It's ok to leave this blank.
  1811. "ExeOutput=\r\n".
  1812. "ObjectOutput=\r\n".
  1813. "OverrideOutput=0\r\n".
  1814. "OverrideOutputName=$windows_project.exe\r\n".
  1815. "HostApplication=\r\n".
  1816. "CommandLine=\r\n".
  1817. "UseCustomMakefile=0\r\n".
  1818. "CustomMakefile=\r\n".
  1819. "IncludeVersionInfo=0\r\n".
  1820. "SupportXPThemes=0\r\n".
  1821. "CompilerSet=0\r\n".
  1822. "CompilerSettings=0000000000000000000000\r\n".
  1823. "\r\n";
  1824. $unit_count = 1;
  1825. foreach $source_file (@source_files) {
  1826. print
  1827. "[Unit$unit_count]\r\n".
  1828. "FileName=..\\..\\$source_file\r\n".
  1829. "Folder=Source Files\r\n".
  1830. "Compile=1\r\n".
  1831. "CompileCpp=0\r\n".
  1832. "Link=1\r\n".
  1833. "Priority=1000\r\n".
  1834. "OverrideBuildCmd=0\r\n".
  1835. "BuildCmd=\r\n".
  1836. "\r\n";
  1837. $unit_count++;
  1838. }
  1839. foreach $header_file (@header_files) {
  1840. print
  1841. "[Unit$unit_count]\r\n".
  1842. "FileName=..\\..\\$header_file\r\n".
  1843. "Folder=Header Files\r\n".
  1844. "Compile=1\r\n".
  1845. "CompileCpp=1\r\n". # Dev-C++ want's to compile all header files with both compilers C and C++. It does not hurt.
  1846. "Link=1\r\n".
  1847. "Priority=1000\r\n".
  1848. "OverrideBuildCmd=0\r\n".
  1849. "BuildCmd=\r\n".
  1850. "\r\n";
  1851. $unit_count++;
  1852. }
  1853. foreach $resource_file (@resources) {
  1854. if ($resource_file =~ /.*\.(ico|cur|bmp|dlg|rc2|rct|bin|rgs|gif|jpg|jpeg|jpe)/io) { # Default filter as in 'vcproj'
  1855. $Compile = "0"; # Don't compile images and other binary resource files
  1856. $CompileCpp = "0";
  1857. } else {
  1858. $Compile = "1";
  1859. $CompileCpp = "1"; # Dev-C++ want's to compile all .rc files with both compilers C and C++. It does not hurt.
  1860. }
  1861. print
  1862. "[Unit$unit_count]\r\n".
  1863. "FileName=..\\..\\$resource_file\r\n".
  1864. "Folder=Resource Files\r\n".
  1865. "Compile=$Compile\r\n".
  1866. "CompileCpp=$CompileCpp\r\n".
  1867. "Link=0\r\n".
  1868. "Priority=1000\r\n".
  1869. "OverrideBuildCmd=0\r\n".
  1870. "BuildCmd=\r\n".
  1871. "\r\n";
  1872. $unit_count++;
  1873. }
  1874. #Note: By default, [VersionInfo] is not used.
  1875. print
  1876. "[VersionInfo]\r\n".
  1877. "Major=0\r\n".
  1878. "Minor=0\r\n".
  1879. "Release=1\r\n".
  1880. "Build=1\r\n".
  1881. "LanguageID=1033\r\n".
  1882. "CharsetID=1252\r\n".
  1883. "CompanyName=\r\n".
  1884. "FileVersion=0.1\r\n".
  1885. "FileDescription=\r\n".
  1886. "InternalName=\r\n".
  1887. "LegalCopyright=\r\n".
  1888. "LegalTrademarks=\r\n".
  1889. "OriginalFilename=$windows_project.exe\r\n".
  1890. "ProductName=$windows_project\r\n".
  1891. "ProductVersion=0.1\r\n".
  1892. "AutoIncBuildNr=0\r\n";
  1893. select STDOUT; close OUT;
  1894. chdir "..";
  1895. }
  1896. }
  1897. # All done, so do the Unix postprocessing if asked to.
  1898. if ($do_unix) {
  1899. chdir $orig_dir;
  1900. system "./mkauto.sh";
  1901. die "mkfiles.pl: mkauto.sh returned $?\n" if $? > 0;
  1902. if ($do_unix == 1) {
  1903. chdir ($targetdir = "unix")
  1904. or die "$targetdir: chdir: $!\n";
  1905. }
  1906. system "./configure", @confargs;
  1907. die "mkfiles.pl: configure returned $?\n" if $? > 0;
  1908. }
  1909. sub invent_guid($) {
  1910. my ($name) = @_;
  1911. # Invent a GUID for use in Visual Studio project files. We need
  1912. # a few of these for every executable file we build.
  1913. #
  1914. # In order to avoid having to use the non-core Perl module
  1915. # Data::GUID, and also arrange for GUIDs to be stable, we generate
  1916. # our GUIDs by hashing a pile of fixed (but originally randomly
  1917. # generated) data with the filename for which we need an id.
  1918. #
  1919. # Hashing _just_ the filenames would clearly be cheating (it's
  1920. # quite conceivable that someone might hash the same string for
  1921. # another reason and so generate a colliding GUID), but hashing a
  1922. # whole SHA-512 data block of random gibberish as well should make
  1923. # these GUIDs pseudo-random enough to not collide with anyone
  1924. # else's.
  1925. my $randdata = pack "N*",
  1926. 0xD4AB035F,0x76998BA0,0x2DCCB0BD,0x6D3FA320,0x53638051,0xFE312F35,
  1927. 0xDE1CECC0,0x784DF852,0x6C9F4589,0x54B7AC23,0x14E7A1C4,0xF9BF04DF,
  1928. 0x19C08B6D,0x3FB69EF1,0xB2DA9043,0xDB5362F3,0x25718DB6,0x733560DA,
  1929. 0xFEF871B0,0xFECF7A0C,0x67D19C95,0xB492E911,0xF5D562A3,0xFCE1D478,
  1930. 0x02C50434,0xF7326B7E,0x93D39872,0xCF0D0269,0x9EF24C0F,0x827689AD,
  1931. 0x88BD20BC,0x74EA6AFE,0x29223682,0xB9AB9287,0x7EA7CE4F,0xCF81B379,
  1932. 0x9AE4A954,0x81C7AD97,0x2FF2F031,0xC51DA3C2,0xD311CCE7,0x0A31EB8B,
  1933. 0x1AB04242,0xAF53B714,0xFC574D40,0x8CB4ED01,0x29FEB16F,0x4904D7ED,
  1934. 0xF5C5F5E1,0xF138A4C2,0xA9D881CE,0xCEA65187,0x4421BA97,0x0EE8428E,
  1935. 0x9556E384,0x6D0484C9,0x561BD84B,0xD9516A40,0x6B4FD33F,0xDDFFE4C8,
  1936. 0x3D5DF8A5,0xFE6B7D99,0x3443371B,0xF4E30A3E,0xE62B9FDA,0x6BAA75DB,
  1937. 0x9EF3C2C7,0x6815CA42,0xE6536076,0xF851E6E2,0x39D16E69,0xBCDF3BB6,
  1938. 0x50EFFA41,0x378CDF2A,0xB5EC0D0C,0x1E94C433,0xE818241A,0x2689EB1F,
  1939. 0xB649CEF9,0xD7344D46,0x59C1BB13,0x27511FDF,0x7DAD1768,0xB355E29E,
  1940. 0xDFAE550C,0x2433005B,0x09DE10B0,0xAA00BA6B,0xC144ED2D,0x8513D007,
  1941. 0xB0315232,0x7A10DAB6,0x1D97654E,0xF048214D,0xE3059E75,0x83C225D1,
  1942. 0xFC7AB177,0x83F2B553,0x79F7A0AF,0x1C94582C,0xF5E4AF4B,0xFB39C865,
  1943. 0x58ABEB27,0xAAB28058,0x52C15A89,0x0EBE9741,0x343F4D26,0xF941202A,
  1944. 0xA32FD32F,0xDCC055B8,0x64281BF3,0x468BD7BA,0x0CEE09D3,0xBB5FD2B6,
  1945. 0xA528D412,0xA6A6967E,0xEAAF5DAE,0xDE7B2FAE,0xCA36887B,0x0DE196EB,
  1946. 0x74B95EF0,0x9EB8B7C2,0x020BFC83,0x1445086F,0xBF4B61B2,0x89AFACEC,
  1947. 0x80A5CD69,0xC790F744,0x435A6998,0x8DE7AC48,0x32F31BC9,0x8F760D3D,
  1948. 0xF02A74CB,0xD7B47E20,0x9EC91035,0x70FDE74D,0x9B531362,0x9D81739A,
  1949. 0x59ADC2EB,0x511555B5,0xCA84B8D5,0x3EC325FF,0x2E442A4C,0x82AF30D9,
  1950. 0xBFD3EC87,0x90C59E07,0x1C6DC991,0x2D16B822,0x7EA44EB5,0x3A655A39,
  1951. 0xAB640886,0x09311821,0x777801D9,0x489DBE61,0xA1FFEC65,0x978B49B1,
  1952. 0x7DB700CD,0x263CF3D6,0xF977E89F,0xBA0B3D01,0x6C6CED19,0x1BE6F23A,
  1953. 0x19E0ED98,0x8E71A499,0x70BA3271,0x3FB7EE98,0xABA46848,0x2B797959,
  1954. 0x72C6DE59,0xE08B795C,0x02936C39,0x02185CCB,0xD6F3CE18,0xD0157A40,
  1955. 0x833DEC3F,0x319B00C4,0x97B59513,0x900B81FD,0x9A022379,0x16E44E1A,
  1956. 0x0C4CC540,0xCA98E7F9,0xF9431A26,0x290BCFAC,0x406B82C0,0xBC1C4585,
  1957. 0x55C54528,0x811EBB77,0xD4EDD4F3,0xA70DC02E,0x8AD5C0D1,0x28D64EF4,
  1958. 0xBEFF5C69,0x99852C4A,0xB4BBFF7B,0x069230AC,0xA3E141FA,0x4E99FB0E,
  1959. 0xBC154DAA,0x323C7F15,0x86E0247E,0x2EEA3054,0xC9CA1D32,0x8964A006,
  1960. 0xC93978AC,0xF9B2C159,0x03F2079E,0xB051D284,0x4A7EA9A9,0xF001DA1F,
  1961. 0xD47A0DAA,0xCF7B6B73,0xF18293B2,0x84303E34,0xF8BC76C4,0xAFBEE24F,
  1962. 0xB589CA80,0x77B5BF86,0x21B9FD5B,0x1A5071DF,0xA3863110,0x0E50CA61,
  1963. 0x939151A5,0xD2A59021,0x83A9CDCE,0xCEC69767,0xC906BB16,0x3EE1FF4D,
  1964. 0x1321EAE4,0x0BF940D6,0x52471E61,0x8A087056,0x66E54293,0xF84AAB9B,
  1965. 0x08835EF1,0x8F12B77A,0xD86935A5,0x200281D7,0xCD3C37C9,0x30ABEC05,
  1966. 0x7067E8A0,0x608C4838,0xC9F51CDE,0xA6D318DE,0x41C05B2A,0x694CCE0E,
  1967. 0xC7842451,0xA3194393,0xFBDC2C84,0xA6D2B577,0xC91E7924,0x01EDA708,
  1968. 0x22FBB61E,0x662F9B7B,0xDE3150C3,0x2397058C;
  1969. my $digest = sha512_hex($name . "\0" . $randdata);
  1970. return sprintf("%s-%s-%04x-%04x-%s",
  1971. substr($digest,0,8),
  1972. substr($digest,8,4),
  1973. 0x4000 | (0xFFF & hex(substr($digest,12,4))),
  1974. 0x8000 | (0x3FFF & hex(substr($digest,16,4))),
  1975. substr($digest,20,12));
  1976. }