1
# ====================================================================
2
# Licensed to the Apache Software Foundation (ASF) under one
3
# or more contributor license agreements. See the NOTICE file
4
# distributed with this work for additional information
5
# regarding copyright ownership. The ASF licenses this file
6
# to you under the Apache License, Version 2.0 (the
7
# "License"); you may not use this file except in compliance
8
# with the License. You may obtain a copy of the License at
10
# http://www.apache.org/licenses/LICENSE-2.0
12
# Unless required by applicable law or agreed to in writing,
13
# software distributed under the License is distributed on an
14
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
# KIND, either express or implied. See the License for the
16
# specific language governing permissions and limitations
18
# ====================================================================
20
# Script to build all the dependencies for Subversion on Windows
21
# It's been written for Windows 8 and Visual Studio 2012, but
22
# it's entirely possible it will work with older versions of both.
24
# The goal here is not to necessarily have everyone using this script.
25
# But rather to be able to produce binary packages of the dependencies
26
# already built to allow developers to be able to download or checkout
27
# Subversion and quickly get up a development environment.
30
# Perl: http://www.activestate.com/activeperl/downloads
31
# Python: http://www.activestate.com/activepython/downloads
32
# 7-Zip: http://www.7-zip.org/download.html
33
# CMake: http://www.cmake.org/cmake/resources/software.html
34
# Microsoft Visual Studio 2012 (Ultimate has been tested, Express does not work)
36
# You probably want these on your PATH. The installers usually
37
# offer an option to do that for you so if you can let them.
39
# You are expected to run this script within the correct Visual Studio
40
# Shell. Probably "VS2012 x86 Native Tools Command Prompt". This
41
# sets the proper PATH arguments so that the the compiler tools are
45
# Find some way to work around the lack of devenv in Express (msbuild will help some)
46
# Include a package target that zips everything up.
47
# Perl script that runs the Subversion get-make.py tool with the right args.
48
# Alternatively update gen-make.py with an arg that knows about our layout.
49
# Make the Windows build not expect to go looking into source code (httpd/zlib)
50
# Add SWIG (to support checkout builds where SWIG generation hasn't been done).
51
# Usage/help output from the usual flags/on error input.
52
# Make SQLITE_VER friendly since we're using no dots right now.
53
# Work out the fixes to the projects' sources and contribute them back.
54
# Allow selection of Arch (x86 and x64)
55
# ZLib support for OpenSSL (have to patch openssl)
56
# Use CMake zlib build instead.
57
# Assembler support for OpenSSL.
58
# Add more specific commands to the command line (e.g. build-httpd)
60
###################################
61
###### V A R I A B L E S ######
62
###################################
64
# variables in the Vars package can be overriden from the command
65
# line with the FOO=BAR syntax. If you want any defaults to reference
66
# other variables the defaults need to be in set_defaults() below to
67
# allow the defaults to be set after processing user set variables.
69
# Paths to commands to use, provide full paths if it's not
70
# on your PATH already.
71
our $SEVEN_ZIP = 'C:\Program Files\7-Zip\7z.exe';
74
# Use the .com version so we get output, the .exe doesn't produce any output
75
our $DEVENV = 'devenv.com';
76
our $VCUPGRADE = 'vcupgrade';
77
our $PYTHON = 'python';
79
# Versions of the dependencies we will use
80
# Change these if you want but these are known to work with
82
our $HTTPD_VER = '2.4.4';
83
our $APR_VER = '1.4.6';
84
our $APU_VER = '1.5.2'; # apr-util version
85
our $API_VER = '1.2.1'; # arp-iconv version
86
our $ZLIB_VER = '1.2.8';
87
our $OPENSSL_VER = '1.0.1e';
88
our $PCRE_VER = '8.35';
89
our $BDB_VER = '5.3.21';
90
our $SQLITE_VER = '3071602';
91
our $SERF_VER = '1.3.6';
92
our $NEON_VER = '0.29.6';
94
# Sources for files to download
95
our $AWK_URL = 'http://www.cs.princeton.edu/~bwk/btl.mirror/awk95.exe';
107
our $PROJREF_URL = 'https://downloads.redhoundsoftware.com/blog/ProjRef.py';
109
# Location of the already downloaded file.
110
# by default these are undefined and set by the downloader.
111
# However, they can be overriden from the commandline and then
112
# the downloader is skipped. Note that BDB has no downloader
113
# so it must be overriden from the command line.
128
# Various directories we use
129
our $TOPDIR = Cwd::cwd(); # top of our tree
130
our $INSTDIR; # where we install to
131
our $BLDDIR; # directory where we actually build
132
our $SRCDIR; # directory where we store package files
137
our $SVN_VER = '1.9.x';
140
# Utility function to remove dots from a string
148
# unless the variable is already defined set the value
153
unless (defined($$var)) {
158
sub set_svn_ver_defaults {
159
my ($svn_major, $svn_minor, $svn_patch) = $SVN_VER =~ /^(\d+)\.(\d+)\.(.+)$/;
161
if ($svn_major > 1 or ($svn_major == 1 and $svn_minor >= 8)) {
162
$NEON=0 unless defined($NEON);
164
$NEON=1 unless defined($NEON);
168
# Any variables with defaults that reference other values
169
# should be set here. This defers setting of the default until runtime in these cases.
171
set_default(\$HTTPD_URL, "http://archive.apache.org/dist/httpd/httpd-$HTTPD_VER.tar.bz2");
172
set_default(\$APR_URL, "http://archive.apache.org/dist/apr/apr-$APR_VER.tar.bz2");
173
set_default(\$APU_URL, "http://archive.apache.org/dist/apr/apr-util-$APU_VER.tar.bz2");
174
set_default(\$API_URL, "http://archive.apache.org/dist/apr/apr-iconv-$API_VER.tar.bz2");
175
set_default(\$ZLIB_URL, "http://sourceforge.net/projects/libpng/files/zlib/$ZLIB_VER/zlib" . remove_dots($ZLIB_VER) . '.zip');
176
set_default(\$OPENSSL_URL, "http://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz");
177
set_default(\$PCRE_URL, "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-$PCRE_VER.zip");
178
set_default(\$BDB_URL, "http://download.oracle.com/berkeley-db/db-5.3.21.zip");
179
set_default(\$SQLITE_URL, "http://www.sqlite.org/2013/sqlite-amalgamation-$SQLITE_VER.zip");
180
set_default(\$SERF_URL, "http://serf.googlecode.com/svn/src_releases/serf-$SERF_VER.zip");
181
set_default(\$NEON_URL, "http://www.webdav.org/neon/neon-$NEON_VER.tar.gz");
182
set_default(\$INSTDIR, $TOPDIR);
183
set_default(\$BLDDIR, "$TOPDIR\\build");
184
set_default(\$SRCDIR, "$TOPDIR\\sources");
185
set_svn_ver_defaults();
188
#################################
189
###### M A I N ######
190
#################################
191
# You shouldn't have any reason to modify below this unless you've changed
192
# versions of something.
206
# Full path to perl, this shouldn't need to be messed with
207
my $PERL = $Config{perlpath};
209
# Directory constants that we setup for convenience, but that
210
# shouldn't be changed since they are assumed in the build systems
211
# of the various dependencies.
212
my $HTTPD; # Where httpd gets built
213
my $BDB; # Where bdb gets built
214
my $BINDIR; # where binaries are installed
215
my $LIBDIR; # where libraries are installed
216
my $INCDIR; # where headers are installed
217
my $SRCLIB; # httpd's srclib dir
219
# defer setting these values till runtime so users can override the
220
# user controlled vars they derive from.
222
$HTTPD = "$BLDDIR\\httpd";
223
$BDB = "$BLDDIR\\bdb";
224
$BINDIR = "$INSTDIR\\bin";
225
$LIBDIR = "$INSTDIR\\lib";
226
$INCDIR = "$INSTDIR\\include";
227
$SRCLIB = "$HTTPD\\srclib";
228
# Add bin to PATH this will be needed for at least awk later on
229
$ENV{PATH} = "$BINDIR;$ENV{PATH}";
230
# Setup LIB and INCLUDE so we can find BDB
231
$ENV{LIB} = "$LIBDIR;$ENV{LIB}";
232
$ENV{INCLUDE} = "$INCDIR;$ENV{INCLUDE}";
235
#####################
236
# UTILTIY FUNCTIONS #
237
#####################
239
# copy a file with error handling
244
copy($src, $dest) or die "Failed to copy $src to $dest: $!";
247
# Rename a file and deal with errors.
252
rename($src, $dest) or die "Failed to rename $src to $dest: $!";
255
# Utility function to chdir with error handling.
259
chdir($dir) or die "Failed to chdir to $dir: $!";
262
# Utility function to call system with error handling.
263
# First arg is an error message to print if something fails.
264
# Remaining args are passed to system.
266
my $error_msg = shift;
267
unless (system(@_) == 0) {
268
if (defined($error_msg)) {
269
die "$error_msg (exit code: $?)";
271
die "Failed while running '@_' (exit code: $?)";
276
# Like perl -pi.orig the second arg is a reference to a
277
# function that does whatever line processing you want.
278
# Note that $_ is used for the input and output of the
279
# function. So modifying $_ changes the line in the file.
280
# bak can be passed to set the backup extension. If the
281
# backup file already exists, shortcut this step.
282
sub modify_file_in_place {
287
unless (defined($bak)) {
291
my $backup = $file . $bak;
292
return if -e $backup;
293
rename_or_die($file, $backup);
294
open(IN, "<$backup") or die "Failed to open $backup: $!";
295
open(OUT, ">$file") or die "Failed to open $file: $!";
305
return if defined($VS_VER);
307
# using the vcupgrade command here because it has a consistent name and version
308
# numbering across versions including express versions.
309
my $help_output = `"$VCUPGRADE" /?`;
310
my ($major_version) = $help_output =~ /Version (\d+)\./s;
312
if (defined($major_version)) {
313
if ($major_version eq '12') {
316
} elsif ($major_version eq '11') {
319
} elsif ($major_version eq '10') {
325
die("Visual Studio Version Not Supported");
332
# Create directories that this script directly needs
333
sub prepare_structure {
334
# ignore errors the directories may already exist.
342
# Remove paths created by this script (directly or indecirectly)
343
# If the first arg is 1 it'll remove the downloaded files otherwise it
345
sub clean_structure {
346
# ignore errors in this function the paths may not exist
347
my $real_clean = shift;
356
rmtree("$INSTDIR\\serf");
357
rmtree("$INSTDIR\\neon");
358
rmtree("$INSTDIR\\sqlite-amalgamation");
360
# Dirs created indirectly by the install targets
361
rmtree("$INSTDIR\\man");
362
rmtree("$INSTDIR\\share");
363
rmtree("$INSTDIR\\ssl");
364
rmtree("$INSTDIR\\cgi-bin");
365
rmtree("$INSTDIR\\conf");
366
rmtree("$INSTDIR\\error");
367
rmtree("$INSTDIR\\htdocs");
368
rmtree("$INSTDIR\\icons");
369
rmtree("$INSTDIR\\logs");
370
rmtree("$INSTDIR\\manual");
371
rmtree("$INSTDIR\\modules");
372
unlink("$INSTDIR\\ABOUT_APACHE.txt");
373
unlink("$INSTDIR\\CHANGES.txt");
374
unlink("$INSTDIR\\INSTALL.txt");
375
unlink("$INSTDIR\\LICENSE.txt");
376
unlink("$INSTDIR\\NOTICE.txt");
377
unlink("$INSTDIR\\OPENSSL-NEWS.txt");
378
unlink("$INSTDIR\\OPENSSL-README.txt");
379
unlink("$INSTDIR\\README.txt");
386
# Download a url into a file if successful put the destination into the
387
# variable referenced by $dest_ref.
391
my $dest_ref = shift;
393
# If the variable referenced by $dest_ref is already set, skip downloading
394
# means we've been asked to use an already downloaded file.
395
return if (defined($$dest_ref));
397
print "Downloading $url\n";
398
# Using mirror() here so that repeated runs shouldn't try to keep downloading
400
my $response = mirror($url, $file);
401
if (is_error($response)) {
402
die "Couldn't save $url to $file received $response";
407
# Download all the dependencies we need
408
sub download_dependencies {
409
# putting awk in sources is a bit of a hack but it lets us
410
# avoid having to figure out what to delete when cleaning bin
411
download_file($AWK_URL, "$SRCDIR\\awk.exe", \$AWK_FILE);
412
unless(-x "$BINDIR\\awk.exe") { # skip the copy if it exists
413
copy_or_die($AWK_FILE, "$BINDIR\\awk.exe");
415
download_file($PROJREF_URL, "$SRCDIR\\ProjRef.py", \$PROJREF_FILE);
416
unless(-x "$BINDIR\\ProjRef.py") { # skip the copy if it exists
417
copy_or_die($PROJREF_FILE, $BINDIR);
419
download_file($BDB_URL, "$SRCDIR\\db.zip", \$BDB_FILE);
420
download_file($ZLIB_URL, "$SRCDIR\\zlib.zip", \$ZLIB_FILE);
421
download_file($OPENSSL_URL, "$SRCDIR\\openssl.tar.gz", \$OPENSSL_FILE);
422
download_file($HTTPD_URL, "$SRCDIR\\httpd.tar.bz2", \$HTTPD_FILE);
423
download_file($APR_URL, "$SRCDIR\\apr.tar.bz2", \$APR_FILE);
424
download_file($APU_URL, "$SRCDIR\\apr-util.tar.bz2", \$APU_FILE);
425
download_file($API_URL, "$SRCDIR\\apr-iconv.tar.bz2", \$API_FILE);
426
download_file($PCRE_URL, "$SRCDIR\\pcre.zip", \$PCRE_FILE);
427
download_file($SQLITE_URL, "$SRCDIR\\sqlite-amalgamation.zip", \$SQLITE_FILE);
428
download_file($SERF_URL, "$SRCDIR\\serf.zip", \$SERF_FILE);
429
download_file($NEON_URL, "$SRCDIR\\neon.tar.gz", \$NEON_FILE) if $NEON;
436
# Extract a compressed file with 7-zip into a given directory
437
# Skip extraction if destination of rename_to or expected_name exists
438
# if rename_to is set rename the path from expected_name to rename_to
441
my $container = shift;
442
my $expected_name = shift;
443
my $rename_to = shift;
445
if (defined($rename_to)) {
446
return if -d $rename_to;
447
} elsif (defined($expected_name)) {
448
return if -d $expected_name;
452
if (defined($container)) {
453
$dest_opt = qq(-o"$container" );
457
if ($file =~ /\.tar\.(bz2|gz)$/) {
458
$cmd = qq("$SEVEN_ZIP" x "$file" -so | "$SEVEN_ZIP" x -y -si -ttar $dest_opt);
460
$cmd = qq("$SEVEN_ZIP" x -y $dest_opt $file);
463
system_or_die("Problem extracting $file", $cmd);
464
if (defined($rename_to)) {
465
rename_or_die($expected_name, $rename_to);
469
sub extract_dependencies {
470
extract_file($BDB_FILE, $BLDDIR,
471
"$BLDDIR\\db-$BDB_VER", "$BLDDIR\\bdb");
472
extract_file($HTTPD_FILE, $BLDDIR,
473
"$BLDDIR\\httpd-$HTTPD_VER", "$BLDDIR\\httpd");
474
extract_file($APR_FILE, $SRCLIB,
475
"$SRCLIB\\apr-$APR_VER", "$SRCLIB\\apr");
476
extract_file($APU_FILE, $SRCLIB,
477
"$SRCLIB\\apr-util-$APU_VER", "$SRCLIB\\apr-util");
478
extract_file($API_FILE, $SRCLIB,
479
"$SRCLIB\\apr-iconv-$API_VER", "$SRCLIB\\apr-iconv");
480
# We fix the line endings before putting the non-Apache deps in place since it
481
# touches everything under httpd and there's no point in doing other things.
482
httpd_fix_lineends();
483
extract_file($ZLIB_FILE, $SRCLIB,
484
"$SRCLIB\\zlib-$ZLIB_VER", "$SRCLIB\\zlib");
485
extract_file($OPENSSL_FILE, $SRCLIB,
486
"$SRCLIB\\openssl-$OPENSSL_VER", "$SRCLIB\\openssl");
487
extract_file($PCRE_FILE, $SRCLIB,
488
"$SRCLIB\\pcre-$PCRE_VER", "$SRCLIB\\pcre");
489
extract_file($SQLITE_FILE, $INSTDIR,
490
"$INSTDIR\\sqlite-amalgamation-$SQLITE_VER",
491
"$INSTDIR\\sqlite-amalgamation");
492
extract_file($SERF_FILE, $INSTDIR,
493
"$INSTDIR\\serf-$SERF_VER", "$INSTDIR\\serf");
494
extract_file($NEON_FILE, $INSTDIR,
495
"$INSTDIR\\neon-$NEON_VER", "$INSTDIR\\neon") if $NEON;
503
chdir_or_die("$SRCLIB\\pcre");
504
my $pcre_generator = 'NMake Makefiles';
505
# Have to use RelWithDebInfo since httpd looks for the pdb files
506
my $pcre_build_type = '-DCMAKE_BUILD_TYPE:STRING=' . ($DEBUG ? 'Debug' : 'RelWithDebInfo');
507
my $pcre_options = '-DPCRE_NO_RECURSE:BOOL=ON';
508
my $pcre_shared_libs = '-DBUILD_SHARED_LIBS:BOOL=ON';
509
my $pcre_install_prefix = "-DCMAKE_INSTALL_PREFIX:PATH=$INSTDIR";
510
my $cmake_cmd = qq("$CMAKE" -G "$pcre_generator" "$pcre_build_type" "$pcre_shared_libs" "$pcre_install_prefix" "$pcre_options" .);
511
system_or_die("Failure generating pcre Makefiles", $cmake_cmd);
512
system_or_die("Failure building pcre", qq("$NMAKE"));
513
system_or_die("Failure testing pcre", qq("$NMAKE" test));
514
system_or_die("Failure installing pcre", qq("$NMAKE" install));
515
chdir_or_die($TOPDIR);
518
# This is based roughly off the build_zlib.bat that the Subversion Windows
519
# build generates, it it doesn't match that then Subversion will fail to build.
521
chdir_or_die("$SRCLIB\\zlib");
522
$ENV{CC_OPTS} = $DEBUG ? '/MDd /Gm /ZI /Od /GZ /D_DEBUG' : '/MD /02 /Zi';
523
$ENV{COMMON_CC_OPTS} = '/nologo /W3 /DWIN32 /D_WINDOWS';
525
system_or_die("Failure building zilb", qq("$NMAKE" /nologo -f win32\\Makefile.msc STATICLIB=zlibstat.lib all));
527
delete $ENV{CC_OPTS};
528
delete $ENV{COMMON_CC_OPTS};
530
chdir_or_die($TOPDIR);
534
chdir_or_die("$SRCLIB\\openssl");
536
# We're building openssl without an assembler. If someone wants to
537
# use this for production they should probably download NASM and
538
# remove the no-asm below and use ms\do_nasm.bat instead.
540
# TODO: Enable openssl to use zlib. openssl needs some patching to do
541
# this since it wants to look for zlib as zlib1.dll and as the httpd
542
# build instructions note you probably don't want to dynamic link zlib.
544
# TODO: OpenSSL requires perl on the path since it uses perl without a full
545
# path in the batch file and the makefiles. Probably should determine
546
# if PERL is on the path and add it here if not.
548
# The apache build docs suggest no-rc5 no-idea enable-mdc2 on top of what
549
# is used below, the primary driver behind that is patents, but I believe
550
# the rc5 and idea patents have expired.
551
my $platform = $DEBUG ? 'debug-VC-WIN32' : 'VC-WIN32';
552
system_or_die("Failure configuring openssl",
553
qq("$PERL" Configure no-asm "--prefix=$INSTDIR" $platform));
554
system_or_die("Failure building openssl (bat)", 'ms\do_ms.bat');
555
system_or_die("Failure building openssl (nmake)", qq("$NMAKE" /f ms\\ntdll.mak));
556
system_or_die("Failure testing openssl", qq("$NMAKE" /f ms\\ntdll.mak test));
557
system_or_die("Failure installing openssl",
558
qq("$NMAKE" /f ms\\ntdll.mak install));
559
chdir_or_die($TOPDIR);
562
# Run devenv /Upgrade on file.
563
# If the file isn't a .sln file and the sln file isn't empty shortcut this
564
# If the file isn't a .sln file touch the basename.sln of file to avoid
565
# Visual Studio whining about its backup step.
566
sub upgrade_solution {
568
my $interactive = shift;
571
my ($basename, $directories) = fileparse($file, qr/\.[^.]*$/);
572
my $sln = $directories . $basename . '.sln';
573
return if $file ne $sln and -s $sln; # shortcut if sln file is unique and isn't empty
574
# 'touch' the sln file so that Visual Studio 2012
575
# doesn't try to say there was an error while upgrading because
576
# it was unable to backup the original solution file.
578
open(SLN, ">$sln") or die "Can't create $sln: $!";
581
print "Upgrading $file (this may take a while)\n";
582
$flags = " /Upgrade" unless $interactive;
583
system_or_die("Failure upgrading $file", qq("$DEVENV" "$file"$flags));
585
print "Can't do automatic upgrade, doing interactive upgrade\n";
586
print "IDE will load, choose to convert all projects, exit the IDE and\n";
587
print "save the resulting solution file\n\n";
588
print "Press Enter to Continue\n";
593
# Run the lineends.pl script
594
sub httpd_fix_lineends {
595
chdir_or_die($HTTPD);
596
# This script fixes the lineendings to be CRLF in appropriate files.
597
# If we don't run this script then the DSW Upgrade will fail.
598
system_or_die(undef, qq("$PERL" "$SRCLIB\\apr\\build\\lineends.pl"));
599
chdir_or_die($TOPDIR);
602
# The httpd makefile in 2.4.4 doesn't know about .vcxproj files and
603
# still thinks it's got an older version of Visual Studio because
604
# .vcproj files have become .vcxproj.
605
sub httpd_fix_makefile {
608
modify_file_in_place($file, sub {
609
s/\.vcproj/.vcxproj/i;
610
# below fixes that installd breaks when trying to install pcre because
611
# dll is named pcred.dll when a Debug build.
612
s/^(\s*copy srclib\\pcre\\pcre\.\$\(src_dll\)\s+"\$\(inst_dll\)"\s+<\s*\.y\s*)$/!IF EXISTS("srclib\\pcre\\pcre\.\$(src_dll)")\n$1!ENDIF\n!IF EXISTS("srclib\\pcre\\pcred\.\$(src_dll)")\n\tcopy srclib\\pcre\\pcred.\$(src_dll)\t\t\t"\$(inst_dll)" <.y\n!ENDIF\n/;
616
# This is a poor mans way of inserting a property group into a
617
# vcxproj file. It assumes that the ending Project tag will
618
# be the start and end of the line with no whitespace, probably
619
# not an entirely valid assumption but it works in this case.
620
sub insert_property_group {
625
modify_file_in_place($file, sub {
626
s#(^</Project>$)#<PropertyGroup>$xml</PropertyGroup>\n$1#i;
630
# Strip pre-compiled headers compile and linker flags from file they follow
631
# the form: /Ycfoo.h or /Yufoo.h.
635
modify_file_in_place($file, sub {
640
# Find the first .exe .dll or .so OutputFile in the project
641
# provided by file. There may be macros or paths in the
643
sub get_output_file {
646
local $_; # Don't mess with the $_ from the find callback
648
open(IN, "<$file") or die "Couldn't open file $file: $!";
650
if (m#<OutputFile>(.*?\.(?:exec|dll|so))</OutputFile>#) {
659
# Find the name of the bdb library we've installed in our LIBDIR.
662
my $debug = $DEBUG ? 'd' : '';
664
if (not defined($result) and /^libdb\d+$debug\.lib$/) {
671
# Insert the dependency dep into project file.
672
# bak can be set to set the backup filename made of the project.
673
sub insert_dependency_in_proj {
678
modify_file_in_place($file, sub {
679
s/(%\(AdditionalDependencies\))/$dep;$1/;
683
# Do what's needed to enable BDB in the httpd and apr-util builds
684
sub httpd_enable_bdb {
685
# Make APU_HAVE_DB be true so the code builds.
686
modify_file_in_place('srclib\apr-util\include\apu.hw', sub {
687
s/(#define\s+APU_HAVE_DB\s+)0/${1}1/;
690
# Fix the linkage, apr_dbm_db is hardcoded to libdb47.lib
691
my $bdb_lib = find_bdb_lib();
692
modify_file_in_place('srclib\apr-util\dbm\apr_dbm_db.vcxproj', sub {
693
s/libdb\d+\.lib/$bdb_lib/g;
696
# httxt2dbm and htdbm need a BDB dependency and don't have one.
697
insert_dependency_in_proj('support\httxt2dbm.vcxproj', $bdb_lib, '.bdb');
698
insert_dependency_in_proj('support\htdbm.vcxproj', $bdb_lib, '.bdb');
701
# Apply the same fix as found in r1486937 on httpd 2.4.x branch.
702
sub httpd_fix_debug {
703
my ($httpd_major, $httpd_minor, $httpd_patch) = $HTTPD_VER =~ /^(\d+)\.(\d+)\.(.+)$/;
704
return unless ($httpd_major <= 2 && $httpd_minor <= 4 && $httpd_patch < 5);
706
modify_file_in_place('libhttpd.dsp', sub {
707
s/^(!MESSAGE "libhttpd - Win32 Debug" \(based on "Win32 \(x86\) Dynamic-Link Library"\))$/$1\n!MESSAGE "libhttpd - Win32 Lexical" (based on "Win32 (x86) Dynamic-Link Library")/;
708
s/^(# Begin Group "headers")$/# Name "libhttpd - Win32 Lexical"\n$1/;
713
chdir_or_die($HTTPD);
715
my $vs_2013 = $VS_VER eq '2013';
716
my $vs_2012 = $VS_VER eq '2012';
717
my $vs_2010 = $VS_VER eq '2010';
721
# I don't think cvtdsp.pl is necessary with Visual Studio 2012
722
# but it shouldn't hurt anything either. Including it allows
723
# for the possibility that this may work for older Visual Studio
725
system_or_die("Failure converting DSP files",
726
qq("$PERL" srclib\\apr\\build\\cvtdsp.pl -2005));
728
upgrade_solution('Apache.dsw', $vs_2010);
730
httpd_fix_makefile('Makefile.win');
732
# Modules and support projects randomly fail due to an error about the
733
# CL.read.1.tlog file already existing. This is really because of the
734
# intermediate dirs being shared between modules, but for the time being
735
# this works around it.
738
insert_property_group($_, '<TrackFileAccess>false</TrackFileAccess>')
740
}, 'modules', 'support');
742
if ($vs_2012 or $vs_2013) {
743
# Turn off pre-compiled headers for apr-iconv to avoid:
744
# LNK2011: http://msdn.microsoft.com/en-us/library/3ay26wa2(v=vs.110).aspx
745
disable_pch('srclib\apr-iconv\build\modules.mk.win');
747
# ApacheMonitor build fails due a duplicate manifest, turn off
749
insert_property_group('support\win32\ApacheMonitor.vcxproj',
750
'<GenerateManifest>false</GenerateManifest>',
753
# The APR libraries have projects named libapr but produce output named libapr-1
754
# The problem with this is in newer versions of Visual Studio TargetName defaults
755
# to the project name and not the basename of the output. Since the PDB file
756
# is named based on the TargetName the pdb file ends up being named libapr.pdb
757
# instead of libapr-1.pdb. The below call fixes this by explicitly providing
758
# a TargetName definition and shuts up some warnings about this problem as well.
759
# Without this fix the install fails when it tries to copy libapr-1.pdb.
760
# See this thread for details of the changes:
761
# http://social.msdn.microsoft.com/Forums/en-US/vcprerelease/thread/3c03e730-6a0e-4ee4-a0d6-6a5c3ce4343c
763
return unless (/\.vcxproj$/);
764
my $output_file = get_output_file($_);
765
return unless (defined($output_file));
766
my ($project_name) = fileparse($_, qr/\.[^.]*$/);
767
my ($old_style_target_name) = fileparse($output_file, qr/\.[^.]*$/);
768
return if ($old_style_target_name eq $project_name);
769
insert_property_group($_,
770
"<TargetName>$old_style_target_name</TargetName>", '.torig');
771
}, "$SRCLIB\\apr", "$SRCLIB\\apr-util", "$SRCLIB\\apr-iconv");
773
system_or_die("Failed fixing project guid references",
774
qq("$PYTHON" "$BINDIR\\ProjRef.py" -i Apache.sln"));
777
# If you're looking here it's possible that something went
778
# wrong with the httpd build. Debugging it can be a bit of a pain
779
# when using this script. There are log files created in the
780
# Release dirs named with the same basename as the project. E.G.
781
# for support\httxt2dbm.vcxproj you can find the log in
782
# support\Release\httxt2dbm.log. You can also run a similar build
783
# from in the IDE, but you'll need to disable some projects since
784
# they are separately driven by the Makefile.win. Grepping for
785
# '/project' in Makefile.win should tell you which projects. You'll
786
# also need to add the bin, include and lib paths to the appropriate
787
# configurations inside the project since we get them from the environment.
788
# Once all that is done the BuildBin project should be buildable for you to
789
# diagnose the problem.
790
my $target = $DEBUG ? "installd" : "installr";
791
system_or_die("Failed building/installing httpd/apr/apu/api",
792
qq("$NMAKE" /f Makefile.win $target "DBM_LIST=db" "INSTDIR=$INSTDIR"));
794
chdir_or_die($TOPDIR);
801
my $sln = 'build_windows\Berkeley_DB_vs2010.sln';
802
upgrade_solution($sln);
804
my $platform = $DEBUG ? 'Debug|Win32' : 'Release|Win32';
806
# Build the db Project first since the full solution fails due to a broken
807
# dependency with the current version of BDB if we don't.
808
system_or_die("Failed building DBD (Project db)",
809
qq("$DEVENV" "$sln" /Build "$platform" /Project db));
811
system_or_die("Failed building DBD",
812
qq("$DEVENV" "$sln" /Build "$platform"));
814
# BDB doesn't seem to have it's own install routines so we'll do it ourselves
815
copy_or_die('build_windows\db.h', $INCDIR);
817
if (/\.(exe|dll|pdb)$/) {
818
copy_or_die($_, $BINDIR);
820
copy_or_die($_, $LIBDIR);
822
}, 'build_windows\\Win32\\' . ($DEBUG ? 'Debug' : 'Release'));
824
chdir_or_die($TOPDIR);
827
# Right now this doesn't actually build serf but just patches it so that it
828
# can build against a debug build of OpenSSL.
830
chdir_or_die("$TOPDIR\\serf");
832
modify_file_in_place('serf.mak', sub {
833
s/^(INTDIR = Release)$/$1\nOPENSSL_OUT_SUFFIX =/;
834
s/^(INTDIR = Debug)$/$1\nOPENSSL_OUT_SUFFIX = .dbg/;
835
s/(\$\(OPENSSL_SRC\)\\out32(?:dll)?)/$1\$(OPENSSL_OUT_SUFFIX)/g;
838
chdir_or_die($TOPDIR);
841
sub build_dependencies {
854
# Implement an interface somewhat similar to the make command line
855
# You can give a list of commands and variable assignments interspersed.
856
# Variable assignments are always VAR=VALUE with no spaces (in a single
860
while (my $arg = shift @ARGV) {
861
# Look for variable assignment
862
if (my ($lhs, $rhs) = $arg =~ /([^=]+)=(.*)/) {
863
# Bit of hackery to allow the global values in the
864
# Vars package to be overriden from the command line.
865
# E.G. "CMAKE=C:\CMake\cmake.exe" would replace the
866
# default value with this value.
867
if (exists($Vars::{$lhs})) {
868
${$Vars::{$lhs}} = $rhs;
870
# Don't allow variables that don't exist already to be touched.
871
die "$lhs is an unknown variable.";
874
# Not a variable so must be a command
875
push @commands, $arg;
879
# No commands so add the implicit all command
880
if ($#commands == -1) {
881
push @commands, 'all';
884
# Set defaults and paths that have to be set at runtime since they are based
885
# on other variables.
886
Vars::set_defaults();
889
# Determine the Visual Studio Version and die if not supported.
892
# change directory to our TOPDIR before running any commands
893
# the variable assignment might have changed it.
894
chdir_or_die($TOPDIR);
896
# Run the commands in the order given.
897
foreach my $command (@commands) {
898
if ($command eq 'clean') {
900
} elsif ($command eq 'real-clean') {
902
} elsif ($command eq 'prepare') {
904
} elsif ($command eq 'download') {
905
download_dependencies();
906
} elsif ($command eq 'extract') {
907
extract_dependencies();
908
} elsif ($command eq 'all') {
910
download_dependencies();
911
extract_dependencies();
912
build_dependencies();
914
die "Command '$command' is unknown";