X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=mkfiles.pl;h=ae15ac488d66caec8b68db0c021c490058b4d2d9;hb=510f49e405e71ba5c97875e7a019364e1ef5fac9;hp=0e7484889e20244466b7d64fd1dbd497cf6f4645;hpb=9ddd071ec28050b3be572f25f3ae7d44e46e4039;p=PuTTY.git diff --git a/mkfiles.pl b/mkfiles.pl index 0e748488..ae15ac48 100755 --- a/mkfiles.pl +++ b/mkfiles.pl @@ -47,8 +47,8 @@ open IN, "Recipe" or do { # HACK: One of the source files in `charset' is auto-generated by # sbcsgen.pl, and licence.h is likewise generated by licence.pl. We # need to generate those _now_, before attempting dependency analysis. -eval 'chdir "charset"; require "sbcsgen.pl"; chdir ".."; select STDOUT;'; -eval 'require "licence.pl"; select STDOUT;'; +eval 'chdir "charset"; require "./sbcsgen.pl"; chdir ".."; select STDOUT;'; +eval 'require "./licence.pl"; select STDOUT;'; @srcdirs = ("./"); @@ -84,7 +84,15 @@ while () { 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 ""; + if ($rest eq "") { + # Make sure this file doesn't get lumped together with any + # other file's cflags. + $rest = "F" . $_[2]; + } else { + # Give this file a specific set of cflags, but permit it to + # go together with other files using the same set. + $rest = "C" . $rest; + } $cflags{$_[1]}->{$_[2]} = $rest; next; } @@ -135,7 +143,7 @@ while () { } elsif (($i =~ /^\[([A-Z]*)\]$/) and defined $prog) { $type = substr($i,1,(length $i)-2); die "unrecognised program type for $prog [$type]\n" - if ! grep { $type eq $_ } qw(G C X U MX UT); + if ! grep { $type eq $_ } qw(G C X U MX XT UT); } else { push @$listref, $i; } @@ -261,7 +269,7 @@ sub mfval($) { # prints a warning and returns false; if (grep { $type eq $_ } ("vc","vcproj","cygwin","borland","lcc","devcppproj","gtk","unix", - "am","osx","vstudio10","vstudio12")) { + "am","osx","vstudio10","vstudio12","clangcl")) { return 1; } warn "$.:unknown makefile type '$type'\n"; @@ -430,13 +438,135 @@ $orig_dir = cwd; # Now we're ready to output the actual Makefiles. +if (defined $makefiles{'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. + + 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=0x500 /DWINVER=0x500 ". + "/D_CRT_SECURE_NO_WARNINGS")."\n". + "LFLAGS = /incremental:no /dynamicbase /nxcompat\n". + &splitline("RCFLAGS = ".(join " ", map {"-I$dirpfx$_"} @srcdirs). + " -DWIN32 -D_WIN32 -DWINVER=0x0400")."\n". + "\n". + &def($makefile_extra{'clangcl'}->{'vars'}) . + "\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.o", undef); + print &splitline("\$(BUILDDIR)$prog.exe: " . $objstr), "\n"; + + $objstr = &objects($p, "\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res.o", "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) $objstr")."\n\n"; + } + foreach $d (&deps("\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res.o", $dirpfx, "/", "vc")) { + $extradeps = $forceobj{$d->{obj_orig}} ? ["*.c","*.h","*.rc"] : []; + print &splitline(sprintf("%s: %s", $d->{obj}, + join " ", @$extradeps, @{$d->{deps}})), "\n"; + if ($d->{obj} =~ /\.res\.o$/) { + print "\t\$(RC) \$(RCFLAGS) ".$d->{deps}->[0]." -o ".$d->{obj}."\n\n"; + } else { + print "\t\$(CC) /Fo\$(BUILDDIR) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) /c \$<\n\n"; + } + } + print "\n"; + print &def($makefile_extra{'clangcl'}->{'end'}); + print "\nclean:\n". + &splitline("\trm -f \$(BUILDDIR)*.obj \$(BUILDDIR)*.exe ". + "\$(BUILDDIR)*.res.o \$(BUILDDIR)*.map ". + "\$(BUILDDIR)*.exe.manifest")."\n"; + select STDOUT; close OUT; +} + if (defined $makefiles{'cygwin'}) { $dirpfx = &dirpfx($makefiles{'cygwin'}, "/"); - ##-- CygWin makefile + ##-- MinGW/CygWin makefile (called 'cygwin' for historical reasons) open OUT, ">$makefiles{'cygwin'}"; select OUT; print - "# Makefile for $project_name under Cygwin, MinGW, or Winelib.\n". + "# Makefile for $project_name under MinGW, Cygwin, or Winelib.\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 @@ -447,6 +577,7 @@ if (defined $makefiles{'cygwin'}) { "# 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". + "# TOOLPATH = i686-w64-mingw32-\n". "CC = \$(TOOLPATH)gcc\n". "RC = \$(TOOLPATH)windres\n". "# Uncomment the following two lines to compile under Winelib\n". @@ -455,11 +586,11 @@ if (defined $makefiles{'cygwin'}) { "# 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 -DNO_SECUREZEROMEMORY " . + &splitline("CFLAGS = -Wall -O2 -D_WINDOWS -DDEBUG -DWIN32S_COMPAT". + " -D_NO_OLDNAMES " . (join " ", map {"-I$dirpfx$_"} @srcdirs)) . "\n". - "LDFLAGS = -mno-cygwin -s\n". + "LDFLAGS = -s\n". &splitline("RCFLAGS = \$(RCINC) --define WIN32=1 --define _WIN32=1 ". "--define WINVER=0x0400 ".(join " ", map {"-I$dirpfx$_"} @srcdirs))."\n". "\n". @@ -636,8 +767,8 @@ if (defined $makefiles{'vc'}) { "# C compilation flags\n". "CFLAGS = /nologo /W3 /O1 " . (join " ", map {"-I$dirpfx$_"} @srcdirs) . - " /D_WINDOWS /D_WIN32_WINDOWS=0x500 /DWINVER=0x500\n". - "LFLAGS = /incremental:no /fixed\n". + " /D_WINDOWS /D_WIN32_WINDOWS=0x500 /DWINVER=0x500 /D_CRT_SECURE_NO_WARNINGS\n". + "LFLAGS = /incremental:no /dynamicbase /nxcompat\n". "RCFLAGS = ".(join " ", map {"-I$dirpfx$_"} @srcdirs). " -DWIN32 -D_WIN32 -DWINVER=0x0400\n". "\n". @@ -667,7 +798,7 @@ if (defined $makefiles{'vc'}) { print "$objlines[$i]\n"; } print "<<\n"; - print "\tlink \$(LFLAGS) \$(XLFLAGS) -out:\$(BUILDDIR)$prog.exe -map:\$(BUILDDIR)$prog.map -nologo -subsystem:$subsys \@$inlinefilename\n\n"; + print "\tlink \$(LFLAGS) \$(XLFLAGS) -out:\$(BUILDDIR)$prog.exe -map:\$(BUILDDIR)$prog.map -nologo -subsystem:$subsys\$(SUBSYSVER) \@$inlinefilename\n\n"; } foreach $d (&deps("\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", $dirpfx, "\\", "vc")) { $extradeps = $forceobj{$d->{obj_orig}} ? ["*.c","*.h","*.rc"] : []; @@ -1357,7 +1488,7 @@ if (defined $makefiles{'gtk'}) { "# building with GTK 1.2, or you can set it to `pkg-config gtk+-2.0 x11'\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 x11 \$\$0 2>/dev/null || gtk-config \$\$0'\n". + "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". "\n". "-include Makefile.local\n". "\n". @@ -1393,15 +1524,17 @@ if (defined $makefiles{'gtk'}) { ".SUFFIXES:\n". "\n". "\n"; - print &splitline("all:" . join "", map { " $_" } &progrealnames("X:U:UT")); + print &splitline("all:" . join "", map { " $_" } + &progrealnames("X:XT:U:UT")); print "\n\n"; - foreach $p (&prognames("X:U:UT")) { + foreach $p (&prognames("X:XT:U:UT")) { ($prog, $type) = split ",", $p; + ($ldflags = $type) =~ s/T$//; $objstr = &objects($p, "X.o", undef, undef); print &splitline($prog . ": " . $objstr), "\n"; $libstr = &objects($p, undef, undef, "-lX"); print &splitline("\t\$(CC) -o \$@ " . - $objstr . " \$(${type}LDFLAGS) $libstr", 69), "\n\n"; + $objstr . " \$(${ldflags}LDFLAGS) $libstr", 69), "\n\n"; } foreach $d (&deps("X.o", undef, $dirpfx, "/", "gtk")) { if ($forceobj{$d->{obj_orig}}) { @@ -1415,7 +1548,7 @@ if (defined $makefiles{'gtk'}) { print "\n"; print &def($makefile_extra{'gtk'}->{'end'}); print "\nclean:\n". - "\trm -f *.o". (join "", map { " $_" } &progrealnames("X:U:UT")) . "\n"; + "\trm -f *.o". (join "", map { " $_" } &progrealnames("X:XT:U:UT")) . "\n"; print "\nFORCE:\n"; select STDOUT; close OUT; } @@ -1506,7 +1639,8 @@ if (defined $makefiles{'am'}) { # 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. - @sources = ("allsources", "=", sort keys %allsourcefiles); + @sources = ("allsources", "=", + sort grep {$_ ne "empty.h"} keys %allsourcefiles); print &splitline(join " ", @sources), "\n\n"; @cliprogs = ("bin_PROGRAMS", "="); @@ -1530,7 +1664,16 @@ if (defined $makefiles{'am'}) { ($prog, $type) = split ",", $p; push @noinstcliprogs, $prog; } + @noinstallprogs = @noinstcliprogs; + foreach $p (&prognames("XT")) { + ($prog, $type) = split ",", $p; + push @noinstallprogs, $prog; + } + print "if HAVE_GTK\n"; + print &splitline(join " ", @noinstallprogs), "\n"; + print "else\n"; print &splitline(join " ", @noinstcliprogs), "\n"; + print "endif\n\n"; %objtosrc = (); foreach $d (&deps("X", undef, "", "/", "am")) { @@ -1550,17 +1693,19 @@ if (defined $makefiles{'am'}) { %amspeciallibs = (); foreach $obj (sort { $a cmp $b } keys %{$cflags{'am'}}) { + my $flags = $cflags{'am'}->{$obj}; + $flags = "" if $flags !~ s/^C//; print "lib${obj}_a_SOURCES = ", $objtosrc{$obj}, "\n"; print &splitline(join " ", "lib${obj}_a_CFLAGS", "=", @amcflags, - $cflags{'am'}->{$obj}), "\n"; + $flags), "\n"; $amspeciallibs{$obj} = "lib${obj}.a"; } print &splitline(join " ", "noinst_LIBRARIES", "=", sort { $a cmp $b } values %amspeciallibs), "\n\n"; - foreach $p (&prognames("X:U:UT")) { + foreach $p (&prognames("X:XT:U:UT")) { ($prog, $type) = split ",", $p; - print "if HAVE_GTK\n" if $type eq "X"; + print "if HAVE_GTK\n" if $type eq "X" || $type eq "XT"; @progsources = ("${prog}_SOURCES", "="); %sourcefiles = (); @ldadd = (); @@ -1574,13 +1719,13 @@ if (defined $makefiles{'am'}) { } push @progsources, sort { $a cmp $b } keys %sourcefiles; print &splitline(join " ", @progsources), "\n"; - if ($type eq "X") { + if ($type eq "X" || $type eq "XT") { push @ldadd, "\$(GTK_LIBS)"; } if (@ldadd) { print &splitline(join " ", "${prog}_LDADD", "=", @ldadd), "\n"; } - print "endif\n" if $type eq "X"; + print "endif\n" if $type eq "X" || $type eq "XT"; print "\n"; } print &def($makefile_extra{'am'}->{'end'});