Commit e0ee307a199fcf47523b395ce99052ec51e69476

Authored by Jay Berkenbilt
1 parent d4d7612b

Updates for newer Windows toolchain

README-windows.txt
... ... @@ -4,47 +4,51 @@ Common Setup
4 4 You may need to disable antivirus software to run qpdf's test suite.
5 5  
6 6 To be able to build qpdf and run its test suite, you must have MSYS
7   -from MinGW installed, and you must have ActiveState Perl. Here's what
8   -I did on my system:
  7 +from MinGW installed, and you must have ActiveState Perl. The Perl
  8 +provided by MSYS won't work reliably. It partially works, but some
  9 +tests will fail with it because it doesn't support all the
  10 +capabilities required by the test driver. Here's what I did on my
  11 +system:
9 12  
10   -Install ActiveState perl.
  13 +Install ActiveState perl. The versions of perl included with git bash
  14 +and mingw are not able to run the test suite.
11 15  
12   -Grab the latest mingw-get-inst. From the installation wizard, choose
13   -to install developer kit, C, and C++ support. Once installed, you
14   -will have an icon to start an msys shell. From the msys shell, run
  16 +Install MinGW-w64. From MinGW-w64 download page, grab the installer
  17 +and run it. First install the i686 compiler to C:\mingw-w64, and then
  18 +install x86_64 compiler to the same location. The installer will
  19 +automatically created mingw32 and mingw64 directories under mingw-w64.
15 20  
16   -mingw-get install msys-unzip msys-zip mingw32-make
  21 +Grab the latest mingw-get-inst from the MinGW project. We are using
  22 +this for shell and build utilties but not for the compiler. Run the
  23 +installer.
17 24  
18   -Then replace perl and make with the appropriate versions:
  25 +Install under basic:
  26 + mingw-developer-toolkit
  27 + msys-base
19 28  
20   -mv /bin/perl.exe /bin/msys-perl.exe
21   -mv /bin/make.exe /bin/msys-make.exe
22   -mv /mingw/bin/mingw32-make.exe /mingw/bin/make.exe
  29 +Use C:\mingw32\msys\1.0\msys.bat to start a shell. In the shell, run
23 30  
24   -Make sure perl --version shows ActiveState perl.
  31 +mingw32-get install msys-zip
25 32  
26   -To install MinGW-w64, first install msys and mingw32 as above.
  33 +Add to path in this order:
  34 + C:\mingw32\msys\1.0\bin
  35 + C:\mingw-w64\mingw64\bin
  36 + C:\mingw-w64\mingw32\bin
27 37  
28   -From MinGW-w64 download page, go to "Toolchains targeting
29   -Win64/Automated Builds" and find the latest mingw-w64 that runs under
30   -i686-mingw. It will be called something like
31   -mingw-w64-bin_i686-mingw_yyyymmdd.zip. The compiler binaries are
32   -32-bit, which (of course) runs on 64-bit Windows. Extract this under
33   -C:\MinGW-w64, and add C:\MinGW-w64\bin and C:\MinGW-w64\lib\mingw to
34   -the path.
  38 +ensuring that they are after ActiveState perl.
35 39  
36   -Starting in version 4.1.0, qpdf uses std::setprecision and std::fixed
37   -to format floating point numbers, and using one or both of those
38   -causes a crash with the version of libstdc++-6 that is included with
39   -mingw-w64-bin_i686-mingw_20111220.zip, which appears to be the latest
40   -mingw-hosted version of mingw that targets w64 that includes the full
41   -toolchain including all the DLL creation tools. To work around this,
42   -for my personal build, I have grabbed
43   -x86_64-w64-mingw32-gcc-4.7.2-release-win64_rubenvb.7z from the
44   -personal builds and just extracted libstdc++-6.dll from there and used
45   -that to replace the one in the 20111220 version, which is based on
46   -4.7.0. That particular workaround results in a Windows-hosted 64-bit
47   -targetted mingw that can build a qpdf that passes its test suite.
  40 +Check to make sure zip and unzip are in your path, make --version
  41 +shows at least 3.81, perl --version shows the perl from ActiveState,
  42 +and gcc --version is the 64-bit gcc. (zip is not actually needed
  43 +unless you are running the tools to create the releases.)
  44 +
  45 +Install suitable Microsoft Visual Studio edition. In early 2016, 2015
  46 +community edition with C++ support is fine. It may crash a few times
  47 +during installation, but repeating the installation will allow it to
  48 +finish, and the resulting software is stable.
  49 +
  50 +To build qpdf, start the msys shell from a command window started from
  51 +one of the Visual Studio shell windows.
48 52  
49 53 Image comparison tests are disabled by default, but it is possible to
50 54 run them on Windows. To do so, add --enable-test-compare-images from
... ... @@ -76,12 +80,6 @@ installers are provided, they might do that already by default.
76 80 binaries. Using "mklink" with "gswin32c.exe" is probably the best
77 81 choice.
78 82  
79   -Jian Ma <stronghorse@tom.com> has generously provided a port of QPDF
80   -that works with Microsoft VC6. Several changes are required, but they
81   -are well documented in his port. You can find the VC6 port in the
82   -contrib area of the qpdf download area. It may not always be
83   -up-to-date with the latest official qpdf release.
84   -
85 83  
86 84 External Libraries
87 85 ==================
... ... @@ -129,13 +127,13 @@ autofiles.zip that you can extract on top of a fresh checkout.
129 127 Building with MinGW
130 128 ===================
131 129  
132   -QPDF is known to build and pass its test suite with mingw (latest
133   -version tested: gcc 4.6.2), mingw64 (latest version tested: 4.7.0) and
134   -Microsoft Visual C++ 2010, both 32-bit and 64-bit versions. MSYS plus
135   -ActiveState Perl is required to build as well in order to get make
136   -and other related tools. While it is possible that Cygwin could be
137   -used to build native Windows versions of qpdf, this configuration has
138   -not been tested recently.
  130 +QPDF is known to build and pass its test suite with mingw-w64 using
  131 +the 32-bit and 64-bit compilers from that project (latest version
  132 +tested: 5.3.0) and Microsoft Visual C++ 2015, both 32-bit and 64-bit
  133 +versions. MSYS plus ActiveState Perl is required to build as well in
  134 +order to get make and other related tools. While it is possible that
  135 +Cygwin could be used to build native Windows versions of qpdf, this
  136 +configuration has not been tested recently.
139 137  
140 138 From your MSYS prompt, run
141 139  
... ... @@ -151,13 +149,7 @@ and then
151 149  
152 150 Note that ./config-mingw32 and ./configure-mingw64 just run
153 151 ./configure with specific arguments, so you can look at it, make
154   -adjustments, and manually run configure instead. Note also that
155   -config-mingw32 appends definition of _FILE_OFFSET_BITS=64 to
156   -qpdf-config.h since, as of the qpdf 3.0 release, the current versions
157   -of the autoconf tools did not correctly detect that mingw requires
158   -this to get large file support. This workaround is only required for
159   -mingw32. The 64-bit version of mingw works "out of the box" with
160   -large file support, as do both the 32-bit and 64-bit versions of MSVC.
  152 +adjustments, and manually run configure instead.
161 153  
162 154 Add the absolute path to the libqpdf/build directory to your PATH.
163 155 Make sure you can run the qpdf command by typing qpdf/build/qpdf and
... ... @@ -177,13 +169,11 @@ You can also take a look at make_windows_releases for reference. This
177 169 is how the distributed Windows executables are created.
178 170  
179 171  
180   -Building with MSVC 2010
  172 +Building with MSVC 2015
181 173 =======================
182 174  
183   -These instructions would likely work with newer version of MSVC or
184   -with full version of MSVC. They may also work with .NET 2005. They
185   -have only been tested with Visual C++ 2010. Earlier version of qpdf
186   -were built with MSVC 2008 Express.
  175 +These instructions would likely work with newer versions of MSVC and
  176 +are known to have worked with versions as old as 2008 Express.
187 177  
188 178 You should first set up your environment to be able to run MSVC from
189 179 the command line. There is usually a batch file included with MSVC
... ... @@ -192,7 +182,8 @@ configured for whichever of 32-bit or 64-bit output that you intend to
192 182 build for.
193 183  
194 184 From that cmd prompt, you can start your msys shell by just running
195   -manually whatever command is associated with your msys shell icon.
  185 +manually whatever command is associated with your msys shell icon
  186 +(such as C:\MinGW\msys\1.0\msys.bat).
196 187  
197 188 Configure as follows:
198 189  
... ... @@ -266,4 +257,6 @@ across the DLL to EXE boundary. Since qpdf uses exception handling
266 257 extensively for error handling, we have no choice but to redistribute
267 258 the C++ runtime DLLs. Maybe this will be addressed in a future
268 259 version of the compilers. This has not been retested with the
269   -toolchain versions used to create qpdf 3.0 distributions.
  260 +toolchain versions used to create qpdf 3.0 distributions. (This has
  261 +not been revisited since MSVC 2008, but redistrbuting runtime DLLs is
  262 +extremely common and should not be a problem.)
... ...
config-mingw32
1 1 #!/bin/sh
2   -./configure --disable-test-compare-images --enable-external-libs --enable-werror --with-windows-wordsize=32 --with-buildrules=mingw ${1+"$@"}
3   -# As of autoconf 2.69 and gcc 4.6, autoconf's configure fails to
4   -# recognize that defining _FILE_OFFSET_BITS works with mingw32.
5   -# Append to qpdf-config.h rather than passing CPPFLAGS on the
6   -# commandline. This way we don't defeat the fact that test_large_file
7   -# and other things that only use the public interface can be built
8   -# without any special flags.
9   -cat >> libqpdf/qpdf/qpdf-config.h <<EOF
10   -#ifndef _FILE_OFFSET_BITS
11   -# define _FILE_OFFSET_BITS 64
12   -#endif
13   -EOF
  2 +./configure --disable-test-compare-images --enable-external-libs --enable-werror --with-windows-wordsize=32 --with-buildrules=mingw \
  3 + CC=i686-w64-mingw32-gcc \
  4 + CXX=i686-w64-mingw32-g++ \
  5 + LD=i686-w64-mingw32-ld \
  6 + AR=i686-w64-mingw32-ar \
  7 + RANLIB=i686-w64-mingw32-ranlib \
  8 + DLLTOOL=$(dirname $(type -p i686-w64-mingw32-gcc))/dlltool \
  9 + STRIP=i686-w64-mingw32-strip \
  10 + OBJDUMP=$(dirname $(type -p i686-w64-mingw32-gcc))/objdump \
  11 + ${1+"$@"}
... ...
config-mingw64
... ... @@ -5,7 +5,7 @@
5 5 LD=x86_64-w64-mingw32-ld \
6 6 AR=x86_64-w64-mingw32-ar \
7 7 RANLIB=x86_64-w64-mingw32-ranlib \
8   - DLLTOOL=x86_64-w64-mingw32-dlltool \
  8 + DLLTOOL=$(dirname $(type -p x86_64-w64-mingw32-gcc))/dlltool \
9 9 STRIP=x86_64-w64-mingw32-strip \
10   - OBJDUMP=x86_64-w64-mingw32-objdump \
  10 + OBJDUMP=$(dirname $(type -p x86_64-w64-mingw32-gcc))/objdump \
11 11 ${1+"$@"}
... ...
config-msvc
... ... @@ -7,6 +7,8 @@ fi
7 7 shift
8 8 objdump=
9 9 if test "$wordsize" = "64"; then
10   - objdump=OBJDUMP=x86_64-w64-mingw32-objdump
  10 + objdump=$(dirname $(type -p x86_64-w64-mingw32-gcc))/objdump
  11 +else
  12 + objdump=$(dirname $(type -p i686-w64-mingw32-gcc))/objdump
11 13 fi
12   -CC=cl CXX="cl -TP -GR" ./configure --disable-test-compare-images --enable-external-libs --enable-werror --with-windows-wordsize=$wordsize --with-buildrules=msvc $objdump ${1+"$@"}
  14 +CC=cl CXX="cl -TP -GR" ./configure --disable-test-compare-images --enable-external-libs --enable-werror --with-windows-wordsize=$wordsize --with-buildrules=msvc OBJDUMP=$objdump ${1+"$@"}
... ...
copy_dlls
... ... @@ -7,8 +7,8 @@ use File::Basename;
7 7  
8 8 my $whoami = basename($0);
9 9  
10   -usage() unless @ARGV == 3;
11   -my ($file, $destdir, $objdump) = @ARGV;
  10 +usage() unless @ARGV == 4;
  11 +my ($file, $destdir, $objdump, $windows_wordsize) = @ARGV;
12 12 my $filedir = dirname($file);
13 13  
14 14 my %dlls = ();
... ... @@ -40,10 +40,39 @@ if (! defined $format)
40 40 # DLLs.
41 41 my $sep = ($^O eq 'MSWin32' ? ';' : ':');
42 42 my @path = ($filedir, '.', split($sep, $ENV{'PATH'}));
  43 +foreach my $var (qw(LIB))
  44 +{
  45 + if (exists $ENV{$var})
  46 + {
  47 + push(@path, split($sep, $ENV{$var}));
  48 + }
  49 +}
43 50 if (-f "$file.manifest")
44 51 {
45 52 unshift(@path, get_manifest_dirs("$file.manifest"));
46 53 }
  54 +my $redist_suffix = (($windows_wordsize eq '64') ? "x64" : "x86");
  55 +if (exists $ENV{'VCINSTALLDIR'})
  56 +{
  57 + my $redist = $ENV{'VCINSTALLDIR'} . "/Redist/$redist_suffix";
  58 + if (opendir(D, $redist))
  59 + {
  60 + my @entries = readdir(D);
  61 + closedir(D);
  62 + foreach my $e (@entries)
  63 + {
  64 + if ($e =~ m/\.CRT$/i)
  65 + {
  66 + unshift(@path, "$redist/$e");
  67 + }
  68 + }
  69 + }
  70 +}
  71 +if (exists $ENV{'UNIVERSALCRTSDKDIR'})
  72 +{
  73 + my $redist = $ENV{'UNIVERSALCRTSDKDIR'} . "/Redist/ucrt/DLLs/$redist_suffix";
  74 + unshift(@path, $redist);
  75 +}
47 76 my @final = ();
48 77 my @notfound = ();
49 78 dll_loop:
... ... @@ -75,7 +104,7 @@ foreach my $f (@final)
75 104 {
76 105 $f =~ s,\\,/,g;
77 106 print "Copying $f to $destdir\n";
78   - system("cp -p $f $destdir") == 0 or
  107 + system("cp -p '$f' '$destdir'") == 0 or
79 108 die "$whoami: copy $f to $destdir failed\n";
80 109 }
81 110  
... ... @@ -92,7 +121,7 @@ sub is_format
92 121 return 1;
93 122 }
94 123 my $result = 0;
95   - my $file_format = `file $file`;
  124 + my $file_format = `file "$file"`;
96 125 print "$file $format $file_format\n";
97 126 if ($? == 0)
98 127 {
... ...
make/installwin.mk
... ... @@ -10,7 +10,7 @@ installwin: all
10 10 mkdir $(DEST)/doc
11 11 cp libqpdf/$(OUTPUT_DIR)/$(STATIC_LIB_NAME) $(DEST)/lib
12 12 cp libqpdf/$(OUTPUT_DIR)/qpdf*.dll $(DEST)/bin
13   - perl copy_dlls libqpdf/$(OUTPUT_DIR)/qpdf*.dll $(DEST)/bin $(OBJDUMP)
  13 + perl copy_dlls libqpdf/$(OUTPUT_DIR)/qpdf*.dll $(DEST)/bin $(OBJDUMP) $(WINDOWS_WORDSIZE)
14 14 cp qpdf/$(OUTPUT_DIR)/qpdf.exe $(DEST)/bin
15 15 cp zlib-flate/$(OUTPUT_DIR)/zlib-flate.exe $(DEST)/bin
16 16 cp qpdf/fix-qdf $(DEST)/bin
... ...
make/msvc.mk
... ... @@ -27,47 +27,47 @@ clean::
27 27 # 1 2
28 28 # Usage: $(call compile,src,includes)
29 29 define compile
30   - cl /nologo /O2 /Zi /Gy /EHsc /MD /TP /GR $(CPPFLAGS) $(CXXFLAGS) \
  30 + cl -nologo -O2 -Zi -Gy -EHsc -MD -TP -GR $(CPPFLAGS) $(CXXFLAGS) \
31 31 $(foreach I,$(2),-I$(I)) \
32   - /c $(1) /Fo$(call src_to_obj,$(1))
  32 + -c $(1) -Fo$(call src_to_obj,$(1))
33 33 endef
34 34  
35 35 # 1 2
36 36 # Usage: $(call c_compile,src,includes)
37 37 define c_compile
38   - cl /nologo /O2 /Zi /Gy /EHsc /MD $(CPPFLAGS) $(CFLAGS) \
  38 + cl -nologo -O2 -Zi -Gy -EHsc -MD $(CPPFLAGS) $(CFLAGS) \
39 39 $(foreach I,$(2),-I$(I)) \
40   - /c $(1) /Fo$(call c_src_to_obj,$(1))
  40 + -c $(1) -Fo$(call c_src_to_obj,$(1))
41 41 endef
42 42  
43 43 # 1 2
44 44 # Usage: $(call libcompile,src,includes)
45 45 define libcompile
46   - cl /nologo /O2 /Zi /Gy /EHsc /MD /TP /GR $(CPPFLAGS) $(CXXFLAGS) \
  46 + cl -nologo -O2 -Zi -Gy -EHsc -MD -TP -GR $(CPPFLAGS) $(CXXFLAGS) \
47 47 -DDLL_EXPORT $(foreach I,$(2),-I$(I)) \
48   - /c $(1) /Fo$(call src_to_obj,$(1))
  48 + -c $(1) -Fo$(call src_to_obj,$(1))
49 49 endef
50 50  
51 51 # 1 2
52 52 # Usage: $(call c_libcompile,src,includes)
53 53 define c_libcompile
54   - cl /nologo /O2 /Zi /Gy /EHsc /MD $(CPPFLAGS) $(CXXFLAGS) \
  54 + cl -nologo -O2 -Zi -Gy -EHsc -MD $(CPPFLAGS) $(CXXFLAGS) \
55 55 -DDLL_EXPORT $(foreach I,$(2),-I$(I)) \
56   - /c $(1) /Fo$(call c_src_to_obj,$(1))
  56 + -c $(1) -Fo$(call c_src_to_obj,$(1))
57 57 endef
58 58  
59 59 # 1 2
60 60 # Usage: $(call makeslib,objs,library)
61 61 define makeslib
62   - lib /nologo /OUT:$(2) $(1)
  62 + lib -nologo -OUT:$(2) $(1)
63 63 endef
64 64  
65 65 # 1 2 3 4 5 6 7
66 66 # Usage: $(call makelib,objs,library,ldflags,libs,current,revision,age)
67 67 define makelib
68   - cl /nologo /O2 /Zi /Gy /EHsc /MD /LD /Fe$(basename $(2))$(shell expr $(5) - $(7)).dll $(1) \
69   - /link /SUBSYSTEM:CONSOLE,5.01 /incremental:no \
70   - $(foreach L,$(subst -L,,$(3)),/LIBPATH:$(L)) \
  68 + cl -nologo -O2 -Zi -Gy -EHsc -MD -LD -Fe$(basename $(2))$(shell expr $(5) - $(7)).dll $(1) \
  69 + -link -SUBSYSTEM:CONSOLE,5.01 -incremental:no \
  70 + $(foreach L,$(subst -L,,$(3)),-LIBPATH:$(L)) \
71 71 $(foreach L,$(subst -l,,$(4)),$(L).lib)
72 72 if [ -f $(basename $(2))$(shell expr $(5) - $(7)).dll.manifest ]; then \
73 73 mt.exe -nologo -manifest $(basename $(2))$(shell expr $(5) - $(7)).dll.manifest \
... ... @@ -79,9 +79,9 @@ endef
79 79 # 1 2 3 4
80 80 # Usage: $(call makebin,objs,binary,ldflags,libs)
81 81 define makebin
82   - cl /nologo /O2 /Zi /Gy /EHsc /MD $(1) \
83   - /link /SUBSYSTEM:CONSOLE,5.01 /incremental:no /OUT:$(2) \
84   - $(foreach L,$(subst -L,,$(3)),/LIBPATH:$(L)) \
  82 + cl -nologo -O2 -Zi -Gy -EHsc -MD $(1) \
  83 + -link -SUBSYSTEM:CONSOLE,5.01 -incremental:no -OUT:$(2) \
  84 + $(foreach L,$(subst -L,,$(3)),-LIBPATH:$(L)) \
85 85 $(foreach L,$(subst -l,,$(4)),$(L).lib)
86 86 if [ -f $(2).manifest ]; then \
87 87 mt.exe -nologo -manifest $(2).manifest \
... ...
make_windows_releases
... ... @@ -12,11 +12,11 @@ PATH=$cwd/libqpdf/build:$PATH
12 12 rm -rf install-mingw* install-msvc*
13 13  
14 14 ./config-mingw64
15   -make -j8
  15 +make
16 16 make check install
17 17 make distclean
18 18 ./config-mingw32
19   -make -j8
  19 +make
20 20 make check install
21 21 make distclean
22 22  
... ...
make_windows_releases-msvc
... ... @@ -17,6 +17,6 @@ cwd=`pwd`
17 17 PATH=$cwd/libqpdf/build:$PATH
18 18  
19 19 ./config-msvc $w
20   -make -j8
  20 +make
21 21 make check install
22 22 make distclean
... ...