mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
Files

To begin with, the toolchain no longer lets me build for x86-32 - apparently MacOS is now 64-bit only. Also, the linker now gives an error about a missing libgcc_s variant for -mmacosx-version-min=10.4, and indeed 10.5. So I've bumped the minimum supported OS version to 10.6. That in turn required some changes in osx.m itself, because bumping the min OS version caused some API deprecations to show up. Luckily I turned out to have left myself a comment some time ago telling me what I was going to need to do about one of them :-)
1954 lines
70 KiB
Perl
Executable File
1954 lines
70 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
#
|
|
# Cross-platform Makefile generator.
|
|
#
|
|
# Reads the file `Recipe' to determine the list of generated
|
|
# executables and their component objects. Then reads the source
|
|
# files to compute #include dependencies. Finally, writes out the
|
|
# various target Makefiles.
|
|
|
|
# PuTTY specifics which could still do with removing:
|
|
# - Mac makefile is not portabilised at all. Include directories
|
|
# are hardwired, and also the libraries are fixed. This is
|
|
# mainly because I was too scared to go anywhere near it.
|
|
# - sbcsgen.pl is still run at startup.
|
|
|
|
# Other things undone:
|
|
# - special-define objects (foo.o[PREPROCSYMBOL]) are not
|
|
# supported in the mac or vcproj makefiles.
|
|
|
|
use warnings;
|
|
use IO::Handle;
|
|
use Cwd;
|
|
use File::Basename;
|
|
|
|
while ($#ARGV >= 0) {
|
|
if ($ARGV[0] eq "-U") {
|
|
# Convenience for Unix users: -U means that after we finish what
|
|
# we're doing here, we also run mkauto.sh and then 'configure'. So
|
|
# it's a one-stop shop for regenerating the actual end-product
|
|
# Unix makefile.
|
|
#
|
|
# Arguments supplied after -U go to configure.
|
|
$do_unix = 1;
|
|
shift @ARGV;
|
|
@confargs = @ARGV;
|
|
@ARGV = ();
|
|
} else {
|
|
die "unrecognised command-line argument '$ARGV[0]'\n";
|
|
}
|
|
}
|
|
|
|
@filestack = ();
|
|
$in = new IO::Handle;
|
|
open $in, "Recipe" or do {
|
|
# We want to deal correctly with being run from one of the
|
|
# subdirs in the source tree. So if we can't find Recipe here,
|
|
# try one level up.
|
|
chdir "..";
|
|
open $in, "Recipe" or die "unable to open Recipe file\n";
|
|
};
|
|
push @filestack, $in;
|
|
|
|
# HACK: One of the source files in `charset' is auto-generated by
|
|
# sbcsgen.pl. We need to generate that _now_, before attempting
|
|
# dependency analysis.
|
|
eval 'chdir "charset"; require "sbcsgen.pl"; chdir ".."';
|
|
|
|
@srcdirs = ("./");
|
|
|
|
$divert = undef; # ref to array of refs of scalars in which text is
|
|
# currently being put
|
|
$help = ""; # list of newline-free lines of help text
|
|
$project_name = "project"; # this is a good enough default
|
|
%makefiles = (); # maps makefile types to output makefile pathnames
|
|
%makefile_extra = (); # maps makefile types to extra Makefile text
|
|
%programs = (); # maps prog name + type letter to listref of objects/resources
|
|
%groups = (); # maps group name to listref of objects/resources
|
|
|
|
@allobjs = (); # all object file names
|
|
|
|
readinput: while (1) {
|
|
$in = $filestack[$#filestack];
|
|
while (not defined ($_ = <$in>)) {
|
|
close $filestack[$#filestack];
|
|
pop @filestack;
|
|
last readinput if 0 == scalar @filestack;
|
|
$in = $filestack[$#filestack];
|
|
}
|
|
chomp;
|
|
@_ = split;
|
|
|
|
# If we're gathering help text, keep doing so.
|
|
if (defined $divert) {
|
|
if ((defined $_[0]) && $_[0] eq "!end") {
|
|
$divert = undef;
|
|
} else {
|
|
for my $ref (@$divert) {
|
|
${$ref} .= "$_\n";
|
|
}
|
|
}
|
|
next;
|
|
}
|
|
# Skip comments and blank lines.
|
|
next if /^\s*#/ or scalar @_ == 0;
|
|
|
|
if ($_[0] eq "!begin" and $_[1] eq "help") { $divert = [\$help]; next; }
|
|
if ($_[0] eq "!name") { $project_name = $_[1]; next; }
|
|
if ($_[0] eq "!srcdir") { push @srcdirs, $_[1]; next; }
|
|
if ($_[0] eq "!makefile" and &mfval($_[1])) { $makefiles{$_[1]}=$_[2]; next;}
|
|
if ($_[0] eq "!specialobj" and &mfval($_[1])) { $specialobj{$_[1]}->{$_[2]} = 1; next;}
|
|
if ($_[0] eq "!cflags" and &mfval($_[1])) {
|
|
($rest = $_) =~ s/^\s*\S+\s+\S+\s+\S+\s*//; # find rest of input line
|
|
$rest = 1 if $rest eq "";
|
|
$cflags{$_[1]}->{$_[2]} = $rest;
|
|
next;
|
|
}
|
|
if ($_[0] eq "!begin") {
|
|
my @args = @_;
|
|
shift @args;
|
|
$divert = [];
|
|
for my $component (@args) {
|
|
if ($component =~ /^>(.*)/) {
|
|
push @$divert, \$auxfiles{$1};
|
|
} elsif ($component =~ /^([^_]*)(_.*)?$/ and &mfval($1)) {
|
|
push @$divert, \$makefile_extra{$component};
|
|
}
|
|
}
|
|
next;
|
|
}
|
|
if ($_[0] eq "!include") {
|
|
@newfiles = ();
|
|
for ($i = 1; $i <= $#_; $i++) {
|
|
push @newfiles, (sort glob $_[$i]);
|
|
}
|
|
for ($i = $#newfiles; $i >= 0; $i--) {
|
|
$file = $newfiles[$i];
|
|
$f = new IO::Handle;
|
|
open $f, "<$file" or die "unable to open include file '$file'\n";
|
|
push @filestack, $f;
|
|
}
|
|
next;
|
|
}
|
|
|
|
# Now we have an ordinary line. See if it's an = line, a : line
|
|
# or a + line.
|
|
@objs = @_;
|
|
|
|
if ($_[0] eq "+") {
|
|
$listref = $lastlistref;
|
|
$prog = undef;
|
|
die "$.: unexpected + line\n" if !defined $lastlistref;
|
|
} elsif ($_[1] eq "=") {
|
|
$groups{$_[0]} = [];
|
|
$listref = $groups{$_[0]};
|
|
$prog = undef;
|
|
shift @objs; # eat the group name
|
|
} elsif ($_[1] eq "+=") {
|
|
$groups{$_[0]} = [] if !defined $groups{$_[0]};
|
|
$listref = $groups{$_[0]};
|
|
$prog = undef;
|
|
shift @objs; # eat the group name
|
|
} elsif ($_[1] eq ":") {
|
|
$listref = [];
|
|
$prog = $_[0];
|
|
shift @objs; # eat the program name
|
|
} else {
|
|
die "$.: unrecognised line type: '$_'\n";
|
|
}
|
|
shift @objs; # eat the +, the = or the :
|
|
|
|
while (scalar @objs > 0) {
|
|
$i = shift @objs;
|
|
if ($groups{$i}) {
|
|
foreach $j (@{$groups{$i}}) { unshift @objs, $j; }
|
|
} elsif (($i eq "[G]" or $i eq "[C]" or $i eq "[M]" or
|
|
$i eq "[X]" or $i eq "[U]" or $i eq "[MX]") and defined $prog) {
|
|
$type = substr($i,1,(length $i)-2);
|
|
} else {
|
|
if ($i =~ /\?$/) {
|
|
# Object files with a trailing question mark are optional:
|
|
# the build can proceed fine without them, so we only use
|
|
# them if their primary source files are present.
|
|
$i =~ s/\?$//;
|
|
$i = undef unless defined &finddep($i);
|
|
} elsif ($i =~ /\|/) {
|
|
# Object file descriptions containing a vertical bar are
|
|
# lists of choices: we use the _first_ one whose primary
|
|
# source file is present.
|
|
@options = split /\|/, $i;
|
|
$j = undef;
|
|
foreach $k (@options) {
|
|
$j=$k, last if defined &finddep($k);
|
|
}
|
|
die "no alternative found for $i\n" unless defined $j;
|
|
$i = $j;
|
|
}
|
|
if (defined $i) {
|
|
push @$listref, $i;
|
|
push @allobjs, $i;
|
|
}
|
|
}
|
|
}
|
|
if ($prog and $type) {
|
|
die "multiple program entries for $prog [$type]\n"
|
|
if defined $programs{$prog . "," . $type};
|
|
$programs{$prog . "," . $type} = $listref;
|
|
}
|
|
$lastlistref = $listref;
|
|
}
|
|
|
|
foreach $aux (sort keys %auxfiles) {
|
|
open AUX, ">$aux";
|
|
print AUX $auxfiles{$aux};
|
|
close AUX;
|
|
}
|
|
|
|
# Find object file names with predefines (in square brackets after
|
|
# the module name), and decide on actual object names for them.
|
|
foreach $i (@allobjs) {
|
|
if ($i !~ /\[/) {
|
|
$objname{$i} = $i;
|
|
$srcname{$i} = $i;
|
|
$usedobjname{$i} = 1;
|
|
}
|
|
}
|
|
foreach $i (@allobjs) {
|
|
if ($i =~ /^(.*)\[([^\]]*)/) {
|
|
$defs{$i} = [ split ",",$2 ];
|
|
$srcname{$i} = $s = $1;
|
|
$index = 1;
|
|
while (1) {
|
|
$maxlen = length $s;
|
|
$maxlen = 8 if $maxlen < 8;
|
|
$chop = $maxlen - length $index;
|
|
$chop = length $s if $chop > length $s;
|
|
$chop = 0 if $chop < 0;
|
|
$name = substr($s, 0, $chop) . $index;
|
|
$index++, next if $usedobjname{$name};
|
|
$objname{$i} = $name;
|
|
$usedobjname{$name} = 1;
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
|
|
# Now retrieve the complete list of objects and resource files, and
|
|
# construct dependency data for them. While we're here, expand the
|
|
# object list for each program, and complain if its type isn't set.
|
|
@prognames = sort keys %programs;
|
|
%depends = ();
|
|
@scanlist = ();
|
|
foreach $i (@prognames) {
|
|
($prog, $type) = split ",", $i;
|
|
# Strip duplicate object names.
|
|
$prev = '';
|
|
@list = grep { $status = ($prev ne $_); $prev=$_; $status }
|
|
sort @{$programs{$i}};
|
|
$programs{$i} = [@list];
|
|
foreach $jj (@list) {
|
|
$j = $srcname{$jj};
|
|
$file = &finddep($j);
|
|
if (defined $file) {
|
|
$depends{$jj} = [$file];
|
|
push @scanlist, $file;
|
|
}
|
|
}
|
|
}
|
|
|
|
# Scan each file on @scanlist and find further inclusions.
|
|
# Inclusions are given by lines of the form `#include "otherfile"'
|
|
# (system headers are automatically ignored by this because they'll
|
|
# be given in angle brackets). Files included by this method are
|
|
# added back on to @scanlist to be scanned in turn (if not already
|
|
# done).
|
|
#
|
|
# Resource scripts (.rc) can also include a file by means of a line
|
|
# ending `ICON "filename"'. Files included by this method are not
|
|
# added to @scanlist because they can never include further files.
|
|
#
|
|
# In this pass we write out a hash %further which maps a source
|
|
# file name into a listref containing further source file names.
|
|
|
|
%further = ();
|
|
while (scalar @scanlist > 0) {
|
|
$file = shift @scanlist;
|
|
next if defined $further{$file}; # skip if we've already done it
|
|
$further{$file} = [];
|
|
$dirfile = &findfile($file);
|
|
open IN, "$dirfile" or die "unable to open source file $file\n";
|
|
while (<IN>) {
|
|
chomp;
|
|
/^\s*#include\s+\"([^\"]+)\"/ and do {
|
|
push @{$further{$file}}, $1;
|
|
push @scanlist, $1;
|
|
next;
|
|
};
|
|
/ICON\s+\"([^\"]+)\"\s*$/ and do {
|
|
push @{$further{$file}}, $1;
|
|
next;
|
|
}
|
|
}
|
|
close IN;
|
|
}
|
|
|
|
# Now we're ready to generate the final dependencies section. For
|
|
# each key in %depends, we must expand the dependencies list by
|
|
# iteratively adding entries from %further.
|
|
foreach $i (keys %depends) {
|
|
%dep = ();
|
|
@scanlist = @{$depends{$i}};
|
|
foreach $i (@scanlist) { $dep{$i} = 1; }
|
|
while (scalar @scanlist > 0) {
|
|
$file = shift @scanlist;
|
|
foreach $j (@{$further{$file}}) {
|
|
if (!$dep{$j}) {
|
|
$dep{$j} = 1;
|
|
push @{$depends{$i}}, $j;
|
|
push @scanlist, $j;
|
|
}
|
|
}
|
|
}
|
|
# printf "%s: %s\n", $i, join ' ',@{$depends{$i}};
|
|
}
|
|
|
|
# Validation of input.
|
|
|
|
sub mfval($) {
|
|
my ($type) = @_;
|
|
# Returns true if the argument is a known makefile type. Otherwise,
|
|
# prints a warning and returns false;
|
|
if (grep { $type eq $_ }
|
|
("vc","vcproj","cygwin","borland","lcc","gtk","am","mpw","nestedvm","osx","wce","gnustep","emcc","clangcl")) {
|
|
return 1;
|
|
}
|
|
warn "$.:unknown makefile type '$type'\n";
|
|
return 0;
|
|
}
|
|
|
|
# Utility routines while writing out the Makefiles.
|
|
|
|
sub dirpfx {
|
|
my ($path) = shift @_;
|
|
my ($sep) = shift @_;
|
|
my $ret = "";
|
|
my $i;
|
|
while (($i = index $path, $sep) >= 0) {
|
|
$path = substr $path, ($i + length $sep);
|
|
$ret .= "..$sep";
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
sub findfile {
|
|
my ($name) = @_;
|
|
my $dir;
|
|
my $i;
|
|
my $outdir = undef;
|
|
unless (defined $findfilecache{$name}) {
|
|
$i = 0;
|
|
foreach $dir (@srcdirs) {
|
|
$outdir = $dir, $i++ if -f "$dir$name";
|
|
}
|
|
die "multiple instances of source file $name\n" if $i > 1;
|
|
$findfilecache{$name} = (defined $outdir ? $outdir . $name : undef);
|
|
}
|
|
return $findfilecache{$name};
|
|
}
|
|
|
|
sub finddep {
|
|
my $j = shift @_;
|
|
my $file;
|
|
# Find the first dependency of an object.
|
|
|
|
# Dependencies for "x" start with "x.c" or "x.m" (depending on
|
|
# which one exists).
|
|
# Dependencies for "x.res" start with "x.rc".
|
|
# Dependencies for "x.rsrc" start with "x.r".
|
|
# Both types of file are pushed on the list of files to scan.
|
|
# Libraries (.lib) don't have dependencies at all.
|
|
if ($j =~ /^(.*)\.res$/) {
|
|
$file = "$1.rc";
|
|
} elsif ($j =~ /^(.*)\.rsrc$/) {
|
|
$file = "$1.r";
|
|
} elsif ($j !~ /\./) {
|
|
$file = "$j.c";
|
|
$file = "$j.m" unless &findfile($file);
|
|
} else {
|
|
# For everything else, we assume it's its own dependency.
|
|
$file = $j;
|
|
}
|
|
$file = undef unless &findfile($file);
|
|
return $file;
|
|
}
|
|
|
|
sub objects {
|
|
my ($prog, $otmpl, $rtmpl, $ltmpl, $prefix, $dirsep) = @_;
|
|
my @ret;
|
|
my ($i, $x, $y);
|
|
($otmpl, $rtmpl, $ltmpl) = map { defined $_ ? $_ : "" } ($otmpl, $rtmpl, $ltmpl);
|
|
@ret = ();
|
|
foreach $ii (@{$programs{$prog}}) {
|
|
$i = $objname{$ii};
|
|
$x = "";
|
|
if ($i =~ /^(.*)\.(res|rsrc)/) {
|
|
$y = $1;
|
|
($x = $rtmpl) =~ s/X/$y/;
|
|
} elsif ($i =~ /^(.*)\.lib/) {
|
|
$y = $1;
|
|
($x = $ltmpl) =~ s/X/$y/;
|
|
} elsif ($i !~ /\./) {
|
|
($x = $otmpl) =~ s/X/$i/;
|
|
}
|
|
push @ret, $x if $x ne "";
|
|
}
|
|
return join " ", @ret;
|
|
}
|
|
|
|
sub special {
|
|
my ($prog, $suffix) = @_;
|
|
my @ret;
|
|
my ($i, $x, $y);
|
|
@ret = ();
|
|
foreach $ii (@{$programs{$prog}}) {
|
|
$i = $objname{$ii};
|
|
if (substr($i, (length $i) - (length $suffix)) eq $suffix) {
|
|
push @ret, $i;
|
|
}
|
|
}
|
|
return join " ", @ret;
|
|
}
|
|
|
|
sub splitline {
|
|
my ($line, $width, $splitchar) = @_;
|
|
my $result = "";
|
|
my $len;
|
|
$len = (defined $width ? $width : 76);
|
|
$splitchar = (defined $splitchar ? $splitchar : '\\');
|
|
while (length $line > $len) {
|
|
$line =~ /^(.{0,$len})\s(.*)$/ or $line =~ /^(.{$len,}?\s(.*)$/;
|
|
$result .= $1;
|
|
$result .= " ${splitchar}\n\t\t" if $2 ne '';
|
|
$line = $2;
|
|
$len = 60;
|
|
}
|
|
return $result . $line;
|
|
}
|
|
|
|
sub deps {
|
|
my ($otmpl, $rtmpl, $prefix, $dirsep, $depchar, $splitchar) = @_;
|
|
my ($i, $x, $y);
|
|
my @deps;
|
|
my @ret;
|
|
@ret = ();
|
|
$depchar ||= ':';
|
|
foreach $ii (sort keys %depends) {
|
|
$i = $objname{$ii};
|
|
next if $specialobj{$mftyp}->{$i};
|
|
if ($i =~ /^(.*)\.(res|rsrc)/) {
|
|
next if !defined $rtmpl;
|
|
$y = $1;
|
|
($x = $rtmpl) =~ s/X/$y/;
|
|
} else {
|
|
($x = $otmpl) =~ s/X/$i/;
|
|
}
|
|
@deps = @{$depends{$ii}};
|
|
# Skip things which are their own dependency.
|
|
next if grep { $_ eq $i } @deps;
|
|
@deps = map {
|
|
$_ = &findfile($_);
|
|
s/\//$dirsep/g;
|
|
$_ = $prefix . $_;
|
|
} @deps;
|
|
push @ret, {obj => $x, deps => [@deps], defs => $defs{$ii}};
|
|
}
|
|
return @ret;
|
|
}
|
|
|
|
sub prognames {
|
|
my ($types) = @_;
|
|
my ($n, $prog, $type);
|
|
my @ret;
|
|
@ret = ();
|
|
foreach $n (@prognames) {
|
|
($prog, $type) = split ",", $n;
|
|
push @ret, $n if index(":$types:", ":$type:") >= 0;
|
|
}
|
|
return @ret;
|
|
}
|
|
|
|
sub progrealnames {
|
|
my ($types) = @_;
|
|
my ($n, $prog, $type);
|
|
my @ret;
|
|
@ret = ();
|
|
foreach $n (@prognames) {
|
|
($prog, $type) = split ",", $n;
|
|
push @ret, $prog if index(":$types:", ":$type:") >= 0;
|
|
}
|
|
return @ret;
|
|
}
|
|
|
|
sub manpages {
|
|
my ($types,$suffix) = @_;
|
|
|
|
# assume that all UNIX programs have a man page
|
|
if($suffix eq "1" && $types =~ /:X:/) {
|
|
return map("$_.1", &progrealnames($types));
|
|
}
|
|
return ();
|
|
}
|
|
|
|
$orig_dir = cwd;
|
|
|
|
# Now we're ready to output the actual Makefiles.
|
|
|
|
if (defined $makefiles{'clangcl'}) {
|
|
$mftyp = 'clangcl';
|
|
$dirpfx = &dirpfx($makefiles{'clangcl'}, "/");
|
|
|
|
##-- Makefile for cross-compiling using clang-cl, lld-link, and
|
|
## MinGW's windres for resource compilation.
|
|
#
|
|
# This makefile allows a complete Linux-based cross-compile, but
|
|
# using the real Visual Studio header files and libraries. In
|
|
# order to run it, you will need:
|
|
#
|
|
# - MinGW windres on your PATH.
|
|
# * On Ubuntu as of 16.04, you can apt-get install
|
|
# binutils-mingw-w64-x86-64 and binutils-mingw-w64-i686
|
|
# which will provide (respectively) 64- and 32-bit versions,
|
|
# under the names to which RCCMD is defined below.
|
|
# - clang-cl and lld-link on your PATH.
|
|
# * I built these from the up-to-date LLVM project trunk git
|
|
# repositories, as of 2017-02-05.
|
|
# - case-mashed copies of the Visual Studio include directories.
|
|
# * On a real VS installation, run vcvars32.bat and look at
|
|
# the resulting value of %INCLUDE%. Take a full copy of each
|
|
# of those directories, and inside the copy, for each
|
|
# include file that has an uppercase letter in its name,
|
|
# make a lowercased symlink to it. Additionally, one of the
|
|
# directories will contain files called driverspecs.h and
|
|
# specstrings.h, and those will need symlinks called
|
|
# DriverSpecs.h and SpecStrings.h.
|
|
# * Now, on Linux, define the environment variable INCLUDE to
|
|
# be a list, separated by *semicolons* (in the Windows
|
|
# style), of those directories, but before all of them you
|
|
# must also include lib/clang/5.0.0/include from the clang
|
|
# installation area (which contains in particular a
|
|
# clang-compatible stdarg.h overriding the Visual Studio
|
|
# one).
|
|
# - similarly case-mashed copies of the library directories.
|
|
# * Again, on a real VS installation, run vcvars32 or
|
|
# vcvarsx86_amd64 (as appropriate), look at %LIB%, make a
|
|
# copy of each directory, and provide symlinks within that
|
|
# directory so that all the files can be opened as
|
|
# lowercase.
|
|
# * Then set LIB to be a semicolon-separated list of those
|
|
# directories (but you'll need to change which set of
|
|
# directories depending on whether you want to do a 32-bit
|
|
# or 64-bit build).
|
|
# - for a 64-bit build, set 'Platform=x64' in the environment as
|
|
# well, or else on the make command line.
|
|
# * This is a variable understood only by this makefile - none
|
|
# of the tools we invoke will know it - but it's consistent
|
|
# with the way the VS scripts like vcvarsx86_amd64.bat set
|
|
# things up, and since the environment has to change
|
|
# _anyway_ between 32- and 64-bit builds (different set of
|
|
# paths in $LIB) it's reasonable to have the choice of
|
|
# compilation target driven by another environment variable
|
|
# set in parallel with that one.
|
|
# - for older versions of the VS libraries you may also have to
|
|
# set EXTRA_console and/or EXTRA_windows to the name of an
|
|
# object file manually extracted from one of those libraries.
|
|
# * This is because old VS seems to manage its startup code by
|
|
# having libcmt.lib contain lots of *crt0.obj objects, one
|
|
# for each possible user entry point (main, WinMain and the
|
|
# wide-char versions of both), of which the linker arranges
|
|
# to include the right one by special-case code. But lld
|
|
# only seems to mimic half of that code - it does include
|
|
# the right crt0 object, but it doesn't also deliberately
|
|
# _avoid_ including the _wrong_ ones, and since all those
|
|
# objects define a common set of global symbols for other
|
|
# parts of the library to use, lld may well select an
|
|
# arbitrary one of them the first time it sees a reference
|
|
# to one of those global symbols, and then later also select
|
|
# the _right_ one for the application's entry point, causing
|
|
# a multiple-definitions crash.
|
|
# * So the workaround is to explicitly include the right
|
|
# *crt0.obj file on the linker command line before lld even
|
|
# begins searching libraries. Hence, for a console
|
|
# application, you might extract crt0.obj from the library
|
|
# in question and set EXTRA_console=crt0.obj, and for a GUI
|
|
# application, do the same with wincrt0.obj. Then this
|
|
# makefile will include the right one of those objects
|
|
# alongside the matching /subsystem linker option.
|
|
|
|
open OUT, ">$makefiles{'clangcl'}"; select OUT;
|
|
print
|
|
"# Makefile for cross-compiling $project_name using clang-cl, lld-link,\n".
|
|
"# and MinGW's windres, using GNU make on Linux.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
print $help;
|
|
print
|
|
"\n".
|
|
"CCCMD = clang-cl\n".
|
|
"ifeq (\$(Platform),x64)\n".
|
|
"CCTARGET = x86_64-pc-windows-msvc18.0.0\n".
|
|
"RCCMD = x86_64-w64-mingw32-windres\n".
|
|
"else\n".
|
|
"CCTARGET = i386-pc-windows-msvc18.0.0\n".
|
|
"RCCMD = i686-w64-mingw32-windres\n".
|
|
"endif\n".
|
|
"CC = \$(CCCMD) --target=\$(CCTARGET)\n".
|
|
&splitline("RC = \$(RCCMD) --preprocessor=\$(CCCMD) ".
|
|
"--preprocessor-arg=/TC --preprocessor-arg=/E")."\n".
|
|
"LD = lld-link\n".
|
|
"\n".
|
|
"# C compilation flags\n".
|
|
&splitline("CFLAGS = /nologo /W3 /O1 " .
|
|
(join " ", map {"-I$dirpfx$_"} @srcdirs) .
|
|
" /D_WINDOWS /D_WIN32_WINDOWS=0x401 /DWINVER=0x401 ".
|
|
"/D_CRT_SECURE_NO_WARNINGS")."\n".
|
|
"LFLAGS = /incremental:no /dynamicbase /nxcompat\n".
|
|
&splitline("RCFLAGS = ".(join " ", map {"-I$dirpfx$_"} @srcdirs).
|
|
" -DWIN32 -D_WIN32 -DWINVER=0x0400 --define MINGW32_FIX=1")."\n".
|
|
"\n".
|
|
"\n";
|
|
print &splitline("all:" . join "", map { " \$(BUILDDIR)$_.exe" } &progrealnames("G:C"));
|
|
print "\n\n";
|
|
foreach $p (&prognames("G:C")) {
|
|
($prog, $type) = split ",", $p;
|
|
$objstr = &objects($p, "\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", undef);
|
|
print &splitline("\$(BUILDDIR)$prog.exe: " . $objstr), "\n";
|
|
|
|
$objstr = &objects($p, "\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", "X.lib");
|
|
$subsys = ($type eq "G") ? "windows" : "console";
|
|
print &splitline("\t\$(LD) \$(LFLAGS) \$(XLFLAGS) ".
|
|
"/out:\$(BUILDDIR)$prog.exe ".
|
|
"/lldmap:\$(BUILDDIR)$prog.map ".
|
|
"/subsystem:$subsys\$(SUBSYSVER) ".
|
|
"\$(EXTRA_$subsys) $objstr")."\n\n";
|
|
}
|
|
foreach $d (&deps("\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", $dirpfx, "/", "vc")) {
|
|
print &splitline(sprintf("%s: %s", $d->{obj},
|
|
join " ", @{$d->{deps}})), "\n";
|
|
if ($d->{obj} =~ /\.res$/) {
|
|
print "\t\$(RC) \$(RCFLAGS) ".$d->{deps}->[0]." -o ".$d->{obj}."\n\n";
|
|
} else {
|
|
$deflist = join "", map { " /D$_" } @{$d->{defs}};
|
|
print "\t\$(CC) /Fo".$d->{obj}." \$(COMPAT) \$(CFLAGS) \$(XFLAGS)$deflist /c \$<\n\n";
|
|
}
|
|
}
|
|
print "\nclean:\n".
|
|
&splitline("\trm -f \$(BUILDDIR)*.obj \$(BUILDDIR)*.exe ".
|
|
"\$(BUILDDIR)*.res \$(BUILDDIR)*.map ".
|
|
"\$(BUILDDIR)*.exe.manifest")."\n";
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
if (defined $makefiles{'cygwin'}) {
|
|
$mftyp = 'cygwin';
|
|
$dirpfx = &dirpfx($makefiles{'cygwin'}, "/");
|
|
|
|
##-- CygWin makefile
|
|
open OUT, ">$makefiles{'cygwin'}"; select OUT;
|
|
print
|
|
"# Makefile for $project_name under cygwin.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
# gcc command line option is -D not /D
|
|
($_ = $help) =~ s/=\/D/=-D/gs;
|
|
print $_;
|
|
print
|
|
"\n".
|
|
"# You can define this path to point at your tools if you need to\n".
|
|
"# TOOLPATH = c:\\cygwin\\bin\\ # or similar, if you're running Windows\n".
|
|
"# TOOLPATH = /pkg/mingw32msvc/i386-mingw32msvc/bin/\n".
|
|
"CC = \$(TOOLPATH)gcc\n".
|
|
"RC = \$(TOOLPATH)windres\n".
|
|
"# Uncomment the following two lines to compile under Winelib\n".
|
|
"# CC = winegcc\n".
|
|
"# RC = wrc\n".
|
|
"# You may also need to tell windres where to find include files:\n".
|
|
"# RCINC = --include-dir c:\\cygwin\\include\\\n".
|
|
"\n".
|
|
&splitline("CFLAGS = -mno-cygwin -Wall -O2 -D_WINDOWS -DDEBUG -DWIN32S_COMPAT".
|
|
" -D_NO_OLDNAMES -DNO_MULTIMON -DNO_HTMLHELP " .
|
|
(join " ", map {"-I$dirpfx$_"} @srcdirs)) .
|
|
"\n".
|
|
"LDFLAGS = -mno-cygwin -s\n".
|
|
&splitline("RCFLAGS = \$(RCINC) --define WIN32=1 --define _WIN32=1".
|
|
" --define WINVER=0x0400 --define MINGW32_FIX=1 " .
|
|
(join " ", map {"--include $dirpfx$_"} @srcdirs) )."\n".
|
|
"\n";
|
|
print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
|
|
print "\n\n";
|
|
foreach $p (&prognames("G:C")) {
|
|
($prog, $type) = split ",", $p;
|
|
$objstr = &objects($p, "X.o", "X.res.o", undef);
|
|
print &splitline($prog . ".exe: " . $objstr), "\n";
|
|
my $mw = $type eq "G" ? " -mwindows" : "";
|
|
$libstr = &objects($p, undef, undef, "-lX");
|
|
print &splitline("\t\$(CC)" . $mw . " \$(LDFLAGS) -o \$@ " .
|
|
"-Wl,-Map,$prog.map " .
|
|
$objstr . " $libstr", 69), "\n\n";
|
|
}
|
|
foreach $d (&deps("X.o", "X.res.o", $dirpfx, "/")) {
|
|
print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
|
|
"\n";
|
|
if ($d->{obj} =~ /\.res\.o$/) {
|
|
print "\t\$(RC) \$(FWHACK) \$(RCFL) \$(RCFLAGS) \$< \$\@\n";
|
|
} else {
|
|
$deflist = join "", map { " -D$_" } @{$d->{defs}};
|
|
print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS)" .
|
|
" \$(XFLAGS)$deflist -c \$< -o \$\@\n";
|
|
}
|
|
}
|
|
print "\n";
|
|
print $makefile_extra{'cygwin'} || "";
|
|
print "\nclean:\n".
|
|
"\trm -f *.o *.exe *.res.o *.map\n".
|
|
"\n";
|
|
select STDOUT; close OUT;
|
|
|
|
}
|
|
|
|
##-- Borland makefile
|
|
if (defined $makefiles{'borland'}) {
|
|
$mftyp = 'borland';
|
|
$dirpfx = &dirpfx($makefiles{'borland'}, "\\");
|
|
|
|
%stdlibs = ( # Borland provides many Win32 API libraries intrinsically
|
|
"advapi32" => 1,
|
|
"comctl32" => 1,
|
|
"comdlg32" => 1,
|
|
"gdi32" => 1,
|
|
"imm32" => 1,
|
|
"shell32" => 1,
|
|
"user32" => 1,
|
|
"winmm" => 1,
|
|
"winspool" => 1,
|
|
"wsock32" => 1,
|
|
);
|
|
open OUT, ">$makefiles{'borland'}"; select OUT;
|
|
print
|
|
"# Makefile for $project_name under Borland C.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
# bcc32 command line option is -D not /D
|
|
($_ = $help) =~ s/=\/D/=-D/gs;
|
|
print $_;
|
|
print
|
|
"\n".
|
|
"# If you rename this file to `Makefile', you should change this line,\n".
|
|
"# so that the .rsp files still depend on the correct makefile.\n".
|
|
"MAKEFILE = Makefile.bor\n".
|
|
"\n".
|
|
"# C compilation flags\n".
|
|
"CFLAGS = -D_WINDOWS -DWINVER=0x0401\n".
|
|
"\n".
|
|
"# Get include directory for resource compiler\n".
|
|
"!if !\$d(BCB)\n".
|
|
"BCB = \$(MAKEDIR)\\..\n".
|
|
"!endif\n".
|
|
"\n";
|
|
print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
|
|
print "\n\n";
|
|
foreach $p (&prognames("G:C")) {
|
|
($prog, $type) = split ",", $p;
|
|
$objstr = &objects($p, "X.obj", "X.res", undef);
|
|
print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
|
|
my $ap = ($type eq "G") ? "-aa" : "-ap";
|
|
print "\tilink32 $ap -Gn -L\$(BCB)\\lib \@$prog.rsp\n\n";
|
|
}
|
|
foreach $p (&prognames("G:C")) {
|
|
($prog, $type) = split ",", $p;
|
|
print $prog, ".rsp: \$(MAKEFILE)\n";
|
|
$objstr = &objects($p, "X.obj", undef, undef);
|
|
@objlist = split " ", $objstr;
|
|
@objlines = ("");
|
|
foreach $i (@objlist) {
|
|
if (length($objlines[$#objlines] . " $i") > 50) {
|
|
push @objlines, "";
|
|
}
|
|
$objlines[$#objlines] .= " $i";
|
|
}
|
|
$c0w = ($type eq "G") ? "c0w32" : "c0x32";
|
|
print "\techo $c0w + > $prog.rsp\n";
|
|
for ($i=0; $i<=$#objlines; $i++) {
|
|
$plus = ($i < $#objlines ? " +" : "");
|
|
print "\techo$objlines[$i]$plus >> $prog.rsp\n";
|
|
}
|
|
print "\techo $prog.exe >> $prog.rsp\n";
|
|
$objstr = &objects($p, "X.obj", "X.res", undef);
|
|
@libs = split " ", &objects($p, undef, undef, "X");
|
|
@libs = grep { !$stdlibs{$_} } @libs;
|
|
unshift @libs, "cw32", "import32";
|
|
$libstr = join ' ', @libs;
|
|
print "\techo nul,$libstr, >> $prog.rsp\n";
|
|
print "\techo " . &objects($p, undef, "X.res", undef) . " >> $prog.rsp\n";
|
|
print "\n";
|
|
}
|
|
foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\")) {
|
|
print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
|
|
"\n";
|
|
if ($d->{obj} =~ /\.res$/) {
|
|
print &splitline("\tbrcc32 \$(FWHACK) \$(RCFL) " .
|
|
"-i \$(BCB)\\include -r -DNO_WINRESRC_H -DWIN32".
|
|
" -D_WIN32 -DWINVER=0x0401 \$*.rc",69)."\n";
|
|
} else {
|
|
$deflist = join "", map { " -D$_" } @{$d->{defs}};
|
|
print &splitline("\tbcc32 -w-aus -w-ccc -w-par -w-pia \$(COMPAT)" .
|
|
" \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist ".
|
|
(join " ", map {"-I$dirpfx$_"} @srcdirs) .
|
|
" /o$d->{obj} /c ".$d->{deps}->[0],69)."\n";
|
|
}
|
|
}
|
|
print "\n";
|
|
print $makefile_extra{'borland'} || "";
|
|
print "\nclean:\n".
|
|
"\t-del *.obj\n".
|
|
"\t-del *.exe\n".
|
|
"\t-del *.res\n".
|
|
"\t-del *.pch\n".
|
|
"\t-del *.aps\n".
|
|
"\t-del *.il*\n".
|
|
"\t-del *.pdb\n".
|
|
"\t-del *.rsp\n".
|
|
"\t-del *.tds\n".
|
|
"\t-del *.\$\$\$\$\$\$\n";
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
if (defined $makefiles{'vc'}) {
|
|
$mftyp = 'vc';
|
|
$dirpfx = &dirpfx($makefiles{'vc'}, "\\");
|
|
|
|
##-- Visual C++ makefile
|
|
open OUT, ">$makefiles{'vc'}"; select OUT;
|
|
print
|
|
"# Makefile for $project_name under Visual C.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
print $help;
|
|
print
|
|
"\n".
|
|
"# If you rename this file to `Makefile', you should change this line,\n".
|
|
"# so that the .rsp files still depend on the correct makefile.\n".
|
|
"MAKEFILE = Makefile.vc\n".
|
|
"\n".
|
|
"# C compilation flags\n".
|
|
"CFLAGS = /nologo /W3 /O1 /D_WINDOWS /D_WIN32_WINDOWS=0x401 /DWINVER=0x401 /I.\n".
|
|
"LFLAGS = /incremental:no /fixed\n".
|
|
"\n";
|
|
print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
|
|
print "\n\n";
|
|
foreach $p (&prognames("G:C")) {
|
|
($prog, $type) = split ",", $p;
|
|
$objstr = &objects($p, "X.obj", "X.res", undef);
|
|
print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
|
|
print "\tlink \$(LFLAGS) -out:$prog.exe -map:$prog.map \@$prog.rsp\n\n";
|
|
}
|
|
foreach $p (&prognames("G:C")) {
|
|
($prog, $type) = split ",", $p;
|
|
print $prog, ".rsp: \$(MAKEFILE)\n";
|
|
$objstr = &objects($p, "X.obj", "X.res", "X.lib");
|
|
@objlist = split " ", $objstr;
|
|
@objlines = ("");
|
|
foreach $i (@objlist) {
|
|
if (length($objlines[$#objlines] . " $i") > 50) {
|
|
push @objlines, "";
|
|
}
|
|
$objlines[$#objlines] .= " $i";
|
|
}
|
|
$subsys = ($type eq "G") ? "windows" : "console";
|
|
print "\techo /nologo /subsystem:$subsys > $prog.rsp\n";
|
|
for ($i=0; $i<=$#objlines; $i++) {
|
|
print "\techo$objlines[$i] >> $prog.rsp\n";
|
|
}
|
|
print "\n";
|
|
}
|
|
foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\")) {
|
|
print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
|
|
"\n";
|
|
if ($d->{obj} =~ /\.res$/) {
|
|
print "\trc \$(FWHACK) \$(RCFL) -r -DWIN32 -D_WIN32 ".
|
|
"-DWINVER=0x0400 -fo".$d->{obj}." ".$d->{deps}->[0]."\n";
|
|
} else {
|
|
$deflist = join "", map { " /D$_" } @{$d->{defs}};
|
|
print "\tcl \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist".
|
|
" /c ".$d->{deps}->[0]." /Fo$d->{obj}\n";
|
|
}
|
|
}
|
|
print "\n";
|
|
print $makefile_extra{'vc'} || "";
|
|
print "\nclean: tidy\n".
|
|
"\t-del *.exe\n\n".
|
|
"tidy:\n".
|
|
"\t-del *.obj\n".
|
|
"\t-del *.res\n".
|
|
"\t-del *.pch\n".
|
|
"\t-del *.aps\n".
|
|
"\t-del *.ilk\n".
|
|
"\t-del *.pdb\n".
|
|
"\t-del *.rsp\n".
|
|
"\t-del *.dsp\n".
|
|
"\t-del *.dsw\n".
|
|
"\t-del *.ncb\n".
|
|
"\t-del *.opt\n".
|
|
"\t-del *.plg\n".
|
|
"\t-del *.map\n".
|
|
"\t-del *.idb\n".
|
|
"\t-del debug.log\n";
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
if (defined $makefiles{'wce'}) {
|
|
$mftyp = 'wce';
|
|
$dirpfx = &dirpfx($makefiles{'wce'}, "\\");
|
|
|
|
##-- eMbedded Visual C PocketPC makefile
|
|
open OUT, ">$makefiles{'wce'}"; select OUT;
|
|
print
|
|
"# Makefile for $project_name on PocketPC using eMbedded Visual C.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
print $help;
|
|
print
|
|
"\n".
|
|
"# If you rename this file to `Makefile', you should change this line,\n".
|
|
"# so that the .rsp files still depend on the correct makefile.\n".
|
|
"MAKEFILE = Makefile.wce\n".
|
|
"\n".
|
|
"# This makefile expects the environment to have been set up by one\n".
|
|
"# of the PocketPC batch files wcearmv4.bat and wceemulator.bat. No\n".
|
|
"# other build targets are currently supported, because they would\n".
|
|
"# need a section in this if statement.\n".
|
|
"!if \"\$(TARGETCPU)\" == \"emulator\"\n".
|
|
"PLATFORM_DEFS=/D \"_i386_\" /D \"i_386_\" /D \"_X86_\" /D \"x86\"\n".
|
|
"CC=cl\n".
|
|
"BASELIBS=commctrl.lib coredll.lib corelibc.lib aygshell.lib\n".
|
|
"MACHINE=IX86\n".
|
|
"!else\n".
|
|
"PLATFORM_DEFS=/D \"ARM\" /D \"_ARM_\" /D \"ARMV4\"\n".
|
|
"CC=clarm\n".
|
|
"BASELIBS=commctrl.lib coredll.lib aygshell.lib\n".
|
|
"MACHINE=ARM\n".
|
|
"!endif\n".
|
|
"\n".
|
|
"# C compilation flags\n".
|
|
"CFLAGS = /nologo /W3 /O1 /MC /D _WIN32_WCE=420 /D \"WIN32_PLATFORM_PSPC=400\" /D UNDER_CE=420 \\\n".
|
|
" \$(PLATFORM_DEFS) \\\n".
|
|
" /D \"UNICODE\" /D \"_UNICODE\" /D \"NDEBUG\" /D \"NO_HTMLHELP\"\n".
|
|
"\n".
|
|
"LFLAGS = /nologo /incremental:no \\\n".
|
|
" /base:0x00010000 /stack:0x10000,0x1000 /entry:WinMainCRTStartup \\\n".
|
|
" /nodefaultlib:libc.lib /nodefaultlib:libcmt.lib /nodefaultlib:msvcrt.lib /nodefaultlib:OLDNAMES.lib \\\n".
|
|
" /subsystem:windowsce,4.20 /align:4096 /MACHINE:\$(MACHINE)\n".
|
|
"\n".
|
|
"RCFL = /d UNDER_CE=420 /d _WIN32_WCE=420 /d \"WIN32_PLATFORM_PSPC=400\" \\\n".
|
|
" \$(PLATFORM_DEFS) \\\n".
|
|
" /d \"NDEBUG\" /d \"UNICODE\" /d \"_UNICODE\"\n".
|
|
"\n";
|
|
print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G"));
|
|
print "\n\n";
|
|
foreach $p (&prognames("G")) {
|
|
($prog, $type) = split ",", $p;
|
|
$objstr = &objects($p, "X.obj", "X.res", undef);
|
|
print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
|
|
print "\tlink \$(LFLAGS) -out:$prog.exe -map:$prog.map \@$prog.rsp\n\n";
|
|
}
|
|
foreach $p (&prognames("G")) {
|
|
($prog, $type) = split ",", $p;
|
|
print $prog, ".rsp: \$(MAKEFILE)\n";
|
|
$objstr = &objects($p, "X.obj", "X.res", undef);
|
|
@objlist = split " ", $objstr;
|
|
@objlines = ("");
|
|
foreach $i (@objlist) {
|
|
if (length($objlines[$#objlines] . " $i") > 50) {
|
|
push @objlines, "";
|
|
}
|
|
$objlines[$#objlines] .= " $i";
|
|
}
|
|
print "\techo \$(BASELIBS) > $prog.rsp\n";
|
|
for ($i=0; $i<=$#objlines; $i++) {
|
|
print "\techo$objlines[$i] >> $prog.rsp\n";
|
|
}
|
|
print "\n";
|
|
}
|
|
foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\")) {
|
|
print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
|
|
"\n";
|
|
if ($d->{obj} =~ /\.res$/) {
|
|
print "\trc \$(FWHACK) \$(RCFL) -r -fo".
|
|
$d->{obj}." ".$d->{deps}->[0]."\n";
|
|
} else {
|
|
$deflist = join "", map { " /D$_" } @{$d->{defs}};
|
|
print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist".
|
|
" /c ".$d->{deps}->[0]." /Fo$d->{obj}\n";
|
|
}
|
|
}
|
|
print "\n";
|
|
print $makefile_extra{'wce'} || "";
|
|
print "\nclean: tidy\n".
|
|
"\t-del *.exe\n\n".
|
|
"tidy:\n".
|
|
"\t-del *.obj\n".
|
|
"\t-del *.res\n".
|
|
"\t-del *.pch\n".
|
|
"\t-del *.aps\n".
|
|
"\t-del *.ilk\n".
|
|
"\t-del *.pdb\n".
|
|
"\t-del *.rsp\n".
|
|
"\t-del *.dsp\n".
|
|
"\t-del *.dsw\n".
|
|
"\t-del *.ncb\n".
|
|
"\t-del *.opt\n".
|
|
"\t-del *.plg\n".
|
|
"\t-del *.map\n".
|
|
"\t-del *.idb\n".
|
|
"\t-del debug.log\n";
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
if (defined $makefiles{'vcproj'}) {
|
|
$mftyp = 'vcproj';
|
|
|
|
##-- MSVC 6 Workspace and projects
|
|
#
|
|
# Note: All files created in this section are written in binary
|
|
# mode, because although MSVC's command-line make can deal with
|
|
# LF-only line endings, MSVC project files really _need_ to be
|
|
# CRLF. Hence, in order for mkfiles.pl to generate usable project
|
|
# files even when run from Unix, I make sure all files are binary
|
|
# and explicitly write the CRLFs.
|
|
#
|
|
# Create directories if necessary
|
|
mkdir $makefiles{'vcproj'}
|
|
if(! -d $makefiles{'vcproj'});
|
|
chdir $makefiles{'vcproj'};
|
|
@deps = &deps("X.obj", "X.res", "", "\\");
|
|
%all_object_deps = map {$_->{obj} => $_->{deps}} @deps;
|
|
# Create the project files
|
|
# Get names of all Windows projects (GUI and console)
|
|
my @prognames = &prognames("G:C");
|
|
foreach $progname (@prognames) {
|
|
create_project(\%all_object_deps, $progname);
|
|
}
|
|
# Create the workspace file
|
|
open OUT, ">$project_name.dsw"; binmode OUT; select OUT;
|
|
print
|
|
"Microsoft Developer Studio Workspace File, Format Version 6.00\r\n".
|
|
"# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r\n".
|
|
"\r\n".
|
|
"###############################################################################\r\n".
|
|
"\r\n";
|
|
# List projects
|
|
foreach $progname (@prognames) {
|
|
($windows_project, $type) = split ",", $progname;
|
|
print "Project: \"$windows_project\"=\".\\$windows_project\\$windows_project.dsp\" - Package Owner=<4>\r\n";
|
|
}
|
|
print
|
|
"\r\n".
|
|
"Package=<5>\r\n".
|
|
"{{{\r\n".
|
|
"}}}\r\n".
|
|
"\r\n".
|
|
"Package=<4>\r\n".
|
|
"{{{\r\n".
|
|
"}}}\r\n".
|
|
"\r\n".
|
|
"###############################################################################\r\n".
|
|
"\r\n".
|
|
"Global:\r\n".
|
|
"\r\n".
|
|
"Package=<5>\r\n".
|
|
"{{{\r\n".
|
|
"}}}\r\n".
|
|
"\r\n".
|
|
"Package=<3>\r\n".
|
|
"{{{\r\n".
|
|
"}}}\r\n".
|
|
"\r\n".
|
|
"###############################################################################\r\n".
|
|
"\r\n";
|
|
select STDOUT; close OUT;
|
|
chdir $orig_dir;
|
|
|
|
sub create_project {
|
|
my ($all_object_deps, $progname) = @_;
|
|
# Construct program's dependency info
|
|
%seen_objects = ();
|
|
%lib_files = ();
|
|
%source_files = ();
|
|
%header_files = ();
|
|
%resource_files = ();
|
|
@object_files = split " ", &objects($progname, "X.obj", "X.res", "X.lib");
|
|
foreach $object_file (@object_files) {
|
|
next if defined $seen_objects{$object_file};
|
|
$seen_objects{$object_file} = 1;
|
|
if($object_file =~ /\.lib$/io) {
|
|
$lib_files{$object_file} = 1;
|
|
next;
|
|
}
|
|
$object_deps = $all_object_deps{$object_file};
|
|
foreach $object_dep (@$object_deps) {
|
|
if($object_dep =~ /\.c$/io) {
|
|
$source_files{$object_dep} = 1;
|
|
next;
|
|
}
|
|
if($object_dep =~ /\.h$/io) {
|
|
$header_files{$object_dep} = 1;
|
|
next;
|
|
}
|
|
if($object_dep =~ /\.(rc|ico)$/io) {
|
|
$resource_files{$object_dep} = 1;
|
|
next;
|
|
}
|
|
}
|
|
}
|
|
$libs = join " ", sort keys %lib_files;
|
|
@source_files = sort keys %source_files;
|
|
@header_files = sort keys %header_files;
|
|
@resources = sort keys %resource_files;
|
|
($windows_project, $type) = split ",", $progname;
|
|
mkdir $windows_project
|
|
if(! -d $windows_project);
|
|
chdir $windows_project;
|
|
$subsys = ($type eq "G") ? "windows" : "console";
|
|
open OUT, ">$windows_project.dsp"; binmode OUT; select OUT;
|
|
print
|
|
"# Microsoft Developer Studio Project File - Name=\"$windows_project\" - Package Owner=<4>\r\n".
|
|
"# Microsoft Developer Studio Generated Build File, Format Version 6.00\r\n".
|
|
"# ** DO NOT EDIT **\r\n".
|
|
"\r\n".
|
|
"# TARGTYPE \"Win32 (x86) Application\" 0x0101\r\n".
|
|
"\r\n".
|
|
"CFG=$windows_project - Win32 Debug\r\n".
|
|
"!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r\n".
|
|
"!MESSAGE use the Export Makefile command and run\r\n".
|
|
"!MESSAGE \r\n".
|
|
"!MESSAGE NMAKE /f \"$windows_project.mak\".\r\n".
|
|
"!MESSAGE \r\n".
|
|
"!MESSAGE You can specify a configuration when running NMAKE\r\n".
|
|
"!MESSAGE by defining the macro CFG on the command line. For example:\r\n".
|
|
"!MESSAGE \r\n".
|
|
"!MESSAGE NMAKE /f \"$windows_project.mak\" CFG=\"$windows_project - Win32 Debug\"\r\n".
|
|
"!MESSAGE \r\n".
|
|
"!MESSAGE Possible choices for configuration are:\r\n".
|
|
"!MESSAGE \r\n".
|
|
"!MESSAGE \"$windows_project - Win32 Release\" (based on \"Win32 (x86) Application\")\r\n".
|
|
"!MESSAGE \"$windows_project - Win32 Debug\" (based on \"Win32 (x86) Application\")\r\n".
|
|
"!MESSAGE \r\n".
|
|
"\r\n".
|
|
"# Begin Project\r\n".
|
|
"# PROP AllowPerConfigDependencies 0\r\n".
|
|
"# PROP Scc_ProjName \"\"\r\n".
|
|
"# PROP Scc_LocalPath \"\"\r\n".
|
|
"CPP=cl.exe\r\n".
|
|
"MTL=midl.exe\r\n".
|
|
"RSC=rc.exe\r\n".
|
|
"\r\n".
|
|
"!IF \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
|
|
"\r\n".
|
|
"# PROP BASE Use_MFC 0\r\n".
|
|
"# PROP BASE Use_Debug_Libraries 0\r\n".
|
|
"# PROP BASE Output_Dir \"Release\"\r\n".
|
|
"# PROP BASE Intermediate_Dir \"Release\"\r\n".
|
|
"# PROP BASE Target_Dir \"\"\r\n".
|
|
"# PROP Use_MFC 0\r\n".
|
|
"# PROP Use_Debug_Libraries 0\r\n".
|
|
"# PROP Output_Dir \"Release\"\r\n".
|
|
"# PROP Intermediate_Dir \"Release\"\r\n".
|
|
"# PROP Ignore_Export_Lib 0\r\n".
|
|
"# PROP Target_Dir \"\"\r\n".
|
|
"# ADD BASE CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
|
|
"# ADD CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
|
|
"# ADD BASE MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
|
|
"# ADD MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
|
|
"# ADD BASE RSC /l 0x809 /d \"NDEBUG\"\r\n".
|
|
"# ADD RSC /l 0x809 /d \"NDEBUG\"\r\n".
|
|
"BSC32=bscmake.exe\r\n".
|
|
"# ADD BASE BSC32 /nologo\r\n".
|
|
"# ADD BSC32 /nologo\r\n".
|
|
"LINK32=link.exe\r\n".
|
|
"# 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".
|
|
"# ADD LINK32 $libs /nologo /subsystem:$subsys /machine:I386\r\n".
|
|
"# SUBTRACT LINK32 /pdb:none\r\n".
|
|
"\r\n".
|
|
"!ELSEIF \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
|
|
"\r\n".
|
|
"# PROP BASE Use_MFC 0\r\n".
|
|
"# PROP BASE Use_Debug_Libraries 1\r\n".
|
|
"# PROP BASE Output_Dir \"Debug\"\r\n".
|
|
"# PROP BASE Intermediate_Dir \"Debug\"\r\n".
|
|
"# PROP BASE Target_Dir \"\"\r\n".
|
|
"# PROP Use_MFC 0\r\n".
|
|
"# PROP Use_Debug_Libraries 1\r\n".
|
|
"# PROP Output_Dir \"Debug\"\r\n".
|
|
"# PROP Intermediate_Dir \"Debug\"\r\n".
|
|
"# PROP Ignore_Export_Lib 0\r\n".
|
|
"# PROP Target_Dir \"\"\r\n".
|
|
"# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
|
|
"# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
|
|
"# ADD BASE MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
|
|
"# ADD MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
|
|
"# ADD BASE RSC /l 0x809 /d \"_DEBUG\"\r\n".
|
|
"# ADD RSC /l 0x809 /d \"_DEBUG\"\r\n".
|
|
"BSC32=bscmake.exe\r\n".
|
|
"# ADD BASE BSC32 /nologo\r\n".
|
|
"# ADD BSC32 /nologo\r\n".
|
|
"LINK32=link.exe\r\n".
|
|
"# 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".
|
|
"# ADD LINK32 $libs /nologo /subsystem:$subsys /debug /machine:I386 /pdbtype:sept\r\n".
|
|
"# SUBTRACT LINK32 /pdb:none\r\n".
|
|
"\r\n".
|
|
"!ENDIF \r\n".
|
|
"\r\n".
|
|
"# Begin Target\r\n".
|
|
"\r\n".
|
|
"# Name \"$windows_project - Win32 Release\"\r\n".
|
|
"# Name \"$windows_project - Win32 Debug\"\r\n".
|
|
"# Begin Group \"Source Files\"\r\n".
|
|
"\r\n".
|
|
"# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\"\r\n";
|
|
foreach $source_file (@source_files) {
|
|
print
|
|
"# Begin Source File\r\n".
|
|
"\r\n".
|
|
"SOURCE=..\\..\\$source_file\r\n";
|
|
if($source_file =~ /ssh\.c/io) {
|
|
# Disable 'Edit and continue' as Visual Studio can't handle the macros
|
|
print
|
|
"\r\n".
|
|
"!IF \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
|
|
"\r\n".
|
|
"!ELSEIF \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
|
|
"\r\n".
|
|
"# ADD CPP /Zi\r\n".
|
|
"\r\n".
|
|
"!ENDIF \r\n".
|
|
"\r\n";
|
|
}
|
|
print "# End Source File\r\n";
|
|
}
|
|
print
|
|
"# End Group\r\n".
|
|
"# Begin Group \"Header Files\"\r\n".
|
|
"\r\n".
|
|
"# PROP Default_Filter \"h;hpp;hxx;hm;inl\"\r\n";
|
|
foreach $header_file (@header_files) {
|
|
print
|
|
"# Begin Source File\r\n".
|
|
"\r\n".
|
|
"SOURCE=..\\..\\$header_file\r\n".
|
|
"# End Source File\r\n";
|
|
}
|
|
print
|
|
"# End Group\r\n".
|
|
"# Begin Group \"Resource Files\"\r\n".
|
|
"\r\n".
|
|
"# PROP Default_Filter \"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\r\n";
|
|
foreach $resource_file (@resources) {
|
|
print
|
|
"# Begin Source File\r\n".
|
|
"\r\n".
|
|
"SOURCE=..\\..\\$resource_file\r\n".
|
|
"# End Source File\r\n";
|
|
}
|
|
print
|
|
"# End Group\r\n".
|
|
"# End Target\r\n".
|
|
"# End Project\r\n";
|
|
select STDOUT; close OUT;
|
|
chdir "..";
|
|
}
|
|
}
|
|
|
|
if (defined $makefiles{'gtk'}) {
|
|
$mftyp = 'gtk';
|
|
$dirpfx = &dirpfx($makefiles{'gtk'}, "/");
|
|
|
|
##-- X/GTK/Unix makefile
|
|
open OUT, ">$makefiles{'gtk'}"; select OUT;
|
|
print
|
|
"# Makefile for $project_name under X/GTK and Unix.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
# gcc command line option is -D not /D
|
|
($_ = $help) =~ s/=\/D/=-D/gs;
|
|
print $_;
|
|
print
|
|
"\n".
|
|
"# You can define this path to point at your tools if you need to\n".
|
|
"# TOOLPATH = /opt/gcc/bin\n".
|
|
"CC := \$(TOOLPATH)\$(CC)\n".
|
|
"# You can manually set this to `gtk-config' or `pkg-config gtk+-1.2'\n".
|
|
"# (depending on what works on your system) if you want to enforce\n".
|
|
"# building with GTK 1.2, or you can set it to `pkg-config gtk+-2.0'\n".
|
|
"# if you want to enforce 2.0. The default is to try 2.0 and fall back\n".
|
|
"# to 1.2 if it isn't found.\n".
|
|
"GTK_CONFIG = sh -c 'pkg-config gtk+-2.0 \$\$0 2>/dev/null || gtk-config \$\$0'\n".
|
|
"\n".
|
|
&splitline("CFLAGS := -O2 -Wall -Werror -ansi -pedantic -g " .
|
|
(join " ", map {"-I$dirpfx$_"} @srcdirs) .
|
|
" `\$(GTK_CONFIG) --cflags` \$(CFLAGS)")."\n".
|
|
"XLIBS = `\$(GTK_CONFIG) --libs` -lm\n".
|
|
"ULIBS = -lm#\n".
|
|
"INSTALL=install\n",
|
|
"INSTALL_PROGRAM=\$(INSTALL)\n",
|
|
"INSTALL_DATA=\$(INSTALL)\n",
|
|
"prefix=/usr/local\n",
|
|
"exec_prefix=\$(prefix)\n",
|
|
"bindir=\$(exec_prefix)/bin\n",
|
|
"gamesdir=\$(exec_prefix)/games\n",
|
|
"mandir=\$(prefix)/man\n",
|
|
"man1dir=\$(mandir)/man1\n",
|
|
"\n";
|
|
print &splitline("all:" . join "", map { " \$(BINPREFIX)$_" }
|
|
&progrealnames("X:U"));
|
|
print "\n\n";
|
|
foreach $p (&prognames("X:U")) {
|
|
($prog, $type) = split ",", $p;
|
|
$objstr = &objects($p, "X.o", undef, undef);
|
|
print &splitline("\$(BINPREFIX)" . $prog . ": " . $objstr), "\n";
|
|
$libstr = &objects($p, undef, undef, "-lX");
|
|
print &splitline("\t\$(CC) -o \$@ $objstr $libstr \$(XLFLAGS) \$(${type}LIBS)", 69),
|
|
"\n\n";
|
|
}
|
|
foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
|
|
print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
|
|
"\n";
|
|
$deflist = join "", map { " -D$_" } @{$d->{defs}};
|
|
print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
|
|
" -c \$< -o \$\@\n";
|
|
}
|
|
print "\n";
|
|
print $makefile_extra{'gtk'} || "";
|
|
print "\nclean:\n".
|
|
"\trm -f *.o". (join "", map { " \$(BINPREFIX)$_" } &progrealnames("X:U")) . "\n";
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
if (defined $makefiles{'am'}) {
|
|
$mftyp = 'am';
|
|
die "Makefile.am in a subdirectory is not supported\n"
|
|
if &dirpfx($makefiles{'am'}, "/") ne "";
|
|
|
|
##-- Unix/autoconf Makefile.am
|
|
open OUT, ">$makefiles{'am'}"; select OUT;
|
|
print
|
|
"# Makefile.am for $project_name under Unix with Autoconf/Automake.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n\n";
|
|
|
|
print $makefile_extra{'am_begin'} || "";
|
|
|
|
# All programs go in noinstprogs by default. If you want them
|
|
# installed anywhere else, you have to also add them to
|
|
# bin_PROGRAMS using '!begin am'. (Automake doesn't seem to mind
|
|
# having a program name in _both_ of bin_PROGRAMS and
|
|
# noinst_PROGRAMS.)
|
|
@noinstprogs = ();
|
|
foreach $p (&prognames("X:U")) {
|
|
($prog, $type) = split ",", $p;
|
|
push @noinstprogs, $prog;
|
|
}
|
|
print &splitline(join " ", "noinst_PROGRAMS", "=", @noinstprogs), "\n";
|
|
|
|
%objtosrc = ();
|
|
%amspeciallibs = ();
|
|
%amlibobjname = ();
|
|
%allsources = ();
|
|
foreach $d (&deps("X", undef, "", "/", "am")) {
|
|
my $obj = $d->{obj};
|
|
my $use_archive = 0;
|
|
|
|
if (defined $d->{defs}) {
|
|
# This file needs to go in an archive, so that we can
|
|
# change the preprocess flags to include some -Ds
|
|
$use_archive = 1;
|
|
$archivecppflags{$obj} = [map { " -D$_" } @{$d->{defs}}];
|
|
}
|
|
if (defined $cflags{'am'} && $cflags{'am'}->{$obj}) {
|
|
# This file needs to go in an archive, so that we can
|
|
# change the compile flags as specified in Recipe
|
|
$use_archive = 1;
|
|
$archivecflags{$obj} = [$cflags{'am'}->{$obj}];
|
|
}
|
|
if ($use_archive) {
|
|
$amspeciallibs{$obj} = "lib${obj}.a";
|
|
$amlibobjname{$obj} = "lib${obj}_a-" .
|
|
basename($d->{deps}->[0], ".c", ".m") .
|
|
".\$(OBJEXT)";
|
|
}
|
|
$objtosrc{$obj} = $d->{deps};
|
|
map { $allsources{$_} = 1 } @{$d->{deps}};
|
|
}
|
|
|
|
# 2014-02-22: as of automake-1.14 we begin to get complained at if
|
|
# we don't use this option
|
|
print "AUTOMAKE_OPTIONS = subdir-objects\n\n";
|
|
|
|
# Complete list of source and header files. Not used by the
|
|
# auto-generated parts of this makefile, but Recipe might like to
|
|
# have it available as a variable so that mandatory-rebuild things
|
|
# (version.o) can conveniently be made to depend on it.
|
|
print &splitline(join " ", "allsources", "=",
|
|
sort {$a cmp $b} keys %allsources), "\n\n";
|
|
|
|
@amcppflags = map {"-I\$(srcdir)/$_"} @srcdirs;
|
|
print &splitline(join " ", "AM_CPPFLAGS", "=", @amcppflags, "\n");
|
|
|
|
@amcflags = ("\$(GTK_CFLAGS)", "\$(WARNINGOPTS)");
|
|
print &splitline(join " ", "AM_CFLAGS", "=", @amcflags), "\n";
|
|
|
|
%amlibsused = ();
|
|
foreach $p (&prognames("X:U")) {
|
|
($prog, $type) = split ",", $p;
|
|
@progsources = ("${prog}_SOURCES", "=");
|
|
%sourcefiles = ();
|
|
@ldadd = ();
|
|
$objstr = &objects($p, "X", undef, undef);
|
|
foreach $obj (split / /,$objstr) {
|
|
if ($amspeciallibs{$obj}) {
|
|
$amlibsused{$obj} = 1;
|
|
push @ldadd, $amlibobjname{$obj};
|
|
} else {
|
|
map { $sourcefiles{$_} = 1 } @{$objtosrc{$obj}};
|
|
}
|
|
}
|
|
push @progsources, sort { $a cmp $b } keys %sourcefiles;
|
|
print &splitline(join " ", @progsources), "\n";
|
|
if ($type eq "X") {
|
|
push @ldadd, "\$(GTK_LIBS)";
|
|
}
|
|
push @ldadd, "-lm";
|
|
print &splitline(join " ", "${prog}_LDADD", "=", @ldadd), "\n";
|
|
print "\n";
|
|
}
|
|
|
|
foreach $obj (sort { $a cmp $b } keys %amlibsused) {
|
|
print &splitline(join " ", "lib${obj}_a_SOURCES", "=",
|
|
@{$objtosrc{$obj}}), "\n";
|
|
print &splitline(join " ", "lib${obj}_a_CPPFLAGS", "=",
|
|
@amcflags, @{$archivecppflags{$obj}}), "\n"
|
|
if $archivecppflags{$obj};
|
|
print &splitline(join " ", "lib${obj}_a_CFLAGS", "=",
|
|
@amcflags, @{$archivecflags{$obj}}), "\n"
|
|
if $archivecflags{$obj};
|
|
}
|
|
print &splitline(join " ", "noinst_LIBRARIES", "=",
|
|
sort { $a cmp $b }
|
|
map { $amspeciallibs{$_} }
|
|
keys %amlibsused),
|
|
"\n\n";
|
|
|
|
print $makefile_extra{'am'} || "";
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
if (defined $makefiles{'mpw'}) {
|
|
$mftyp = 'mpw';
|
|
##-- MPW Makefile
|
|
open OUT, ">$makefiles{'mpw'}"; select OUT;
|
|
print
|
|
"# Makefile for $project_name under MPW.\n#\n".
|
|
"# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
# MPW command line option is -d not /D
|
|
($_ = $help) =~ s/=\/D/=-d /gs;
|
|
print $_;
|
|
print "\n\n".
|
|
"ROptions = `Echo \"{VER}\" | StreamEdit -e \"1,\$ replace /=(\xc5)\xa81\xb0/ 'STR=\xb6\xb6\xb6\xb6\xb6\"' \xa81 '\xb6\xb6\xb6\xb6\xb6\"'\"`".
|
|
"\n".
|
|
"C_68K = {C}\n".
|
|
"C_CFM68K = {C}\n".
|
|
"C_PPC = {PPCC}\n".
|
|
"C_Carbon = {PPCC}\n".
|
|
"\n".
|
|
"# -w 35 disables \"unused parameter\" warnings\n".
|
|
"COptions = -i : -i :: -i ::charset -w 35 -w err -proto strict -ansi on \xb6\n".
|
|
" -notOnce\n".
|
|
"COptions_68K = {COptions} -model far -opt time\n".
|
|
"# Enabling \"-opt space\" for CFM-68K gives me undefined references to\n".
|
|
"# _\$LDIVT and _\$LMODT.\n".
|
|
"COptions_CFM68K = {COptions} -model cfmSeg -opt time\n".
|
|
"COptions_PPC = {COptions} -opt size -traceback\n".
|
|
"COptions_Carbon = {COptions} -opt size -traceback -d TARGET_API_MAC_CARBON\n".
|
|
"\n".
|
|
"Link_68K = ILink\n".
|
|
"Link_CFM68K = ILink\n".
|
|
"Link_PPC = PPCLink\n".
|
|
"Link_Carbon = PPCLink\n".
|
|
"\n".
|
|
"LinkOptions = -c 'pTTY'\n".
|
|
"LinkOptions_68K = {LinkOptions} -br 68k -model far -compact\n".
|
|
"LinkOptions_CFM68K = {LinkOptions} -br 020 -model cfmseg -compact\n".
|
|
"LinkOptions_PPC = {LinkOptions}\n".
|
|
"LinkOptions_Carbon = -m __appstart -w {LinkOptions}\n".
|
|
"\n".
|
|
"Libs_68K = \"{CLibraries}StdCLib.far.o\" \xb6\n".
|
|
" \"{Libraries}MacRuntime.o\" \xb6\n".
|
|
" \"{Libraries}MathLib.far.o\" \xb6\n".
|
|
" \"{Libraries}IntEnv.far.o\" \xb6\n".
|
|
" \"{Libraries}Interface.o\" \xb6\n".
|
|
" \"{Libraries}Navigation.far.o\" \xb6\n".
|
|
" \"{Libraries}OpenTransport.o\" \xb6\n".
|
|
" \"{Libraries}OpenTransportApp.o\" \xb6\n".
|
|
" \"{Libraries}OpenTptInet.o\" \xb6\n".
|
|
" \"{Libraries}UnicodeConverterLib.far.o\"\n".
|
|
"\n".
|
|
"Libs_CFM = \"{SharedLibraries}InterfaceLib\" \xb6\n".
|
|
" \"{SharedLibraries}StdCLib\" \xb6\n".
|
|
" \"{SharedLibraries}AppearanceLib\" \xb6\n".
|
|
" -weaklib AppearanceLib \xb6\n".
|
|
" \"{SharedLibraries}NavigationLib\" \xb6\n".
|
|
" -weaklib NavigationLib \xb6\n".
|
|
" \"{SharedLibraries}TextCommon\" \xb6\n".
|
|
" -weaklib TextCommon \xb6\n".
|
|
" \"{SharedLibraries}UnicodeConverter\" \xb6\n".
|
|
" -weaklib UnicodeConverter\n".
|
|
"\n".
|
|
"Libs_CFM68K = {Libs_CFM} \xb6\n".
|
|
" \"{CFM68KLibraries}NuMacRuntime.o\"\n".
|
|
"\n".
|
|
"Libs_PPC = {Libs_CFM} \xb6\n".
|
|
" \"{SharedLibraries}ControlsLib\" \xb6\n".
|
|
" -weaklib ControlsLib \xb6\n".
|
|
" \"{SharedLibraries}WindowsLib\" \xb6\n".
|
|
" -weaklib WindowsLib \xb6\n".
|
|
" \"{SharedLibraries}OpenTransportLib\" \xb6\n".
|
|
" -weaklib OTClientLib \xb6\n".
|
|
" -weaklib OTClientUtilLib \xb6\n".
|
|
" \"{SharedLibraries}OpenTptInternetLib\" \xb6\n".
|
|
" -weaklib OTInetClientLib \xb6\n".
|
|
" \"{PPCLibraries}StdCRuntime.o\" \xb6\n".
|
|
" \"{PPCLibraries}PPCCRuntime.o\" \xb6\n".
|
|
" \"{PPCLibraries}CarbonAccessors.o\" \xb6\n".
|
|
" \"{PPCLibraries}OpenTransportAppPPC.o\" \xb6\n".
|
|
" \"{PPCLibraries}OpenTptInetPPC.o\"\n".
|
|
"\n".
|
|
"Libs_Carbon = \"{PPCLibraries}CarbonStdCLib.o\" \xb6\n".
|
|
" \"{PPCLibraries}StdCRuntime.o\" \xb6\n".
|
|
" \"{PPCLibraries}PPCCRuntime.o\" \xb6\n".
|
|
" \"{SharedLibraries}CarbonLib\" \xb6\n".
|
|
" \"{SharedLibraries}StdCLib\"\n".
|
|
"\n";
|
|
print &splitline("all \xc4 " . join(" ", &progrealnames("M")), undef, "\xb6");
|
|
print "\n\n";
|
|
foreach $p (&prognames("M")) {
|
|
($prog, $type) = split ",", $p;
|
|
|
|
print &splitline("$prog \xc4 $prog.68k $prog.ppc $prog.carbon",
|
|
undef, "\xb6"), "\n\n";
|
|
|
|
$rsrc = &objects($p, "", "X.rsrc", undef);
|
|
|
|
foreach $arch (qw(68K CFM68K PPC Carbon)) {
|
|
$objstr = &objects($p, "X.\L$arch\E.o", "", undef);
|
|
print &splitline("$prog.\L$arch\E \xc4 $objstr $rsrc", undef, "\xb6");
|
|
print "\n";
|
|
print &splitline("\tDuplicate -y $rsrc {Targ}", 69, "\xb6"), "\n";
|
|
print &splitline("\t{Link_$arch} -o {Targ} -fragname $prog " .
|
|
"{LinkOptions_$arch} " .
|
|
$objstr . " {Libs_$arch}", 69, "\xb6"), "\n";
|
|
print &splitline("\tSetFile -a BMi {Targ}", 69, "\xb6"), "\n\n";
|
|
}
|
|
|
|
}
|
|
foreach $d (&deps("", "X.rsrc", "::", ":")) {
|
|
next unless $d->{obj};
|
|
print &splitline(sprintf("%s \xc4 %s", $d->{obj}, join " ", @{$d->{deps}}),
|
|
undef, "\xb6"), "\n";
|
|
print "\tRez ", $d->{deps}->[0], " -o {Targ} {ROptions}\n\n";
|
|
}
|
|
foreach $arch (qw(68K CFM68K)) {
|
|
foreach $d (&deps("X.\L$arch\E.o", "", "::", ":")) {
|
|
next unless $d->{obj};
|
|
print &splitline(sprintf("%s \xc4 %s", $d->{obj},
|
|
join " ", @{$d->{deps}}),
|
|
undef, "\xb6"), "\n";
|
|
print "\t{C_$arch} ", $d->{deps}->[0],
|
|
" -o {Targ} {COptions_$arch}\n\n";
|
|
}
|
|
}
|
|
foreach $arch (qw(PPC Carbon)) {
|
|
foreach $d (&deps("X.\L$arch\E.o", "", "::", ":")) {
|
|
next unless $d->{obj};
|
|
print &splitline(sprintf("%s \xc4 %s", $d->{obj},
|
|
join " ", @{$d->{deps}}),
|
|
undef, "\xb6"), "\n";
|
|
# The odd stuff here seems to stop afpd getting confused.
|
|
print "\techo -n > {Targ}\n";
|
|
print "\tsetfile -t XCOF {Targ}\n";
|
|
print "\t{C_$arch} ", $d->{deps}->[0],
|
|
" -o {Targ} {COptions_$arch}\n\n";
|
|
}
|
|
}
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
if (defined $makefiles{'lcc'}) {
|
|
$mftyp = 'lcc';
|
|
$dirpfx = &dirpfx($makefiles{'lcc'}, "\\");
|
|
|
|
##-- lcc makefile
|
|
open OUT, ">$makefiles{'lcc'}"; select OUT;
|
|
print
|
|
"# Makefile for $project_name under lcc.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
# lcc command line option is -D not /D
|
|
($_ = $help) =~ s/=\/D/=-D/gs;
|
|
print $_;
|
|
print
|
|
"\n".
|
|
"# If you rename this file to `Makefile', you should change this line,\n".
|
|
"# so that the .rsp files still depend on the correct makefile.\n".
|
|
"MAKEFILE = Makefile.lcc\n".
|
|
"\n".
|
|
"# C compilation flags\n".
|
|
"CFLAGS = -D_WINDOWS " .
|
|
(join " ", map {"-I$dirpfx$_"} @srcdirs) .
|
|
"\n".
|
|
"\n".
|
|
"# Get include directory for resource compiler\n".
|
|
"\n";
|
|
print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
|
|
print "\n\n";
|
|
foreach $p (&prognames("G:C")) {
|
|
($prog, $type) = split ",", $p;
|
|
$objstr = &objects($p, "X.obj", "X.res", undef);
|
|
print &splitline("$prog.exe: " . $objstr ), "\n";
|
|
$subsystemtype = undef;
|
|
if ($type eq "G") { $subsystemtype = "-subsystem windows"; }
|
|
my $libss = "shell32.lib wsock32.lib ws2_32.lib winspool.lib winmm.lib imm32.lib";
|
|
print &splitline("\tlcclnk $subsystemtype -o $prog.exe $objstr $libss");
|
|
print "\n\n";
|
|
}
|
|
|
|
foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\")) {
|
|
print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
|
|
"\n";
|
|
if ($d->{obj} =~ /\.res$/) {
|
|
print &splitline("\tlrc \$(FWHACK) \$(RCFL) -r \$*.rc",69)."\n";
|
|
} else {
|
|
$deflist = join "", map { " -D$_" } @{$d->{defs}};
|
|
print &splitline("\tlcc -O -p6 \$(COMPAT) \$(FWHACK) \$(CFLAGS)".
|
|
" \$(XFLAGS)$deflist ".$d->{deps}->[0]." -o \$\@",69)."\n";
|
|
}
|
|
}
|
|
print "\n";
|
|
print $makefile_extra{'lcc'} || "";
|
|
print "\nclean:\n".
|
|
"\t-del *.obj\n".
|
|
"\t-del *.exe\n".
|
|
"\t-del *.res\n";
|
|
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
if (defined $makefiles{'nestedvm'}) {
|
|
$mftyp = 'nestedvm';
|
|
$dirpfx = &dirpfx($makefiles{'nestedvm'}, "/");
|
|
|
|
##-- NestedVM makefile
|
|
open OUT, ">$makefiles{'nestedvm'}"; select OUT;
|
|
print
|
|
"# Makefile for $project_name under NestedVM.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
# gcc command line option is -D not /D
|
|
($_ = $help) =~ s/=\/D/=-D/gs;
|
|
print $_;
|
|
print
|
|
"\n".
|
|
"# This path points at the nestedvm root directory\n".
|
|
"NESTEDVM = /opt/nestedvm\n".
|
|
"# You can define this path to point at your tools if you need to\n".
|
|
"TOOLPATH = \$(NESTEDVM)/upstream/install/bin\n".
|
|
"CC = \$(TOOLPATH)/mips-unknown-elf-gcc\n".
|
|
"\n".
|
|
&splitline("CFLAGS = -O2 -Wall -Werror -DSLOW_SYSTEM -g " .
|
|
(join " ", map {"-I$dirpfx$_"} @srcdirs))."\n".
|
|
"\n";
|
|
print &splitline("all:" . join "", map { " $_.jar" } &progrealnames("X"));
|
|
print "\n\n";
|
|
foreach $p (&prognames("X")) {
|
|
($prog, $type) = split ",", $p;
|
|
$objstr = &objects($p, "X.o", undef, undef);
|
|
$objstr =~ s/gtk\.o/nestedvm\.o/g;
|
|
print &splitline($prog . ".mips: " . $objstr), "\n";
|
|
$libstr = &objects($p, undef, undef, "-lX");
|
|
print &splitline("\t\$(CC) \$(${type}LDFLAGS) -o \$@ " .
|
|
$objstr . " $libstr -lm", 69), "\n\n";
|
|
}
|
|
foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
|
|
$oobjs = $d->{obj};
|
|
$ddeps= join " ", @{$d->{deps}};
|
|
$oobjs =~ s/gtk/nestedvm/g;
|
|
$ddeps =~ s/gtk/nestedvm/g;
|
|
print &splitline(sprintf("%s: %s", $oobjs, $ddeps)),
|
|
"\n";
|
|
$deflist = join "", map { " -D$_" } @{$d->{defs}};
|
|
print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
|
|
" -c \$< -o \$\@\n";
|
|
}
|
|
print "\n";
|
|
print $makefile_extra{'nestedvm'} || "";
|
|
print "\nclean:\n".
|
|
"\trm -rf *.o *.mips *.class *.html *.jar org applet.manifest\n";
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
if (defined $makefiles{'osx'}) {
|
|
$mftyp = 'osx';
|
|
$dirpfx = &dirpfx($makefiles{'osx'}, "/");
|
|
@osxarchs = ('x86_64');
|
|
my $osxminver = "10.6";
|
|
|
|
##-- Mac OS X makefile
|
|
open OUT, ">$makefiles{'osx'}"; select OUT;
|
|
print
|
|
"# Makefile for $project_name under Mac OS X.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
# gcc command line option is -D not /D
|
|
($_ = $help) =~ s/=\/D/=-D/gs;
|
|
print $_;
|
|
print
|
|
"CC = \$(TOOLPATH)gcc\n".
|
|
"LIPO = \$(TOOLPATH)lipo\n".
|
|
"\n".
|
|
&splitline("CFLAGS = -O2 -Wall -Werror -g " .
|
|
(join " ", map {"-I$dirpfx$_"} @srcdirs))."\n".
|
|
"LDFLAGS = -framework Cocoa\n".
|
|
&splitline("all:" . join "", map { " $_" } &progrealnames("MX:U")) .
|
|
"\n";
|
|
print $makefile_extra{'osx'} || "";
|
|
print "\n".
|
|
".SUFFIXES: .o .c .m\n".
|
|
"\n";
|
|
print "\n\n";
|
|
foreach $p (&prognames("MX")) {
|
|
($prog, $type) = split ",", $p;
|
|
$icon = &special($p, ".icns");
|
|
$infoplist = &special($p, "info.plist");
|
|
print "${prog}.app:\n\tmkdir -p \$\@\n";
|
|
print "${prog}.app/Contents: ${prog}.app\n\tmkdir -p \$\@\n";
|
|
print "${prog}.app/Contents/MacOS: ${prog}.app/Contents\n\tmkdir -p \$\@\n";
|
|
$targets = "${prog}.app/Contents/MacOS/$prog";
|
|
if (defined $icon) {
|
|
print "${prog}.app/Contents/Resources: ${prog}.app/Contents\n\tmkdir -p \$\@\n";
|
|
print "${prog}.app/Contents/Resources/${prog}.icns: ${prog}.app/Contents/Resources $icon\n\tcp $icon \$\@\n";
|
|
$targets .= " ${prog}.app/Contents/Resources/${prog}.icns";
|
|
}
|
|
if (defined $infoplist) {
|
|
print "${prog}.app/Contents/Info.plist: ${prog}.app/Contents/Resources $infoplist\n\tcp $infoplist \$\@\n";
|
|
$targets .= " ${prog}.app/Contents/Info.plist";
|
|
}
|
|
$targets .= " \$(${prog}_extra)";
|
|
print &splitline("${prog}: $targets", 69) . "\n\n";
|
|
$libstr = &objects($p, undef, undef, "-lX");
|
|
$archbins = "";
|
|
foreach $arch (@osxarchs) {
|
|
$objstr = &objects($p, "X.${arch}.o", undef, undef);
|
|
print &splitline("${prog}.${arch}.bin: " . $objstr), "\n";
|
|
print &splitline("\t\$(CC) -arch ${arch} -mmacosx-version-min=${osxminver} \$(LDFLAGS) -o \$@ " .
|
|
$objstr . " $libstr", 69), "\n\n";
|
|
$archbins .= " ${prog}.${arch}.bin";
|
|
}
|
|
print &splitline("${prog}.app/Contents/MacOS/$prog: ".
|
|
"${prog}.app/Contents/MacOS" . $archbins), "\n";
|
|
print &splitline("\t\$(LIPO) -create $archbins -output \$@", 69), "\n\n";
|
|
}
|
|
foreach $p (&prognames("U")) {
|
|
($prog, $type) = split ",", $p;
|
|
$libstr = &objects($p, undef, undef, "-lX");
|
|
$archbins = "";
|
|
foreach $arch (@osxarchs) {
|
|
$objstr = &objects($p, "X.${arch}.o", undef, undef);
|
|
print &splitline("${prog}.${arch}: " . $objstr), "\n";
|
|
print &splitline("\t\$(CC) -arch ${arch} -mmacosx-version-min=${osxminver} \$(ULDFLAGS) -o \$@ " .
|
|
$objstr . " $libstr", 69), "\n\n";
|
|
$archbins .= " ${prog}.${arch}";
|
|
}
|
|
print &splitline("${prog}:" . $archbins), "\n";
|
|
print &splitline("\t\$(LIPO) -create $archbins -output \$@", 69), "\n\n";
|
|
}
|
|
foreach $arch (@osxarchs) {
|
|
foreach $d (&deps("X.${arch}.o", undef, $dirpfx, "/")) {
|
|
print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
|
|
"\n";
|
|
$deflist = join "", map { " -D$_" } @{$d->{defs}};
|
|
if ($d->{deps}->[0] =~ /\.m$/) {
|
|
print "\t\$(CC) -arch $arch -mmacosx-version-min=${osxminver} -x objective-c \$(COMPAT) \$(FWHACK) \$(CFLAGS)".
|
|
" \$(XFLAGS)$deflist -c \$< -o \$\@\n";
|
|
} else {
|
|
print "\t\$(CC) -arch $arch -mmacosx-version-min=${osxminver} \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
|
|
" -c \$< -o \$\@\n";
|
|
}
|
|
}
|
|
}
|
|
print "\nclean:\n".
|
|
"\trm -f *.o *.dmg". (join "", map { my $a=$_; (" $a", map { " ${a}.$_" } @osxarchs) } &progrealnames("U")) . "\n".
|
|
"\trm -rf *.app\n";
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
if (defined $makefiles{'gnustep'}) {
|
|
$mftyp = 'gnustep';
|
|
$dirpfx = &dirpfx($makefiles{'gnustep'}, "/");
|
|
|
|
##-- GNUstep makefile (use with 'gs_make -f Makefile.gnustep')
|
|
|
|
# This is a pretty evil way to do things. In an ideal world, I'd
|
|
# use the approved GNUstep makefile mechanism which just defines a
|
|
# variable or two saying what source files go into what binary and
|
|
# then includes application.make. Unfortunately, that has the
|
|
# automake-ish limitation that it doesn't let you choose different
|
|
# command lines for each object, so I can't arrange for all those
|
|
# files with -DTHIS and -DTHAT to Just Work.
|
|
#
|
|
# A simple if ugly fix would be to have mkfiles.pl construct a
|
|
# directory full of stub C files of the form '#define thing',
|
|
# '#include "real_source_file"', and then reference those in this
|
|
# makefile. That would also make it easy to build a proper
|
|
# automake makefile.
|
|
open OUT, ">$makefiles{'gnustep'}"; select OUT;
|
|
print
|
|
"# Makefile for $project_name under GNUstep.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
# gcc command line option is -D not /D
|
|
($_ = $help) =~ s/=\/D/=-D/gs;
|
|
print $_;
|
|
print
|
|
"NEEDS_GUI=yes\n".
|
|
"include \$(GNUSTEP_MAKEFILES)/common.make\n".
|
|
"include \$(GNUSTEP_MAKEFILES)/rules.make\n".
|
|
"include \$(GNUSTEP_MAKEFILES)/Instance/rules.make\n".
|
|
"\n".
|
|
&splitline("all::" . join "", map { " $_" } &progrealnames("MX:U")) .
|
|
"\n";
|
|
print $makefile_extra{'gnustep'} || "";
|
|
print "\n".
|
|
".SUFFIXES: .o .c .m\n".
|
|
"\n";
|
|
print "\n\n";
|
|
foreach $p (&prognames("MX")) {
|
|
($prog, $type) = split ",", $p;
|
|
$icon = &special($p, ".icns");
|
|
$infoplist = &special($p, "info.plist");
|
|
print "${prog}.app:\n\tmkdir -p \$\@\n";
|
|
$targets = "${prog}.app ${prog}.app/$prog";
|
|
if (defined $icon) {
|
|
print "${prog}.app/Resources: ${prog}.app\n\tmkdir -p \$\@\n";
|
|
print "${prog}.app/Resources/${prog}.icns: ${prog}.app/Resources $icon\n\tcp $icon \$\@\n";
|
|
$targets .= " ${prog}.app/Resources/${prog}.icns";
|
|
}
|
|
if (defined $infoplist) {
|
|
print "${prog}.app/Info.plist: ${prog}.app $infoplist\n\tcp $infoplist \$\@\n";
|
|
$targets .= " ${prog}.app/Info.plist";
|
|
}
|
|
$targets .= " \$(${prog}_extra)";
|
|
print &splitline("${prog}: $targets", 69) . "\n\n";
|
|
$libstr = &objects($p, undef, undef, "-lX");
|
|
$objstr = &objects($p, "X.o", undef, undef);
|
|
print &splitline("${prog}.app/$prog: " . $objstr), "\n";
|
|
print &splitline("\t\$(CC) \$(ALL_LDFLAGS) -o \$@ " . $objstr . " \$(ALL_LIB_DIRS) $libstr \$(ALL_LIBS)", 69), "\n\n";
|
|
}
|
|
foreach $p (&prognames("U")) {
|
|
($prog, $type) = split ",", $p;
|
|
$libstr = &objects($p, undef, undef, "-lX");
|
|
$objstr = &objects($p, "X.o", undef, undef);
|
|
print &splitline("${prog}: " . $objstr), "\n";
|
|
print &splitline("\t\$(CC) \$(ULDFLAGS) -o \$@ " . $objstr . " $libstr", 69), "\n\n";
|
|
}
|
|
foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
|
|
print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
|
|
"\n";
|
|
$deflist = join "", map { " -D$_" } @{$d->{defs}};
|
|
if ($d->{deps}->[0] =~ /\.m$/) {
|
|
print "\t\$(CC) -DGNUSTEP \$(ALL_OBJCFLAGS) \$(COMPAT) \$(FWHACK) \$(OBJCFLAGS)".
|
|
" \$(XFLAGS)$deflist -c \$< -o \$\@\n";
|
|
} else {
|
|
print "\t\$(CC) \$(ALL_CFLAGS) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
|
|
" -c \$< -o \$\@\n";
|
|
}
|
|
}
|
|
print "\nclean::\n".
|
|
"\trm -f *.o ". (join " ", &progrealnames("U")) . "\n".
|
|
"\trm -rf *.app\n";
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
if (defined $makefiles{'emcc'}) {
|
|
$mftyp = 'emcc';
|
|
$dirpfx = &dirpfx($makefiles{'emcc'}, "/");
|
|
|
|
##-- Makefile for building Javascript puzzles via Emscripten
|
|
|
|
open OUT, ">$makefiles{'emcc'}"; select OUT;
|
|
print
|
|
"# Makefile for $project_name using Emscripten. Requires GNU make.\n".
|
|
"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
|
|
"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
|
|
# emcc command line option is -D not /D
|
|
($_ = $help) =~ s/=\/D/=-D/gs;
|
|
print $_;
|
|
print
|
|
"\n".
|
|
"# This can be set on the command line to point at the emcc command,\n".
|
|
"# if it is not on your PATH.\n".
|
|
"EMCC = emcc\n".
|
|
"\n".
|
|
&splitline("CFLAGS = -DSLOW_SYSTEM " .
|
|
(join " ", map {"-I$dirpfx$_"} @srcdirs))."\n".
|
|
"\n";
|
|
$output_js_files = join "", map { " \$(OUTPREFIX)$_.js" } &progrealnames("X");
|
|
print &splitline("all:" . $output_js_files);
|
|
print "\n\n";
|
|
foreach $p (&prognames("X")) {
|
|
($prog, $type) = split ",", $p;
|
|
$objstr = &objects($p, "X.o", undef, undef);
|
|
$objstr =~ s/gtk\.o/emcc\.o/g;
|
|
print &splitline("\$(OUTPREFIX)" . $prog . ".js: " . $objstr . " emccpre.js emcclib.js emccx.json"), "\n";
|
|
print "\t\$(EMCC) -o \$(OUTPREFIX)".$prog.".js ".
|
|
"-O2 ".
|
|
"-s ASM_JS=1 ".
|
|
"--pre-js emccpre.js ".
|
|
"--js-library emcclib.js ".
|
|
"-s EXPORTED_FUNCTIONS=\"`sed 's://.*::' emccx.json | tr -d ' \\n'`\" " . $objstr . "\n\n";
|
|
}
|
|
foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
|
|
$oobjs = $d->{obj};
|
|
$ddeps= join " ", @{$d->{deps}};
|
|
$oobjs =~ s/gtk/emcc/g;
|
|
$ddeps =~ s/gtk/emcc/g;
|
|
print &splitline(sprintf("%s: %s", $oobjs, $ddeps)),
|
|
"\n";
|
|
$deflist = join "", map { " -D$_" } @{$d->{defs}};
|
|
print "\t\$(EMCC) \$(CFLAGS) \$(XFLAGS)$deflist" .
|
|
" -c \$< -o \$\@\n";
|
|
}
|
|
print "\n";
|
|
print $makefile_extra{'emcc'} || "";
|
|
print "\nclean:\n".
|
|
"\trm -rf *.o $output_js_files\n";
|
|
select STDOUT; close OUT;
|
|
}
|
|
|
|
# All done, so do the Unix postprocessing if asked to.
|
|
|
|
if ($do_unix) {
|
|
chdir $orig_dir;
|
|
system "./mkauto.sh";
|
|
die "mkfiles.pl: mkauto.sh returned $?\n" if $? > 0;
|
|
system "./configure", @confargs;
|
|
die "mkfiles.pl: configure returned $?\n" if $? > 0;
|
|
}
|