mkfiles.pl 77 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029
  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] 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] 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","borland","lcc","devcppproj","gtk","unix",
  251. "am","osx","vstudio10","vstudio12")) {
  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{'cygwin'}) {
  405. $dirpfx = &dirpfx($makefiles{'cygwin'}, "/");
  406. ##-- MinGW/CygWin makefile (called 'cygwin' for historical reasons)
  407. open OUT, ">$makefiles{'cygwin'}"; select OUT;
  408. print
  409. "# Makefile for $project_name under MinGW, Cygwin, or Winelib.\n".
  410. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  411. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  412. # gcc command line option is -D not /D
  413. ($_ = $help) =~ s/([=" ])\/D/$1-D/gs;
  414. print $_;
  415. print
  416. "\n".
  417. "# You can define this path to point at your tools if you need to\n".
  418. "# TOOLPATH = c:\\cygwin\\bin\\ # or similar, if you're running Windows\n".
  419. "# TOOLPATH = /pkg/mingw32msvc/i386-mingw32msvc/bin/\n".
  420. "# TOOLPATH = i686-w64-mingw32-\n".
  421. "CC = \$(TOOLPATH)gcc\n".
  422. "RC = \$(TOOLPATH)windres\n".
  423. "# Uncomment the following two lines to compile under Winelib\n".
  424. "# CC = winegcc\n".
  425. "# RC = wrc\n".
  426. "# You may also need to tell windres where to find include files:\n".
  427. "# RCINC = --include-dir c:\\cygwin\\include\\\n".
  428. "\n".
  429. &splitline("CFLAGS = -Wall -O2 -D_WINDOWS -DDEBUG -DWIN32S_COMPAT".
  430. " -D_NO_OLDNAMES " .
  431. (join " ", map {"-I$dirpfx$_"} @srcdirs)) .
  432. "\n".
  433. "LDFLAGS = -s\n".
  434. &splitline("RCFLAGS = \$(RCINC) --define WIN32=1 --define _WIN32=1 ".
  435. "--define WINVER=0x0400 ".(join " ", map {"-I$dirpfx$_"} @srcdirs))."\n".
  436. "\n".
  437. &def($makefile_extra{'cygwin'}->{'vars'}) .
  438. "\n".
  439. ".SUFFIXES:\n".
  440. "\n";
  441. print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
  442. print "\n\n";
  443. foreach $p (&prognames("G:C")) {
  444. ($prog, $type) = split ",", $p;
  445. $objstr = &objects($p, "X.o", "X.res.o", undef);
  446. print &splitline($prog . ".exe: " . $objstr), "\n";
  447. my $mw = $type eq "G" ? " -mwindows" : "";
  448. $libstr = &objects($p, undef, undef, "-lX");
  449. print &splitline("\t\$(CC)" . $mw . " \$(LDFLAGS) -o \$@ " .
  450. "-Wl,-Map,$prog.map " .
  451. $objstr . " $libstr", 69), "\n\n";
  452. }
  453. foreach $d (&deps("X.o", "X.res.o", $dirpfx, "/", "cygwin")) {
  454. if ($forceobj{$d->{obj_orig}}) {
  455. printf ("%s: FORCE\n", $d->{obj});
  456. } else {
  457. print &splitline(sprintf("%s: %s", $d->{obj},
  458. join " ", @{$d->{deps}})), "\n";
  459. }
  460. if ($d->{obj} =~ /\.res\.o$/) {
  461. print "\t\$(RC) \$(RCFL) \$(RCFLAGS) ".$d->{deps}->[0]." -o ".$d->{obj}."\n\n";
  462. } else {
  463. print "\t\$(CC) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) -c ".$d->{deps}->[0]."\n\n";
  464. }
  465. }
  466. print "\n";
  467. print &def($makefile_extra{'cygwin'}->{'end'});
  468. print "\nclean:\n".
  469. "\trm -f *.o *.exe *.res.o *.so *.map\n".
  470. "\n".
  471. "FORCE:\n";
  472. select STDOUT; close OUT;
  473. }
  474. ##-- Borland makefile
  475. if (defined $makefiles{'borland'}) {
  476. $dirpfx = &dirpfx($makefiles{'borland'}, "\\");
  477. %stdlibs = ( # Borland provides many Win32 API libraries intrinsically
  478. "advapi32" => 1,
  479. "comctl32" => 1,
  480. "comdlg32" => 1,
  481. "gdi32" => 1,
  482. "imm32" => 1,
  483. "shell32" => 1,
  484. "user32" => 1,
  485. "winmm" => 1,
  486. "winspool" => 1,
  487. "wsock32" => 1,
  488. );
  489. open OUT, ">$makefiles{'borland'}"; select OUT;
  490. print
  491. "# Makefile for $project_name under Borland C.\n".
  492. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  493. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  494. # bcc32 command line option is -D not /D
  495. ($_ = $help) =~ s/([=" ])\/D/$1-D/gs;
  496. print $_;
  497. print
  498. "\n".
  499. "# If you rename this file to `Makefile', you should change this line,\n".
  500. "# so that the .rsp files still depend on the correct makefile.\n".
  501. "MAKEFILE = Makefile.bor\n".
  502. "\n".
  503. "# C compilation flags\n".
  504. "CFLAGS = -D_WINDOWS -DWINVER=0x0500\n".
  505. "# Resource compilation flags\n".
  506. "RCFLAGS = -DNO_WINRESRC_H -DWIN32 -D_WIN32 -DWINVER=0x0401\n".
  507. "\n".
  508. "# Get include directory for resource compiler\n".
  509. "!if !\$d(BCB)\n".
  510. "BCB = \$(MAKEDIR)\\..\n".
  511. "!endif\n".
  512. "\n".
  513. &def($makefile_extra{'borland'}->{'vars'}) .
  514. "\n".
  515. ".c.obj:\n".
  516. &splitline("\tbcc32 -w-aus -w-ccc -w-par -w-pia \$(COMPAT)".
  517. " \$(CFLAGS) \$(XFLAGS) ".
  518. (join " ", map {"-I$dirpfx$_"} @srcdirs) .
  519. " /c \$*.c",69)."\n".
  520. ".rc.res:\n".
  521. &splitline("\tbrcc32 \$(RCFL) -i \$(BCB)\\include -r".
  522. " \$(RCFLAGS) \$*.rc",69)."\n".
  523. "\n";
  524. print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
  525. print "\n\n";
  526. foreach $p (&prognames("G:C")) {
  527. ($prog, $type) = split ",", $p;
  528. $objstr = &objects($p, "X.obj", "X.res", undef);
  529. print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
  530. my $ap = ($type eq "G") ? "-aa" : "-ap";
  531. print "\tilink32 $ap -Gn -L\$(BCB)\\lib \@$prog.rsp\n\n";
  532. }
  533. foreach $p (&prognames("G:C")) {
  534. ($prog, $type) = split ",", $p;
  535. print $prog, ".rsp: \$(MAKEFILE)\n";
  536. $objstr = &objects($p, "X.obj", undef, undef);
  537. @objlist = split " ", $objstr;
  538. @objlines = ("");
  539. foreach $i (@objlist) {
  540. if (length($objlines[$#objlines] . " $i") > 50) {
  541. push @objlines, "";
  542. }
  543. $objlines[$#objlines] .= " $i";
  544. }
  545. $c0w = ($type eq "G") ? "c0w32" : "c0x32";
  546. print "\techo $c0w + > $prog.rsp\n";
  547. for ($i=0; $i<=$#objlines; $i++) {
  548. $plus = ($i < $#objlines ? " +" : "");
  549. print "\techo$objlines[$i]$plus >> $prog.rsp\n";
  550. }
  551. print "\techo $prog.exe >> $prog.rsp\n";
  552. $objstr = &objects($p, "X.obj", "X.res", undef);
  553. @libs = split " ", &objects($p, undef, undef, "X");
  554. @libs = grep { !$stdlibs{$_} } @libs;
  555. unshift @libs, "cw32", "import32";
  556. $libstr = join ' ', @libs;
  557. print "\techo nul,$libstr, >> $prog.rsp\n";
  558. print "\techo " . &objects($p, undef, "X.res", undef) . " >> $prog.rsp\n";
  559. print "\n";
  560. }
  561. foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\", "borland")) {
  562. if ($forceobj{$d->{obj_orig}}) {
  563. printf("%s: FORCE\n", $d->{obj});
  564. } else {
  565. print &splitline(sprintf("%s: %s", $d->{obj},
  566. join " ", @{$d->{deps}})), "\n";
  567. }
  568. }
  569. print "\n";
  570. print &def($makefile_extra{'borland'}->{'end'});
  571. print "\nclean:\n".
  572. "\t-del *.obj\n".
  573. "\t-del *.exe\n".
  574. "\t-del *.res\n".
  575. "\t-del *.pch\n".
  576. "\t-del *.aps\n".
  577. "\t-del *.il*\n".
  578. "\t-del *.pdb\n".
  579. "\t-del *.rsp\n".
  580. "\t-del *.tds\n".
  581. "\t-del *.\$\$\$\$\$\$\n".
  582. "\n".
  583. "FORCE:\n".
  584. "\t-rem dummy command\n";
  585. select STDOUT; close OUT;
  586. }
  587. if (defined $makefiles{'vc'}) {
  588. $dirpfx = &dirpfx($makefiles{'vc'}, "\\");
  589. ##-- Visual C++ makefile
  590. open OUT, ">$makefiles{'vc'}"; select OUT;
  591. print
  592. "# Makefile for $project_name under Visual C.\n".
  593. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  594. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  595. print $help;
  596. print
  597. "\n".
  598. "# If you rename this file to `Makefile', you should change this line,\n".
  599. "# so that the .rsp files still depend on the correct makefile.\n".
  600. "MAKEFILE = Makefile.vc\n".
  601. "\n".
  602. "# C compilation flags\n".
  603. "CFLAGS = /nologo /W3 /O1 " .
  604. (join " ", map {"-I$dirpfx$_"} @srcdirs) .
  605. " /D_WINDOWS /D_WIN32_WINDOWS=0x500 /DWINVER=0x500 /D_CRT_SECURE_NO_WARNINGS\n".
  606. "LFLAGS = /incremental:no /fixed\n".
  607. "RCFLAGS = ".(join " ", map {"-I$dirpfx$_"} @srcdirs).
  608. " -DWIN32 -D_WIN32 -DWINVER=0x0400\n".
  609. "\n".
  610. &def($makefile_extra{'vc'}->{'vars'}) .
  611. "\n".
  612. "\n";
  613. print &splitline("all:" . join "", map { " \$(BUILDDIR)$_.exe" } &progrealnames("G:C"));
  614. print "\n\n";
  615. foreach $p (&prognames("G:C")) {
  616. ($prog, $type) = split ",", $p;
  617. $objstr = &objects($p, "\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", undef);
  618. print &splitline("\$(BUILDDIR)$prog.exe: " . $objstr), "\n";
  619. $objstr = &objects($p, "\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", "X.lib");
  620. $subsys = ($type eq "G") ? "windows" : "console";
  621. $inlinefilename = "link_$prog";
  622. print "\ttype <<$inlinefilename\n";
  623. @objlist = split " ", $objstr;
  624. @objlines = ("");
  625. foreach $i (@objlist) {
  626. if (length($objlines[$#objlines] . " $i") > 72) {
  627. push @objlines, "";
  628. }
  629. $objlines[$#objlines] .= " $i";
  630. }
  631. for ($i=0; $i<=$#objlines; $i++) {
  632. print "$objlines[$i]\n";
  633. }
  634. print "<<\n";
  635. print "\tlink \$(LFLAGS) \$(XLFLAGS) -out:\$(BUILDDIR)$prog.exe -map:\$(BUILDDIR)$prog.map -nologo -subsystem:$subsys \@$inlinefilename\n\n";
  636. }
  637. foreach $d (&deps("\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", $dirpfx, "\\", "vc")) {
  638. $extradeps = $forceobj{$d->{obj_orig}} ? ["*.c","*.h","*.rc"] : [];
  639. print &splitline(sprintf("%s: %s", $d->{obj},
  640. join " ", @$extradeps, @{$d->{deps}})), "\n";
  641. if ($d->{obj} =~ /.res$/) {
  642. print "\trc /Fo@{[$d->{obj}]} \$(RCFL) -r \$(RCFLAGS) ".$d->{deps}->[0],"\n\n";
  643. }
  644. }
  645. print "\n";
  646. foreach $real_srcdir ("", @srcdirs) {
  647. $srcdir = $real_srcdir;
  648. if ($srcdir ne "") {
  649. $srcdir =~ s!/!\\!g;
  650. $srcdir = $dirpfx . $srcdir;
  651. $srcdir =~ s!\\\.\\!\\!;
  652. $srcdir = "{$srcdir}";
  653. }
  654. # The double colon at the end of the line makes this a
  655. # 'batch-mode inference rule', which means that nmake will
  656. # aggregate multiple invocations of the rule and issue just
  657. # one cl command with multiple source-file arguments. That
  658. # noticeably speeds up builds, since starting up the cl
  659. # process is a noticeable overhead and now has to be done far
  660. # fewer times.
  661. print "${srcdir}.c.obj::\n\tcl /Fo\$(BUILDDIR) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) /c \$<\n\n";
  662. }
  663. print &def($makefile_extra{'vc'}->{'end'});
  664. print "\nclean: tidy\n".
  665. "\t-del \$(BUILDDIR)*.exe\n\n".
  666. "tidy:\n".
  667. "\t-del \$(BUILDDIR)*.obj\n".
  668. "\t-del \$(BUILDDIR)*.res\n".
  669. "\t-del \$(BUILDDIR)*.pch\n".
  670. "\t-del \$(BUILDDIR)*.aps\n".
  671. "\t-del \$(BUILDDIR)*.ilk\n".
  672. "\t-del \$(BUILDDIR)*.pdb\n".
  673. "\t-del \$(BUILDDIR)*.rsp\n".
  674. "\t-del \$(BUILDDIR)*.dsp\n".
  675. "\t-del \$(BUILDDIR)*.dsw\n".
  676. "\t-del \$(BUILDDIR)*.ncb\n".
  677. "\t-del \$(BUILDDIR)*.opt\n".
  678. "\t-del \$(BUILDDIR)*.plg\n".
  679. "\t-del \$(BUILDDIR)*.map\n".
  680. "\t-del \$(BUILDDIR)*.idb\n".
  681. "\t-del \$(BUILDDIR)debug.log\n";
  682. select STDOUT; close OUT;
  683. }
  684. if (defined $makefiles{'vcproj'}) {
  685. $dirpfx = &dirpfx($makefiles{'vcproj'}, "\\");
  686. ##-- MSVC 6 Workspace and projects
  687. #
  688. # Note: All files created in this section are written in binary
  689. # mode, because although MSVC's command-line make can deal with
  690. # LF-only line endings, MSVC project files really _need_ to be
  691. # CRLF. Hence, in order for mkfiles.pl to generate usable project
  692. # files even when run from Unix, I make sure all files are binary
  693. # and explicitly write the CRLFs.
  694. #
  695. # Create directories if necessary
  696. mkdir $makefiles{'vcproj'}
  697. if(! -d $makefiles{'vcproj'});
  698. chdir $makefiles{'vcproj'};
  699. @deps = &deps("X.obj", "X.res", $dirpfx, "\\", "vcproj");
  700. %all_object_deps = map {$_->{obj} => $_->{deps}} @deps;
  701. # Create the project files
  702. # Get names of all Windows projects (GUI and console)
  703. my @prognames = &prognames("G:C");
  704. foreach $progname (@prognames) {
  705. create_vc_project(\%all_object_deps, $progname);
  706. }
  707. # Create the workspace file
  708. open OUT, ">$project_name.dsw"; binmode OUT; select OUT;
  709. print
  710. "Microsoft Developer Studio Workspace File, Format Version 6.00\r\n".
  711. "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r\n".
  712. "\r\n".
  713. "###############################################################################\r\n".
  714. "\r\n";
  715. # List projects
  716. foreach $progname (@prognames) {
  717. ($windows_project, $type) = split ",", $progname;
  718. print "Project: \"$windows_project\"=\".\\$windows_project\\$windows_project.dsp\" - Package Owner=<4>\r\n";
  719. }
  720. print
  721. "\r\n".
  722. "Package=<5>\r\n".
  723. "{{{\r\n".
  724. "}}}\r\n".
  725. "\r\n".
  726. "Package=<4>\r\n".
  727. "{{{\r\n".
  728. "}}}\r\n".
  729. "\r\n".
  730. "###############################################################################\r\n".
  731. "\r\n".
  732. "Global:\r\n".
  733. "\r\n".
  734. "Package=<5>\r\n".
  735. "{{{\r\n".
  736. "}}}\r\n".
  737. "\r\n".
  738. "Package=<3>\r\n".
  739. "{{{\r\n".
  740. "}}}\r\n".
  741. "\r\n".
  742. "###############################################################################\r\n".
  743. "\r\n";
  744. select STDOUT; close OUT;
  745. chdir $orig_dir;
  746. sub create_vc_project {
  747. my ($all_object_deps, $progname) = @_;
  748. # Construct program's dependency info
  749. %seen_objects = ();
  750. %lib_files = ();
  751. %source_files = ();
  752. %header_files = ();
  753. %resource_files = ();
  754. @object_files = split " ", &objects($progname, "X.obj", "X.res", "X.lib");
  755. foreach $object_file (@object_files) {
  756. next if defined $seen_objects{$object_file};
  757. $seen_objects{$object_file} = 1;
  758. if($object_file =~ /\.lib$/io) {
  759. $lib_files{$object_file} = 1;
  760. next;
  761. }
  762. $object_deps = $all_object_deps{$object_file};
  763. foreach $object_dep (@$object_deps) {
  764. if($object_dep =~ /\.c$/io) {
  765. $source_files{$object_dep} = 1;
  766. next;
  767. }
  768. if($object_dep =~ /\.h$/io) {
  769. $header_files{$object_dep} = 1;
  770. next;
  771. }
  772. if($object_dep =~ /\.(rc|ico)$/io) {
  773. $resource_files{$object_dep} = 1;
  774. next;
  775. }
  776. }
  777. }
  778. $libs = join " ", sort keys %lib_files;
  779. @source_files = sort keys %source_files;
  780. @header_files = sort keys %header_files;
  781. @resources = sort keys %resource_files;
  782. ($windows_project, $type) = split ",", $progname;
  783. mkdir $windows_project
  784. if(! -d $windows_project);
  785. chdir $windows_project;
  786. $subsys = ($type eq "G") ? "windows" : "console";
  787. open OUT, ">$windows_project.dsp"; binmode OUT; select OUT;
  788. print
  789. "# Microsoft Developer Studio Project File - Name=\"$windows_project\" - Package Owner=<4>\r\n".
  790. "# Microsoft Developer Studio Generated Build File, Format Version 6.00\r\n".
  791. "# ** DO NOT EDIT **\r\n".
  792. "\r\n".
  793. "# TARGTYPE \"Win32 (x86) Application\" 0x0101\r\n".
  794. "\r\n".
  795. "CFG=$windows_project - Win32 Debug\r\n".
  796. "!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r\n".
  797. "!MESSAGE use the Export Makefile command and run\r\n".
  798. "!MESSAGE \r\n".
  799. "!MESSAGE NMAKE /f \"$windows_project.mak\".\r\n".
  800. "!MESSAGE \r\n".
  801. "!MESSAGE You can specify a configuration when running NMAKE\r\n".
  802. "!MESSAGE by defining the macro CFG on the command line. For example:\r\n".
  803. "!MESSAGE \r\n".
  804. "!MESSAGE NMAKE /f \"$windows_project.mak\" CFG=\"$windows_project - Win32 Debug\"\r\n".
  805. "!MESSAGE \r\n".
  806. "!MESSAGE Possible choices for configuration are:\r\n".
  807. "!MESSAGE \r\n".
  808. "!MESSAGE \"$windows_project - Win32 Release\" (based on \"Win32 (x86) Application\")\r\n".
  809. "!MESSAGE \"$windows_project - Win32 Debug\" (based on \"Win32 (x86) Application\")\r\n".
  810. "!MESSAGE \r\n".
  811. "\r\n".
  812. "# Begin Project\r\n".
  813. "# PROP AllowPerConfigDependencies 0\r\n".
  814. "# PROP Scc_ProjName \"\"\r\n".
  815. "# PROP Scc_LocalPath \"\"\r\n".
  816. "CPP=cl.exe\r\n".
  817. "MTL=midl.exe\r\n".
  818. "RSC=rc.exe\r\n".
  819. "\r\n".
  820. "!IF \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
  821. "\r\n".
  822. "# PROP BASE Use_MFC 0\r\n".
  823. "# PROP BASE Use_Debug_Libraries 0\r\n".
  824. "# PROP BASE Output_Dir \"Release\"\r\n".
  825. "# PROP BASE Intermediate_Dir \"Release\"\r\n".
  826. "# PROP BASE Target_Dir \"\"\r\n".
  827. "# PROP Use_MFC 0\r\n".
  828. "# PROP Use_Debug_Libraries 0\r\n".
  829. "# PROP Output_Dir \"Release\"\r\n".
  830. "# PROP Intermediate_Dir \"Release\"\r\n".
  831. "# PROP Ignore_Export_Lib 0\r\n".
  832. "# PROP Target_Dir \"\"\r\n".
  833. "# ADD BASE CPP /nologo /W3 /GX /O2 ".
  834. (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
  835. " /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
  836. "# ADD CPP /nologo /W3 /GX /O2 ".
  837. (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
  838. " /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
  839. "# ADD BASE MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
  840. "# ADD MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
  841. "# ADD BASE RSC /l 0x809 /d \"NDEBUG\"\r\n".
  842. "# ADD RSC /l 0x809 /d \"NDEBUG\"\r\n".
  843. "BSC32=bscmake.exe\r\n".
  844. "# ADD BASE BSC32 /nologo\r\n".
  845. "# ADD BSC32 /nologo\r\n".
  846. "LINK32=link.exe\r\n".
  847. "# 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".
  848. "# ADD LINK32 $libs /nologo /subsystem:$subsys /machine:I386\r\n".
  849. "# SUBTRACT LINK32 /pdb:none\r\n".
  850. "\r\n".
  851. "!ELSEIF \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
  852. "\r\n".
  853. "# PROP BASE Use_MFC 0\r\n".
  854. "# PROP BASE Use_Debug_Libraries 1\r\n".
  855. "# PROP BASE Output_Dir \"Debug\"\r\n".
  856. "# PROP BASE Intermediate_Dir \"Debug\"\r\n".
  857. "# PROP BASE Target_Dir \"\"\r\n".
  858. "# PROP Use_MFC 0\r\n".
  859. "# PROP Use_Debug_Libraries 1\r\n".
  860. "# PROP Output_Dir \"Debug\"\r\n".
  861. "# PROP Intermediate_Dir \"Debug\"\r\n".
  862. "# PROP Ignore_Export_Lib 0\r\n".
  863. "# PROP Target_Dir \"\"\r\n".
  864. "# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od ".
  865. (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
  866. " /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
  867. "# ADD CPP /nologo /W3 /Gm /GX /ZI /Od ".
  868. (join " ", map {"/I \"..\\..\\$dirpfx$_\""} @srcdirs) .
  869. " /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
  870. "# ADD BASE MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
  871. "# ADD MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
  872. "# ADD BASE RSC /l 0x809 /d \"_DEBUG\"\r\n".
  873. "# ADD RSC /l 0x809 /d \"_DEBUG\"\r\n".
  874. "BSC32=bscmake.exe\r\n".
  875. "# ADD BASE BSC32 /nologo\r\n".
  876. "# ADD BSC32 /nologo\r\n".
  877. "LINK32=link.exe\r\n".
  878. "# 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".
  879. "# ADD LINK32 $libs /nologo /subsystem:$subsys /debug /machine:I386 /pdbtype:sept\r\n".
  880. "# SUBTRACT LINK32 /pdb:none\r\n".
  881. "\r\n".
  882. "!ENDIF \r\n".
  883. "\r\n".
  884. "# Begin Target\r\n".
  885. "\r\n".
  886. "# Name \"$windows_project - Win32 Release\"\r\n".
  887. "# Name \"$windows_project - Win32 Debug\"\r\n".
  888. "# Begin Group \"Source Files\"\r\n".
  889. "\r\n".
  890. "# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\"\r\n";
  891. foreach $source_file (@source_files) {
  892. print
  893. "# Begin Source File\r\n".
  894. "\r\n".
  895. "SOURCE=..\\..\\$source_file\r\n";
  896. if($source_file =~ /ssh\.c/io) {
  897. # Disable 'Edit and continue' as Visual Studio can't handle the macros
  898. print
  899. "\r\n".
  900. "!IF \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
  901. "\r\n".
  902. "!ELSEIF \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
  903. "\r\n".
  904. "# ADD CPP /Zi\r\n".
  905. "\r\n".
  906. "!ENDIF \r\n".
  907. "\r\n";
  908. }
  909. print "# End Source File\r\n";
  910. }
  911. print
  912. "# End Group\r\n".
  913. "# Begin Group \"Header Files\"\r\n".
  914. "\r\n".
  915. "# PROP Default_Filter \"h;hpp;hxx;hm;inl\"\r\n";
  916. foreach $header_file (@header_files) {
  917. print
  918. "# Begin Source File\r\n".
  919. "\r\n".
  920. "SOURCE=..\\..\\$header_file\r\n".
  921. "# End Source File\r\n";
  922. }
  923. print
  924. "# End Group\r\n".
  925. "# Begin Group \"Resource Files\"\r\n".
  926. "\r\n".
  927. "# PROP Default_Filter \"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\r\n";
  928. foreach $resource_file (@resources) {
  929. print
  930. "# Begin Source File\r\n".
  931. "\r\n".
  932. "SOURCE=..\\..\\$resource_file\r\n".
  933. "# End Source File\r\n";
  934. }
  935. print
  936. "# End Group\r\n".
  937. "# End Target\r\n".
  938. "# End Project\r\n";
  939. select STDOUT; close OUT;
  940. chdir "..";
  941. }
  942. }
  943. if (defined $makefiles{'vstudio10'} || defined $makefiles{'vstudio12'}) {
  944. ##-- Visual Studio 2010+ Solution and Projects
  945. if (defined $makefiles{'vstudio10'}) {
  946. create_vs_solution('vstudio10', "2010", "11.00", "v100");
  947. }
  948. if (defined $makefiles{'vstudio12'}) {
  949. create_vs_solution('vstudio12', "2012", "12.00", "v110");
  950. }
  951. sub create_vs_solution {
  952. my ($makefilename, $name, $version, $toolsver) = @_;
  953. $dirpfx = &dirpfx($makefiles{$makefilename}, "\\");
  954. @deps = &deps("X.obj", "X.res", $dirpfx, "\\", $makefilename);
  955. %all_object_deps = map {$_->{obj} => $_->{deps}} @deps;
  956. my @prognames = &prognames("G:C");
  957. # Create the solution file.
  958. mkdir $makefiles{$makefilename}
  959. if(! -f $makefiles{$makefilename});
  960. chdir $makefiles{$makefilename};
  961. open OUT, ">$project_name.sln"; select OUT;
  962. print
  963. "Microsoft Visual Studio Solution File, Format Version $version\n" .
  964. "# Visual Studio $name\n";
  965. my %projguids = ();
  966. foreach $progname (@prognames) {
  967. ($windows_project, $type) = split ",", $progname;
  968. $projguids{$windows_project} = $guid =
  969. &invent_guid("project:$progname");
  970. print
  971. "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$windows_project\", \"$windows_project\\$windows_project.vcxproj\", \"{$guid}\"\n" .
  972. "EndProject\n";
  973. }
  974. print
  975. "Global\n" .
  976. " GlobalSection(SolutionConfigurationPlatforms) = preSolution\n" .
  977. " Debug|Win32 = Debug|Win32\n" .
  978. " Release|Win32 = Release|Win32\n" .
  979. " EndGlobalSection\n" .
  980. " GlobalSection(ProjectConfigurationPlatforms) = postSolution\n" ;
  981. foreach my $projguid (values %projguids) {
  982. print
  983. " {$projguid}.Debug|Win32.ActiveCfg = Debug|Win32\n" .
  984. " {$projguid}.Debug|Win32.Build.0 = Debug|Win32\n" .
  985. " {$projguid}.Release|Win32.ActiveCfg = Release|Win32\n" .
  986. " {$projguid}.Release|Win32.Build.0 = Release|Win32\n";
  987. }
  988. print
  989. " EndGlobalSection\n" .
  990. " GlobalSection(SolutionProperties) = preSolution\n" .
  991. " HideSolutionNode = FALSE\n" .
  992. " EndGlobalSection\n" .
  993. "EndGlobal\n";
  994. select STDOUT; close OUT;
  995. foreach $progname (@prognames) {
  996. ($windows_project, $type) = split ",", $progname;
  997. create_vs_project(\%all_object_deps, $windows_project, $type, $projguids{$windows_project}, $toolsver);
  998. }
  999. chdir $orig_dir;
  1000. }
  1001. sub create_vs_project {
  1002. my ($all_object_deps, $windows_project, $type, $projguid, $toolsver) = @_;
  1003. # Break down the project's dependency information into the appropriate
  1004. # groups.
  1005. %seen_objects = ();
  1006. %lib_files = ();
  1007. %source_files = ();
  1008. %header_files = ();
  1009. %resource_files = ();
  1010. %icon_files = ();
  1011. @object_files = split " ", &objects($progname, "X.obj", "X.res", "X.lib");
  1012. foreach $object_file (@object_files) {
  1013. next if defined $seen_objects{$object_file};
  1014. $seen_objects{$object_file} = 1;
  1015. if($object_file =~ /\.lib$/io) {
  1016. $lib_files{$object_file} = 1;
  1017. next;
  1018. }
  1019. $object_deps = $all_object_deps{$object_file};
  1020. foreach $object_dep (@$object_deps) {
  1021. if($object_dep eq $object_deps->[0]) {
  1022. if($object_dep =~ /\.c$/io) {
  1023. $source_files{$object_dep} = 1;
  1024. } elsif($object_dep =~ /\.rc$/io) {
  1025. $resource_files{$object_dep} = 1;
  1026. }
  1027. } elsif ($object_dep =~ /\.[ch]$/io) {
  1028. $header_files{$object_dep} = 1;
  1029. } elsif ($object_dep =~ /\.ico$/io) {
  1030. $icon_files{$object_dep} = 1;
  1031. }
  1032. }
  1033. }
  1034. $libs = join ";", sort keys %lib_files;
  1035. @source_files = sort keys %source_files;
  1036. @header_files = sort keys %header_files;
  1037. @resources = sort keys %resource_files;
  1038. @icons = sort keys %icon_files;
  1039. $subsystem = ($type eq "G") ? "Windows" : "Console";
  1040. mkdir $windows_project
  1041. if(! -d $windows_project);
  1042. chdir $windows_project;
  1043. open OUT, ">$windows_project.vcxproj"; select OUT;
  1044. open FILTERS, ">$windows_project.vcxproj.filters";
  1045. # The bulk of the project file is just boilerplate stuff, so we
  1046. # can mostly just dump it out here. Note, buried in the ClCompile
  1047. # item definition, that we use a debug information format of
  1048. # ProgramDatabase, which disables the edit-and-continue support
  1049. # that breaks most of the project builds.
  1050. print
  1051. "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .
  1052. "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" .
  1053. " <ItemGroup Label=\"ProjectConfigurations\">\n" .
  1054. " <ProjectConfiguration Include=\"Debug|Win32\">\n" .
  1055. " <Configuration>Debug</Configuration>\n" .
  1056. " <Platform>Win32</Platform>\n" .
  1057. " </ProjectConfiguration>\n" .
  1058. " <ProjectConfiguration Include=\"Release|Win32\">\n" .
  1059. " <Configuration>Release</Configuration>\n" .
  1060. " <Platform>Win32</Platform>\n" .
  1061. " </ProjectConfiguration>\n" .
  1062. " </ItemGroup>\n" .
  1063. " <PropertyGroup Label=\"Globals\">\n" .
  1064. " <SccProjectName />\n" .
  1065. " <SccLocalPath />\n" .
  1066. " <ProjectGuid>{$projguid}</ProjectGuid>\n" .
  1067. " </PropertyGroup>\n" .
  1068. " <Import Project=\"\$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n" .
  1069. " <PropertyGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n" .
  1070. " <ConfigurationType>Application</ConfigurationType>\n" .
  1071. " <UseOfMfc>false</UseOfMfc>\n" .
  1072. " <CharacterSet>MultiByte</CharacterSet>\n" .
  1073. " <PlatformToolset>$toolsver</PlatformToolset>\n" .
  1074. " </PropertyGroup>\n" .
  1075. " <PropertyGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n" .
  1076. " <ConfigurationType>Application</ConfigurationType>\n" .
  1077. " <UseOfMfc>false</UseOfMfc>\n" .
  1078. " <CharacterSet>MultiByte</CharacterSet>\n" .
  1079. " <PlatformToolset>$toolsver</PlatformToolset>\n" .
  1080. " </PropertyGroup>\n" .
  1081. " <Import Project=\"\$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n" .
  1082. " <ImportGroup Label=\"ExtensionTargets\">\n" .
  1083. " </ImportGroup>\n" .
  1084. " <ImportGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n" .
  1085. " <Import Project=\"\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props\" Condition=\"exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n" .
  1086. " </ImportGroup>\n" .
  1087. " <ImportGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n" .
  1088. " <Import Project=\"\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props\" Condition=\"exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n" .
  1089. " </ImportGroup>\n" .
  1090. " <PropertyGroup Label=\"UserMacros\" />\n" .
  1091. " <PropertyGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Release|Win32'\">\n" .
  1092. " <OutDir>.\\Release\\</OutDir>\n" .
  1093. " <IntDir>.\\Release\\</IntDir>\n" .
  1094. " <LinkIncremental>false</LinkIncremental>\n" .
  1095. " </PropertyGroup>\n" .
  1096. " <PropertyGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">\n" .
  1097. " <OutDir>.\\Debug\\</OutDir>\n" .
  1098. " <IntDir>.\\Debug\\</IntDir>\n" .
  1099. " <LinkIncremental>true</LinkIncremental>\n" .
  1100. " </PropertyGroup>\n" .
  1101. " <ItemDefinitionGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Release|Win32'\">\n" .
  1102. " <ClCompile>\n" .
  1103. " <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n" .
  1104. " <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n" .
  1105. " <StringPooling>true</StringPooling>\n" .
  1106. " <FunctionLevelLinking>true</FunctionLevelLinking>\n" .
  1107. " <Optimization>MaxSpeed</Optimization>\n" .
  1108. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1109. " <WarningLevel>Level3</WarningLevel>\n" .
  1110. " <AdditionalIncludeDirectories>" . (join ";", map {"..\\..\\$dirpfx$_"} @srcdirs) . ";%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" .
  1111. " <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;POSIX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1112. " <AssemblerListingLocation>.\\Release\\</AssemblerListingLocation>\n" .
  1113. " <PrecompiledHeaderOutputFile>.\\Release\\$windows_project.pch</PrecompiledHeaderOutputFile>\n" .
  1114. " <ObjectFileName>.\\Release\\</ObjectFileName>\n" .
  1115. " <ProgramDataBaseFileName>.\\Release\\</ProgramDataBaseFileName>\n" .
  1116. " </ClCompile>\n" .
  1117. " <Midl>\n" .
  1118. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1119. " <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1120. " <TypeLibraryName>.\\Release\\$windows_project.tlb</TypeLibraryName>\n" .
  1121. " <MkTypLibCompatible>true</MkTypLibCompatible>\n" .
  1122. " <TargetEnvironment>Win32</TargetEnvironment>\n" .
  1123. " </Midl>\n" .
  1124. " <ResourceCompile>\n" .
  1125. " <Culture>0x0809</Culture>\n" .
  1126. " <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1127. " </ResourceCompile>\n" .
  1128. " <Bscmake>\n" .
  1129. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1130. " <OutputFile>.\\Release\\$windows_project.bsc</OutputFile>\n" .
  1131. " </Bscmake>\n" .
  1132. " <Link>\n" .
  1133. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1134. " <SubSystem>$subsystem</SubSystem>\n" .
  1135. " <OutputFile>.\\Release\\$windows_project.exe</OutputFile>\n" .
  1136. " <AdditionalDependencies>$libs;%(AdditionalDependencies)</AdditionalDependencies>\n" .
  1137. " </Link>\n" .
  1138. " </ItemDefinitionGroup>\n" .
  1139. " <ItemDefinitionGroup Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">\n" .
  1140. " <ClCompile>\n" .
  1141. " <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n" .
  1142. " <InlineFunctionExpansion>Default</InlineFunctionExpansion>\n" .
  1143. " <FunctionLevelLinking>false</FunctionLevelLinking>\n" .
  1144. " <Optimization>Disabled</Optimization>\n" .
  1145. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1146. " <WarningLevel>Level3</WarningLevel>\n" .
  1147. " <MinimalRebuild>true</MinimalRebuild>\n" .
  1148. " <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n" .
  1149. " <AdditionalIncludeDirectories>" . (join ";", map {"..\\..\\$dirpfx$_"} @srcdirs) . ";%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" .
  1150. " <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POSIX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1151. " <AssemblerListingLocation>.\\Debug\\</AssemblerListingLocation>\n" .
  1152. " <PrecompiledHeaderOutputFile>.\\Debug\\$windows_project.pch</PrecompiledHeaderOutputFile>\n" .
  1153. " <ObjectFileName>.\\Debug\\</ObjectFileName>\n" .
  1154. " <ProgramDataBaseFileName>.\\Debug\\</ProgramDataBaseFileName>\n" .
  1155. " <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n" .
  1156. " </ClCompile>\n" .
  1157. " <Midl>\n" .
  1158. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1159. " <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1160. " <TypeLibraryName>.\\Debug\\$windows_project.tlb</TypeLibraryName>\n" .
  1161. " <MkTypLibCompatible>true</MkTypLibCompatible>\n" .
  1162. " <TargetEnvironment>Win32</TargetEnvironment>\n" .
  1163. " </Midl>\n" .
  1164. " <ResourceCompile>\n" .
  1165. " <Culture>0x0809</Culture>\n" .
  1166. " <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" .
  1167. " </ResourceCompile>\n" .
  1168. " <Bscmake>\n" .
  1169. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1170. " <OutputFile>.\\Debug\\$windows_project.bsc</OutputFile>\n" .
  1171. " </Bscmake>\n" .
  1172. " <Link>\n" .
  1173. " <SuppressStartupBanner>true</SuppressStartupBanner>\n" .
  1174. " <GenerateDebugInformation>true</GenerateDebugInformation>\n" .
  1175. " <SubSystem>$subsystem</SubSystem>\n" .
  1176. " <OutputFile>\$(TargetPath)</OutputFile>\n" .
  1177. " <AdditionalDependencies>$libs;%(AdditionalDependencies)</AdditionalDependencies>\n" .
  1178. " </Link>\n" .
  1179. " </ItemDefinitionGroup>\n";
  1180. # The VC++ projects don't have physical structure to them, instead
  1181. # the files are organized by logical "filters" that are stored in
  1182. # a separate file, so different users can organize things differently.
  1183. # The filters file contains a copy of the ItemGroup elements from
  1184. # the main project file that list the included items, but tack
  1185. # on a filter name where needed.
  1186. print FILTERS
  1187. "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .
  1188. "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n";
  1189. print " <ItemGroup>\n";
  1190. print FILTERS " <ItemGroup>\n";
  1191. foreach $icon_file (@icons) {
  1192. $icon_file =~ s/..\\windows\\//;
  1193. print " <CustomBuild Include=\"..\\..\\$icon_file\" />\n";
  1194. print FILTERS
  1195. " <CustomBuild Include=\"..\\..\\$icon_file\">\n" .
  1196. " <Filter>Resource Files</Filter>\n" .
  1197. " </CustomBuild>\n";
  1198. }
  1199. print FILTERS " </ItemGroup>\n";
  1200. print " </ItemGroup>\n";
  1201. print " <ItemGroup>\n";
  1202. print FILTERS " <ItemGroup>\n";
  1203. foreach $resource_file (@resources) {
  1204. $resource_file =~ s/..\\windows\\//;
  1205. print
  1206. " <ResourceCompile Include=\"..\\..\\$resource_file\">\n" .
  1207. " <AdditionalIncludeDirectories Condition=\"'\$(Configuration)|\$(Platform)'=='Release|Win32'\">..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" .
  1208. " <AdditionalIncludeDirectories Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" .
  1209. " </ResourceCompile>\n";
  1210. print FILTERS
  1211. " <ResourceCompile Include=\"..\\..\\$resource_file\">\n" .
  1212. " <Filter>Resource Files</Filter>\n" .
  1213. " </ResourceCompile>\n";
  1214. }
  1215. print FILTERS " </ItemGroup>\n";
  1216. print " </ItemGroup>\n";
  1217. print " <ItemGroup>\n";
  1218. print FILTERS " <ItemGroup>\n";
  1219. foreach $source_file (@source_files) {
  1220. $source_file =~ s/..\\windows\\//;
  1221. print " <ClCompile Include=\"..\\..\\$source_file\" />\n";
  1222. print FILTERS
  1223. " <ClCompile Include=\"..\\..\\$source_file\">\n" .
  1224. " <Filter>Source Files</Filter>\n" .
  1225. " </ClCompile>";
  1226. }
  1227. print FILTERS " </ItemGroup>\n";
  1228. print " </ItemGroup>\n";
  1229. print " <ItemGroup>\n";
  1230. print FILTERS " <ItemGroup>\n";
  1231. foreach $header_file (@header_files) {
  1232. $header_file =~ s/..\\windows\\//;
  1233. print " <ClInclude Include=\"..\\..\\$header_file\" />\n";
  1234. print FILTERS
  1235. " <ClInclude Include=\"..\\..\\$header_file\">\n" .
  1236. " <Filter>Header Files</Filter>\n" .
  1237. " </ClInclude>";
  1238. }
  1239. print FILTERS " </ItemGroup>\n";
  1240. print " </ItemGroup>\n";
  1241. print
  1242. " <Import Project=\"\$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n" .
  1243. "</Project>";
  1244. print FILTERS
  1245. " <ItemGroup>\n" .
  1246. " <Filter Include=\"Source Files\">\n" .
  1247. " <UniqueIdentifier>{" . &invent_guid("sources:$windows_project") . "}</UniqueIdentifier>\n" .
  1248. " </Filter>\n" .
  1249. " <Filter Include=\"Header Files\">\n" .
  1250. " <UniqueIdentifier>{" . &invent_guid("headers:$windows_project") . "}</UniqueIdentifier>\n" .
  1251. " </Filter>\n" .
  1252. " <Filter Include=\"Resource Files\">\n" .
  1253. " <UniqueIdentifier>{" . &invent_guid("resources:$windows_project") . "}</UniqueIdentifier>\n" .
  1254. " </Filter>\n" .
  1255. " </ItemGroup>\n" .
  1256. "</Project>";
  1257. select STDOUT; close OUT; close FILTERS;
  1258. chdir "..";
  1259. }
  1260. }
  1261. if (defined $makefiles{'gtk'}) {
  1262. $dirpfx = &dirpfx($makefiles{'gtk'}, "/");
  1263. ##-- X/GTK/Unix makefile
  1264. open OUT, ">$makefiles{'gtk'}"; select OUT;
  1265. print
  1266. "# Makefile for $project_name under X/GTK and Unix.\n".
  1267. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  1268. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  1269. # gcc command line option is -D not /D
  1270. ($_ = $help) =~ s/([=" ])\/D/$1-D/gs;
  1271. print $_;
  1272. print
  1273. "\n".
  1274. "# You can define this path to point at your tools if you need to\n".
  1275. "# TOOLPATH = /opt/gcc/bin\n".
  1276. "CC = \$(TOOLPATH)cc\n".
  1277. "# If necessary set the path to krb5-config here\n".
  1278. "KRB5CONFIG=krb5-config\n".
  1279. "# You can manually set this to `gtk-config' or `pkg-config gtk+-1.2'\n".
  1280. "# (depending on what works on your system) if you want to enforce\n".
  1281. "# building with GTK 1.2, or you can set it to `pkg-config gtk+-2.0 x11'\n".
  1282. "# if you want to enforce 2.0. The default is to try 2.0 and fall back\n".
  1283. "# to 1.2 if it isn't found.\n".
  1284. "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".
  1285. "\n".
  1286. "-include Makefile.local\n".
  1287. "\n".
  1288. "unexport CFLAGS # work around a weird issue with krb5-config\n".
  1289. "\n".
  1290. &splitline("CFLAGS = -O2 -Wall -Werror -g " .
  1291. (join " ", map {"-I$dirpfx$_"} @srcdirs) .
  1292. " \$(shell \$(GTK_CONFIG) --cflags)").
  1293. " -D _FILE_OFFSET_BITS=64\n".
  1294. "XLDFLAGS = \$(LDFLAGS) \$(shell \$(GTK_CONFIG) --libs)\n".
  1295. "ULDFLAGS = \$(LDFLAGS)\n".
  1296. "ifeq (,\$(findstring NO_GSSAPI,\$(COMPAT)))\n".
  1297. "ifeq (,\$(findstring STATIC_GSSAPI,\$(COMPAT)))\n".
  1298. "XLDFLAGS+= -ldl\n".
  1299. "ULDFLAGS+= -ldl\n".
  1300. "else\n".
  1301. "CFLAGS+= -DNO_LIBDL \$(shell \$(KRB5CONFIG) --cflags gssapi)\n".
  1302. "XLDFLAGS+= \$(shell \$(KRB5CONFIG) --libs gssapi)\n".
  1303. "ULDFLAGS+= \$(shell \$(KRB5CONFIG) --libs gssapi)\n".
  1304. "endif\n".
  1305. "endif\n".
  1306. "INSTALL=install\n".
  1307. "INSTALL_PROGRAM=\$(INSTALL)\n".
  1308. "INSTALL_DATA=\$(INSTALL)\n".
  1309. "prefix=/usr/local\n".
  1310. "exec_prefix=\$(prefix)\n".
  1311. "bindir=\$(exec_prefix)/bin\n".
  1312. "mandir=\$(prefix)/man\n".
  1313. "man1dir=\$(mandir)/man1\n".
  1314. "\n".
  1315. &def($makefile_extra{'gtk'}->{'vars'}) .
  1316. "\n".
  1317. ".SUFFIXES:\n".
  1318. "\n".
  1319. "\n";
  1320. print &splitline("all:" . join "", map { " $_" }
  1321. &progrealnames("X:XT:U:UT"));
  1322. print "\n\n";
  1323. foreach $p (&prognames("X:XT:U:UT")) {
  1324. ($prog, $type) = split ",", $p;
  1325. ($ldflags = $type) =~ s/T$//;
  1326. $objstr = &objects($p, "X.o", undef, undef);
  1327. print &splitline($prog . ": " . $objstr), "\n";
  1328. $libstr = &objects($p, undef, undef, "-lX");
  1329. print &splitline("\t\$(CC) -o \$@ " .
  1330. $objstr . " \$(${ldflags}LDFLAGS) $libstr", 69), "\n\n";
  1331. }
  1332. foreach $d (&deps("X.o", undef, $dirpfx, "/", "gtk")) {
  1333. if ($forceobj{$d->{obj_orig}}) {
  1334. printf("%s: FORCE\n", $d->{obj});
  1335. } else {
  1336. print &splitline(sprintf("%s: %s", $d->{obj},
  1337. join " ", @{$d->{deps}})), "\n";
  1338. }
  1339. print &splitline("\t\$(CC) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) -c $d->{deps}->[0]\n");
  1340. }
  1341. print "\n";
  1342. print &def($makefile_extra{'gtk'}->{'end'});
  1343. print "\nclean:\n".
  1344. "\trm -f *.o". (join "", map { " $_" } &progrealnames("X:XT:U:UT")) . "\n";
  1345. print "\nFORCE:\n";
  1346. select STDOUT; close OUT;
  1347. }
  1348. if (defined $makefiles{'unix'}) {
  1349. $dirpfx = &dirpfx($makefiles{'unix'}, "/");
  1350. ##-- GTK-free pure-Unix makefile for non-GUI apps only
  1351. open OUT, ">$makefiles{'unix'}"; select OUT;
  1352. print
  1353. "# Makefile for $project_name under Unix.\n".
  1354. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  1355. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  1356. # gcc command line option is -D not /D
  1357. ($_ = $help) =~ s/([=" ])\/D/$1-D/gs;
  1358. print $_;
  1359. print
  1360. "\n".
  1361. "# You can define this path to point at your tools if you need to\n".
  1362. "# TOOLPATH = /opt/gcc/bin\n".
  1363. "CC = \$(TOOLPATH)cc\n".
  1364. "\n".
  1365. "-include Makefile.local\n".
  1366. "\n".
  1367. "unexport CFLAGS # work around a weird issue with krb5-config\n".
  1368. "\n".
  1369. &splitline("CFLAGS = -O2 -Wall -Werror -g " .
  1370. (join " ", map {"-I$dirpfx$_"} @srcdirs)).
  1371. " -D _FILE_OFFSET_BITS=64\n".
  1372. "ULDFLAGS = \$(LDFLAGS)\n".
  1373. "INSTALL=install\n".
  1374. "INSTALL_PROGRAM=\$(INSTALL)\n".
  1375. "INSTALL_DATA=\$(INSTALL)\n".
  1376. "prefix=/usr/local\n".
  1377. "exec_prefix=\$(prefix)\n".
  1378. "bindir=\$(exec_prefix)/bin\n".
  1379. "mandir=\$(prefix)/man\n".
  1380. "man1dir=\$(mandir)/man1\n".
  1381. "\n".
  1382. &def($makefile_extra{'unix'}->{'vars'}) .
  1383. "\n".
  1384. ".SUFFIXES:\n".
  1385. "\n".
  1386. "\n";
  1387. print &splitline("all:" . join "", map { " $_" } &progrealnames("U:UT"));
  1388. print "\n\n";
  1389. foreach $p (&prognames("U:UT")) {
  1390. ($prog, $type) = split ",", $p;
  1391. $objstr = &objects($p, "X.o", undef, undef);
  1392. print &splitline($prog . ": " . $objstr), "\n";
  1393. $libstr = &objects($p, undef, undef, "-lX");
  1394. print &splitline("\t\$(CC) -o \$@ " .
  1395. $objstr . " \$(${type}LDFLAGS) $libstr", 69), "\n\n";
  1396. }
  1397. foreach $d (&deps("X.o", undef, $dirpfx, "/", "unix")) {
  1398. if ($forceobj{$d->{obj_orig}}) {
  1399. printf("%s: FORCE\n", $d->{obj});
  1400. } else {
  1401. print &splitline(sprintf("%s: %s", $d->{obj},
  1402. join " ", @{$d->{deps}})), "\n";
  1403. }
  1404. print &splitline("\t\$(CC) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) -c $d->{deps}->[0]\n");
  1405. }
  1406. print "\n";
  1407. print &def($makefile_extra{'unix'}->{'end'});
  1408. print "\nclean:\n".
  1409. "\trm -f *.o". (join "", map { " $_" } &progrealnames("U:UT")) . "\n";
  1410. print "\nFORCE:\n";
  1411. select STDOUT; close OUT;
  1412. }
  1413. if (defined $makefiles{'am'}) {
  1414. die "Makefile.am in a subdirectory is not supported\n"
  1415. if &dirpfx($makefiles{'am'}, "/") ne "";
  1416. ##-- Unix/autoconf Makefile.am
  1417. open OUT, ">$makefiles{'am'}"; select OUT;
  1418. print
  1419. "# Makefile.am for $project_name under Unix with Autoconf/Automake.\n".
  1420. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  1421. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n\n";
  1422. # 2014-02-22: as of automake-1.14 we begin to get complained at if
  1423. # we don't use this option
  1424. print "AUTOMAKE_OPTIONS = subdir-objects\n\n";
  1425. # Complete list of source and header files. Not used by the
  1426. # auto-generated parts of this makefile, but Recipe might like to
  1427. # have it available as a variable so that mandatory-rebuild things
  1428. # (version.o) can conveniently be made to depend on it.
  1429. @sources = ("allsources", "=", sort keys %allsourcefiles);
  1430. print &splitline(join " ", @sources), "\n\n";
  1431. @cliprogs = ("bin_PROGRAMS", "=");
  1432. foreach $p (&prognames("U")) {
  1433. ($prog, $type) = split ",", $p;
  1434. push @cliprogs, $prog;
  1435. }
  1436. @allprogs = @cliprogs;
  1437. foreach $p (&prognames("X")) {
  1438. ($prog, $type) = split ",", $p;
  1439. push @allprogs, $prog;
  1440. }
  1441. print "if HAVE_GTK\n";
  1442. print &splitline(join " ", @allprogs), "\n";
  1443. print "else\n";
  1444. print &splitline(join " ", @cliprogs), "\n";
  1445. print "endif\n\n";
  1446. @noinstcliprogs = ("noinst_PROGRAMS", "=");
  1447. foreach $p (&prognames("XT:UT")) {
  1448. ($prog, $type) = split ",", $p;
  1449. push @noinstcliprogs, $prog;
  1450. }
  1451. print &splitline(join " ", @noinstcliprogs), "\n";
  1452. %objtosrc = ();
  1453. foreach $d (&deps("X", undef, "", "/", "am")) {
  1454. $objtosrc{$d->{obj}} = $d->{deps}->[0];
  1455. }
  1456. print &splitline(join " ", "AM_CPPFLAGS", "=",
  1457. map {"-I\$(srcdir)/$_"} @srcdirs), "\n";
  1458. @amcflags = ("\$(COMPAT)", "\$(XFLAGS)", "\$(WARNINGOPTS)");
  1459. print "if HAVE_GTK\n";
  1460. print &splitline(join " ", "AM_CFLAGS", "=",
  1461. "\$(GTK_CFLAGS)", @amcflags), "\n";
  1462. print "else\n";
  1463. print &splitline(join " ", "AM_CFLAGS", "=", @amcflags), "\n";
  1464. print "endif\n\n";
  1465. %amspeciallibs = ();
  1466. foreach $obj (sort { $a cmp $b } keys %{$cflags{'am'}}) {
  1467. my $flags = $cflags{'am'}->{$obj};
  1468. $flags = "" if $flags !~ s/^C//;
  1469. print "lib${obj}_a_SOURCES = ", $objtosrc{$obj}, "\n";
  1470. print &splitline(join " ", "lib${obj}_a_CFLAGS", "=", @amcflags,
  1471. $flags), "\n";
  1472. $amspeciallibs{$obj} = "lib${obj}.a";
  1473. }
  1474. print &splitline(join " ", "noinst_LIBRARIES", "=",
  1475. sort { $a cmp $b } values %amspeciallibs), "\n\n";
  1476. foreach $p (&prognames("X:XT:U:UT")) {
  1477. ($prog, $type) = split ",", $p;
  1478. print "if HAVE_GTK\n" if $type eq "X" || $type eq "XT";
  1479. @progsources = ("${prog}_SOURCES", "=");
  1480. %sourcefiles = ();
  1481. @ldadd = ();
  1482. $objstr = &objects($p, "X", undef, undef);
  1483. foreach $obj (split / /,$objstr) {
  1484. if ($amspeciallibs{$obj}) {
  1485. push @ldadd, $amspeciallibs{$obj};
  1486. } else {
  1487. $sourcefiles{$objtosrc{$obj}} = 1;
  1488. }
  1489. }
  1490. push @progsources, sort { $a cmp $b } keys %sourcefiles;
  1491. print &splitline(join " ", @progsources), "\n";
  1492. if ($type eq "X" || $type eq "XT") {
  1493. push @ldadd, "\$(GTK_LIBS)";
  1494. }
  1495. if (@ldadd) {
  1496. print &splitline(join " ", "${prog}_LDADD", "=", @ldadd), "\n";
  1497. }
  1498. print "endif\n" if $type eq "X" || $type eq "XT";
  1499. print "\n";
  1500. }
  1501. print &def($makefile_extra{'am'}->{'end'});
  1502. select STDOUT; close OUT;
  1503. }
  1504. if (defined $makefiles{'lcc'}) {
  1505. $dirpfx = &dirpfx($makefiles{'lcc'}, "\\");
  1506. ##-- lcc makefile
  1507. open OUT, ">$makefiles{'lcc'}"; select OUT;
  1508. print
  1509. "# Makefile for $project_name under lcc.\n".
  1510. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  1511. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  1512. # lcc command line option is -D not /D
  1513. ($_ = $help) =~ s/([=" ])\/D/$1-D/gs;
  1514. print $_;
  1515. print
  1516. "\n".
  1517. "# If you rename this file to `Makefile', you should change this line,\n".
  1518. "# so that the .rsp files still depend on the correct makefile.\n".
  1519. "MAKEFILE = Makefile.lcc\n".
  1520. "\n".
  1521. "# C compilation flags\n".
  1522. "CFLAGS = -D_WINDOWS " .
  1523. (join " ", map {"-I$dirpfx$_"} @srcdirs) .
  1524. "\n".
  1525. "# Resource compilation flags\n".
  1526. "RCFLAGS = ".(join " ", map {"-I$dirpfx$_"} @srcdirs)."\n".
  1527. "\n".
  1528. "# Get include directory for resource compiler\n".
  1529. "\n".
  1530. &def($makefile_extra{'lcc'}->{'vars'}) .
  1531. "\n";
  1532. print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
  1533. print "\n\n";
  1534. foreach $p (&prognames("G:C")) {
  1535. ($prog, $type) = split ",", $p;
  1536. $objstr = &objects($p, "X.obj", "X.res", undef);
  1537. print &splitline("$prog.exe: " . $objstr ), "\n";
  1538. $subsystemtype = '';
  1539. if ($type eq "G") { $subsystemtype = "-subsystem windows"; }
  1540. my $libss = "shell32.lib wsock32.lib ws2_32.lib winspool.lib winmm.lib imm32.lib";
  1541. print &splitline("\tlcclnk $subsystemtype -o $prog.exe $objstr $libss");
  1542. print "\n\n";
  1543. }
  1544. foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\", "lcc")) {
  1545. if ($forceobj{$d->{obj_orig}}) {
  1546. printf("%s: FORCE\n", $d->{obj});
  1547. } else {
  1548. print &splitline(sprintf("%s: %s", $d->{obj},
  1549. join " ", @{$d->{deps}})), "\n";
  1550. }
  1551. if ($d->{obj} =~ /\.obj$/) {
  1552. print &splitline("\tlcc -O -p6 \$(COMPAT)".
  1553. " \$(CFLAGS) \$(XFLAGS) ".$d->{deps}->[0],69)."\n";
  1554. } else {
  1555. print &splitline("\tlrc \$(RCFL) -r \$(RCFLAGS) ".
  1556. $d->{deps}->[0],69)."\n";
  1557. }
  1558. }
  1559. print "\n";
  1560. print &def($makefile_extra{'lcc'}->{'end'});
  1561. print "\nclean:\n".
  1562. "\t-del *.obj\n".
  1563. "\t-del *.exe\n".
  1564. "\t-del *.res\n".
  1565. "\n".
  1566. "FORCE:\n";
  1567. select STDOUT; close OUT;
  1568. }
  1569. if (defined $makefiles{'osx'}) {
  1570. $dirpfx = &dirpfx($makefiles{'osx'}, "/");
  1571. ##-- Mac OS X makefile
  1572. open OUT, ">$makefiles{'osx'}"; select OUT;
  1573. print
  1574. "# Makefile for $project_name under Mac OS X.\n".
  1575. "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
  1576. "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
  1577. # gcc command line option is -D not /D
  1578. ($_ = $help) =~ s/([=" ])\/D/$1-D/gs;
  1579. print $_;
  1580. print
  1581. "CC = \$(TOOLPATH)gcc\n".
  1582. "\n".
  1583. &splitline("CFLAGS = -O2 -Wall -Werror -g " .
  1584. (join " ", map {"-I$dirpfx$_"} @srcdirs))."\n".
  1585. "MLDFLAGS = -framework Cocoa\n".
  1586. "ULDFLAGS =\n".
  1587. "\n" .
  1588. &def($makefile_extra{'osx'}->{'vars'}) .
  1589. "\n" .
  1590. &splitline("all:" . join "", map { " $_" } &progrealnames("MX:U:UT")) .
  1591. "\n";
  1592. foreach $p (&prognames("MX")) {
  1593. ($prog, $type) = split ",", $p;
  1594. $objstr = &objects($p, "X.o", undef, undef);
  1595. $icon = &special($p, ".icns");
  1596. $infoplist = &special($p, "info.plist");
  1597. print "${prog}.app:\n\tmkdir -p \$\@\n";
  1598. print "${prog}.app/Contents: ${prog}.app\n\tmkdir -p \$\@\n";
  1599. print "${prog}.app/Contents/MacOS: ${prog}.app/Contents\n\tmkdir -p \$\@\n";
  1600. $targets = "${prog}.app/Contents/MacOS/$prog";
  1601. if (defined $icon) {
  1602. print "${prog}.app/Contents/Resources: ${prog}.app/Contents\n\tmkdir -p \$\@\n";
  1603. print "${prog}.app/Contents/Resources/${prog}.icns: ${prog}.app/Contents/Resources $icon\n\tcp $icon \$\@\n";
  1604. $targets .= " ${prog}.app/Contents/Resources/${prog}.icns";
  1605. }
  1606. if (defined $infoplist) {
  1607. print "${prog}.app/Contents/Info.plist: ${prog}.app/Contents/Resources $infoplist\n\tcp $infoplist \$\@\n";
  1608. $targets .= " ${prog}.app/Contents/Info.plist";
  1609. }
  1610. $targets .= " \$(${prog}_extra)";
  1611. print &splitline("${prog}: $targets", 69) . "\n\n";
  1612. print &splitline("${prog}.app/Contents/MacOS/$prog: ".
  1613. "${prog}.app/Contents/MacOS " . $objstr), "\n";
  1614. $libstr = &objects($p, undef, undef, "-lX");
  1615. print &splitline("\t\$(CC) \$(MLDFLAGS) -o \$@ " .
  1616. $objstr . " $libstr", 69), "\n\n";
  1617. }
  1618. foreach $p (&prognames("U:UT")) {
  1619. ($prog, $type) = split ",", $p;
  1620. $objstr = &objects($p, "X.o", undef, undef);
  1621. print &splitline($prog . ": " . $objstr), "\n";
  1622. $libstr = &objects($p, undef, undef, "-lX");
  1623. print &splitline("\t\$(CC) \$(ULDFLAGS) -o \$@ " .
  1624. $objstr . " $libstr", 69), "\n\n";
  1625. }
  1626. foreach $d (&deps("X.o", undef, $dirpfx, "/", "osx")) {
  1627. if ($forceobj{$d->{obj_orig}}) {
  1628. printf("%s: FORCE\n", $d->{obj});
  1629. } else {
  1630. print &splitline(sprintf("%s: %s", $d->{obj},
  1631. join " ", @{$d->{deps}})), "\n";
  1632. }
  1633. $firstdep = $d->{deps}->[0];
  1634. if ($firstdep =~ /\.c$/) {
  1635. print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS) -c \$<\n";
  1636. } elsif ($firstdep =~ /\.m$/) {
  1637. print "\t\$(CC) -x objective-c \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS) -c \$<\n";
  1638. }
  1639. }
  1640. print "\n".&def($makefile_extra{'osx'}->{'end'});
  1641. print "\nclean:\n".
  1642. "\trm -f *.o *.dmg". (join "", map { " $_" } &progrealnames("U:UT")) . "\n".
  1643. "\trm -rf *.app\n".
  1644. "\n".
  1645. "FORCE:\n";
  1646. select STDOUT; close OUT;
  1647. }
  1648. if (defined $makefiles{'devcppproj'}) {
  1649. $dirpfx = &dirpfx($makefiles{'devcppproj'}, "\\");
  1650. $orig_dir = cwd;
  1651. ##-- Dev-C++ 5 projects
  1652. #
  1653. # Note: All files created in this section are written in binary
  1654. # mode to prevent any posibility of misinterpreted line endings.
  1655. # I don't know if Dev-C++ is as touchy as MSVC with LF-only line
  1656. # endings. But however, CRLF line endings are the common way on
  1657. # Win32 machines where Dev-C++ is running.
  1658. # Hence, in order for mkfiles.pl to generate CRLF project files
  1659. # even when run from Unix, I make sure all files are binary and
  1660. # explicitly write the CRLFs.
  1661. #
  1662. # Create directories if necessary
  1663. mkdir $makefiles{'devcppproj'}
  1664. if(! -d $makefiles{'devcppproj'});
  1665. chdir $makefiles{'devcppproj'};
  1666. @deps = &deps("X.obj", "X.res", $dirpfx, "\\", "devcppproj");
  1667. %all_object_deps = map {$_->{obj} => $_->{deps}} @deps;
  1668. # Make dir names FAT/NTFS compatible
  1669. my @srcdirs = @srcdirs;
  1670. for ($i=0; $i<@srcdirs; $i++) {
  1671. $srcdirs[$i] =~ s/\//\\/g;
  1672. $srcdirs[$i] =~ s/\\$//;
  1673. }
  1674. # Create the project files
  1675. # Get names of all Windows projects (GUI and console)
  1676. my @prognames = &prognames("G:C");
  1677. foreach $progname (@prognames) {
  1678. create_devcpp_project(\%all_object_deps, $progname);
  1679. }
  1680. chdir $orig_dir;
  1681. sub create_devcpp_project {
  1682. my ($all_object_deps, $progname) = @_;
  1683. # Construct program's dependency info (Taken from 'vcproj', seems to work right here, too.)
  1684. %seen_objects = ();
  1685. %lib_files = ();
  1686. %source_files = ();
  1687. %header_files = ();
  1688. %resource_files = ();
  1689. @object_files = split " ", &objects($progname, "X.obj", "X.res", "X.lib");
  1690. foreach $object_file (@object_files) {
  1691. next if defined $seen_objects{$object_file};
  1692. $seen_objects{$object_file} = 1;
  1693. if($object_file =~ /\.lib$/io) {
  1694. $lib_files{$object_file} = 1;
  1695. next;
  1696. }
  1697. $object_deps = $all_object_deps{$object_file};
  1698. foreach $object_dep (@$object_deps) {
  1699. if($object_dep =~ /\.c$/io) {
  1700. $source_files{$object_dep} = 1;
  1701. next;
  1702. }
  1703. if($object_dep =~ /\.h$/io) {
  1704. $header_files{$object_dep} = 1;
  1705. next;
  1706. }
  1707. if($object_dep =~ /\.(rc|ico)$/io) {
  1708. $resource_files{$object_dep} = 1;
  1709. next;
  1710. }
  1711. }
  1712. }
  1713. $libs = join " ", sort keys %lib_files;
  1714. @source_files = sort keys %source_files;
  1715. @header_files = sort keys %header_files;
  1716. @resources = sort keys %resource_files;
  1717. ($windows_project, $type) = split ",", $progname;
  1718. mkdir $windows_project
  1719. if(! -d $windows_project);
  1720. chdir $windows_project;
  1721. $subsys = ($type eq "G") ? "0" : "1"; # 0 = Win32 GUI, 1 = Win32 Console
  1722. open OUT, ">$windows_project.dev"; binmode OUT; select OUT;
  1723. print
  1724. "# DEV-C++ 5 Project File - $windows_project.dev\r\n".
  1725. "# ** DO NOT EDIT **\r\n".
  1726. "\r\n".
  1727. # No difference between DEBUG and RELEASE here as in 'vcproj', because
  1728. # Dev-C++ does not support mutiple compilation profiles in one single project.
  1729. # (At least I can say this for Dev-C++ 5 Beta)
  1730. "[Project]\r\n".
  1731. "FileName=$windows_project.dev\r\n".
  1732. "Name=$windows_project\r\n".
  1733. "Ver=1\r\n".
  1734. "IsCpp=1\r\n".
  1735. "Type=$subsys\r\n".
  1736. # Multimon is disabled here, as Dev-C++ (Version 5 Beta) does not have multimon.h
  1737. "Compiler=-W -D__GNUWIN32__ -DWIN32 -DNDEBUG -D_WINDOWS -DNO_MULTIMON -D_MBCS_\@\@_\r\n".
  1738. "CppCompiler=-W -D__GNUWIN32__ -DWIN32 -DNDEBUG -D_WINDOWS -DNO_MULTIMON -D_MBCS_\@\@_\r\n".
  1739. "Includes=" . (join ";", map {"..\\..\\$dirpfx$_"} @srcdirs) . "\r\n".
  1740. "Linker=-ladvapi32 -lcomctl32 -lcomdlg32 -lgdi32 -limm32 -lshell32 -luser32 -lwinmm -lwinspool_\@\@_\r\n".
  1741. "Libs=\r\n".
  1742. "UnitCount=" . (@source_files + @header_files + @resources) . "\r\n".
  1743. "Folders=\"Header Files\",\"Resource Files\",\"Source Files\"\r\n".
  1744. "ObjFiles=\r\n".
  1745. "PrivateResource=${windows_project}_private.rc\r\n".
  1746. "ResourceIncludes=..\\..\\..\\WINDOWS\r\n".
  1747. "MakeIncludes=\r\n".
  1748. "Icon=\r\n". # It's ok to leave this blank.
  1749. "ExeOutput=\r\n".
  1750. "ObjectOutput=\r\n".
  1751. "OverrideOutput=0\r\n".
  1752. "OverrideOutputName=$windows_project.exe\r\n".
  1753. "HostApplication=\r\n".
  1754. "CommandLine=\r\n".
  1755. "UseCustomMakefile=0\r\n".
  1756. "CustomMakefile=\r\n".
  1757. "IncludeVersionInfo=0\r\n".
  1758. "SupportXPThemes=0\r\n".
  1759. "CompilerSet=0\r\n".
  1760. "CompilerSettings=0000000000000000000000\r\n".
  1761. "\r\n";
  1762. $unit_count = 1;
  1763. foreach $source_file (@source_files) {
  1764. print
  1765. "[Unit$unit_count]\r\n".
  1766. "FileName=..\\..\\$source_file\r\n".
  1767. "Folder=Source Files\r\n".
  1768. "Compile=1\r\n".
  1769. "CompileCpp=0\r\n".
  1770. "Link=1\r\n".
  1771. "Priority=1000\r\n".
  1772. "OverrideBuildCmd=0\r\n".
  1773. "BuildCmd=\r\n".
  1774. "\r\n";
  1775. $unit_count++;
  1776. }
  1777. foreach $header_file (@header_files) {
  1778. print
  1779. "[Unit$unit_count]\r\n".
  1780. "FileName=..\\..\\$header_file\r\n".
  1781. "Folder=Header Files\r\n".
  1782. "Compile=1\r\n".
  1783. "CompileCpp=1\r\n". # Dev-C++ want's to compile all header files with both compilers C and C++. It does not hurt.
  1784. "Link=1\r\n".
  1785. "Priority=1000\r\n".
  1786. "OverrideBuildCmd=0\r\n".
  1787. "BuildCmd=\r\n".
  1788. "\r\n";
  1789. $unit_count++;
  1790. }
  1791. foreach $resource_file (@resources) {
  1792. if ($resource_file =~ /.*\.(ico|cur|bmp|dlg|rc2|rct|bin|rgs|gif|jpg|jpeg|jpe)/io) { # Default filter as in 'vcproj'
  1793. $Compile = "0"; # Don't compile images and other binary resource files
  1794. $CompileCpp = "0";
  1795. } else {
  1796. $Compile = "1";
  1797. $CompileCpp = "1"; # Dev-C++ want's to compile all .rc files with both compilers C and C++. It does not hurt.
  1798. }
  1799. print
  1800. "[Unit$unit_count]\r\n".
  1801. "FileName=..\\..\\$resource_file\r\n".
  1802. "Folder=Resource Files\r\n".
  1803. "Compile=$Compile\r\n".
  1804. "CompileCpp=$CompileCpp\r\n".
  1805. "Link=0\r\n".
  1806. "Priority=1000\r\n".
  1807. "OverrideBuildCmd=0\r\n".
  1808. "BuildCmd=\r\n".
  1809. "\r\n";
  1810. $unit_count++;
  1811. }
  1812. #Note: By default, [VersionInfo] is not used.
  1813. print
  1814. "[VersionInfo]\r\n".
  1815. "Major=0\r\n".
  1816. "Minor=0\r\n".
  1817. "Release=1\r\n".
  1818. "Build=1\r\n".
  1819. "LanguageID=1033\r\n".
  1820. "CharsetID=1252\r\n".
  1821. "CompanyName=\r\n".
  1822. "FileVersion=0.1\r\n".
  1823. "FileDescription=\r\n".
  1824. "InternalName=\r\n".
  1825. "LegalCopyright=\r\n".
  1826. "LegalTrademarks=\r\n".
  1827. "OriginalFilename=$windows_project.exe\r\n".
  1828. "ProductName=$windows_project\r\n".
  1829. "ProductVersion=0.1\r\n".
  1830. "AutoIncBuildNr=0\r\n";
  1831. select STDOUT; close OUT;
  1832. chdir "..";
  1833. }
  1834. }
  1835. # All done, so do the Unix postprocessing if asked to.
  1836. if ($do_unix) {
  1837. chdir $orig_dir;
  1838. system "./mkauto.sh";
  1839. die "mkfiles.pl: mkauto.sh returned $?\n" if $? > 0;
  1840. if ($do_unix == 1) {
  1841. chdir ($targetdir = "unix")
  1842. or die "$targetdir: chdir: $!\n";
  1843. }
  1844. system "./configure", @confargs;
  1845. die "mkfiles.pl: configure returned $?\n" if $? > 0;
  1846. }
  1847. sub invent_guid($) {
  1848. my ($name) = @_;
  1849. # Invent a GUID for use in Visual Studio project files. We need
  1850. # a few of these for every executable file we build.
  1851. #
  1852. # In order to avoid having to use the non-core Perl module
  1853. # Data::GUID, and also arrange for GUIDs to be stable, we generate
  1854. # our GUIDs by hashing a pile of fixed (but originally randomly
  1855. # generated) data with the filename for which we need an id.
  1856. #
  1857. # Hashing _just_ the filenames would clearly be cheating (it's
  1858. # quite conceivable that someone might hash the same string for
  1859. # another reason and so generate a colliding GUID), but hashing a
  1860. # whole SHA-512 data block of random gibberish as well should make
  1861. # these GUIDs pseudo-random enough to not collide with anyone
  1862. # else's.
  1863. my $randdata = pack "N*",
  1864. 0xD4AB035F,0x76998BA0,0x2DCCB0BD,0x6D3FA320,0x53638051,0xFE312F35,
  1865. 0xDE1CECC0,0x784DF852,0x6C9F4589,0x54B7AC23,0x14E7A1C4,0xF9BF04DF,
  1866. 0x19C08B6D,0x3FB69EF1,0xB2DA9043,0xDB5362F3,0x25718DB6,0x733560DA,
  1867. 0xFEF871B0,0xFECF7A0C,0x67D19C95,0xB492E911,0xF5D562A3,0xFCE1D478,
  1868. 0x02C50434,0xF7326B7E,0x93D39872,0xCF0D0269,0x9EF24C0F,0x827689AD,
  1869. 0x88BD20BC,0x74EA6AFE,0x29223682,0xB9AB9287,0x7EA7CE4F,0xCF81B379,
  1870. 0x9AE4A954,0x81C7AD97,0x2FF2F031,0xC51DA3C2,0xD311CCE7,0x0A31EB8B,
  1871. 0x1AB04242,0xAF53B714,0xFC574D40,0x8CB4ED01,0x29FEB16F,0x4904D7ED,
  1872. 0xF5C5F5E1,0xF138A4C2,0xA9D881CE,0xCEA65187,0x4421BA97,0x0EE8428E,
  1873. 0x9556E384,0x6D0484C9,0x561BD84B,0xD9516A40,0x6B4FD33F,0xDDFFE4C8,
  1874. 0x3D5DF8A5,0xFE6B7D99,0x3443371B,0xF4E30A3E,0xE62B9FDA,0x6BAA75DB,
  1875. 0x9EF3C2C7,0x6815CA42,0xE6536076,0xF851E6E2,0x39D16E69,0xBCDF3BB6,
  1876. 0x50EFFA41,0x378CDF2A,0xB5EC0D0C,0x1E94C433,0xE818241A,0x2689EB1F,
  1877. 0xB649CEF9,0xD7344D46,0x59C1BB13,0x27511FDF,0x7DAD1768,0xB355E29E,
  1878. 0xDFAE550C,0x2433005B,0x09DE10B0,0xAA00BA6B,0xC144ED2D,0x8513D007,
  1879. 0xB0315232,0x7A10DAB6,0x1D97654E,0xF048214D,0xE3059E75,0x83C225D1,
  1880. 0xFC7AB177,0x83F2B553,0x79F7A0AF,0x1C94582C,0xF5E4AF4B,0xFB39C865,
  1881. 0x58ABEB27,0xAAB28058,0x52C15A89,0x0EBE9741,0x343F4D26,0xF941202A,
  1882. 0xA32FD32F,0xDCC055B8,0x64281BF3,0x468BD7BA,0x0CEE09D3,0xBB5FD2B6,
  1883. 0xA528D412,0xA6A6967E,0xEAAF5DAE,0xDE7B2FAE,0xCA36887B,0x0DE196EB,
  1884. 0x74B95EF0,0x9EB8B7C2,0x020BFC83,0x1445086F,0xBF4B61B2,0x89AFACEC,
  1885. 0x80A5CD69,0xC790F744,0x435A6998,0x8DE7AC48,0x32F31BC9,0x8F760D3D,
  1886. 0xF02A74CB,0xD7B47E20,0x9EC91035,0x70FDE74D,0x9B531362,0x9D81739A,
  1887. 0x59ADC2EB,0x511555B5,0xCA84B8D5,0x3EC325FF,0x2E442A4C,0x82AF30D9,
  1888. 0xBFD3EC87,0x90C59E07,0x1C6DC991,0x2D16B822,0x7EA44EB5,0x3A655A39,
  1889. 0xAB640886,0x09311821,0x777801D9,0x489DBE61,0xA1FFEC65,0x978B49B1,
  1890. 0x7DB700CD,0x263CF3D6,0xF977E89F,0xBA0B3D01,0x6C6CED19,0x1BE6F23A,
  1891. 0x19E0ED98,0x8E71A499,0x70BA3271,0x3FB7EE98,0xABA46848,0x2B797959,
  1892. 0x72C6DE59,0xE08B795C,0x02936C39,0x02185CCB,0xD6F3CE18,0xD0157A40,
  1893. 0x833DEC3F,0x319B00C4,0x97B59513,0x900B81FD,0x9A022379,0x16E44E1A,
  1894. 0x0C4CC540,0xCA98E7F9,0xF9431A26,0x290BCFAC,0x406B82C0,0xBC1C4585,
  1895. 0x55C54528,0x811EBB77,0xD4EDD4F3,0xA70DC02E,0x8AD5C0D1,0x28D64EF4,
  1896. 0xBEFF5C69,0x99852C4A,0xB4BBFF7B,0x069230AC,0xA3E141FA,0x4E99FB0E,
  1897. 0xBC154DAA,0x323C7F15,0x86E0247E,0x2EEA3054,0xC9CA1D32,0x8964A006,
  1898. 0xC93978AC,0xF9B2C159,0x03F2079E,0xB051D284,0x4A7EA9A9,0xF001DA1F,
  1899. 0xD47A0DAA,0xCF7B6B73,0xF18293B2,0x84303E34,0xF8BC76C4,0xAFBEE24F,
  1900. 0xB589CA80,0x77B5BF86,0x21B9FD5B,0x1A5071DF,0xA3863110,0x0E50CA61,
  1901. 0x939151A5,0xD2A59021,0x83A9CDCE,0xCEC69767,0xC906BB16,0x3EE1FF4D,
  1902. 0x1321EAE4,0x0BF940D6,0x52471E61,0x8A087056,0x66E54293,0xF84AAB9B,
  1903. 0x08835EF1,0x8F12B77A,0xD86935A5,0x200281D7,0xCD3C37C9,0x30ABEC05,
  1904. 0x7067E8A0,0x608C4838,0xC9F51CDE,0xA6D318DE,0x41C05B2A,0x694CCE0E,
  1905. 0xC7842451,0xA3194393,0xFBDC2C84,0xA6D2B577,0xC91E7924,0x01EDA708,
  1906. 0x22FBB61E,0x662F9B7B,0xDE3150C3,0x2397058C;
  1907. my $digest = sha512_hex($name . "\0" . $randdata);
  1908. return sprintf("%s-%s-%04x-%04x-%s",
  1909. substr($digest,0,8),
  1910. substr($digest,8,4),
  1911. 0x4000 | (0xFFF & hex(substr($digest,12,4))),
  1912. 0x8000 | (0x3FFF & hex(substr($digest,16,4))),
  1913. substr($digest,20,12));
  1914. }