~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to tools/dev/build-svn-deps-win.pl

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2015-08-07 21:32:47 UTC
  • mfrom: (0.2.15) (4.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20150807213247-ozyewtmgsr6tkewl
Tags: 1.9.0-1
* Upload to unstable
* New upstream release.
  + Security fixes
    - CVE-2015-3184: Mixed anonymous/authenticated path-based authz with
      httpd 2.4
    - CVE-2015-3187: svn_repos_trace_node_locations() reveals paths hidden
      by authz
* Add >= 2.7 requirement for python-all-dev Build-Depends, needed to run
  tests.
* Remove Build-Conflicts against ruby-test-unit.  (Closes: #791844)
* Remove patches/apache_module_dependency in favor of expressing the
  dependencies in authz_svn.load/dav_svn.load.
* Build-Depend on apache2-dev (>= 2.4.16) to ensure ap_some_authn_required()
  is available when building mod_authz_svn and Depend on apache2-bin (>=
  2.4.16) for runtime support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
9
#
 
10
#      http://www.apache.org/licenses/LICENSE-2.0
 
11
#
 
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
 
17
#    under the License.
 
18
# ====================================================================
 
19
#
 
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.
 
23
 
 
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.
 
28
 
 
29
# Prerequisites:
 
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)
 
35
#
 
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.
 
38
#
 
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
 
42
# available.
 
43
#
 
44
# TODO:
 
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)
 
59
 
 
60
###################################
 
61
######   V A R I A B L E S   ######
 
62
###################################
 
63
package Vars;
 
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.
 
68
 
 
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';
 
72
our $CMAKE = 'cmake';
 
73
our $NMAKE = 'nmake';
 
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';
 
78
 
 
79
# Versions of the dependencies we will use
 
80
# Change these if you want but these are known to work with
 
81
# this script as is.
 
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';
 
93
 
 
94
# Sources for files to download
 
95
our $AWK_URL = 'http://www.cs.princeton.edu/~bwk/btl.mirror/awk95.exe';
 
96
our $HTTPD_URL;
 
97
our $APR_URL;
 
98
our $APU_URL;
 
99
our $API_URL;
 
100
our $ZLIB_URL;
 
101
our $OPENSSL_URL;
 
102
our $PCRE_URL;
 
103
our $BDB_URL;
 
104
our $SQLITE_URL;
 
105
our $SERF_URL;
 
106
our $NEON_URL;
 
107
our $PROJREF_URL = 'https://downloads.redhoundsoftware.com/blog/ProjRef.py';
 
108
 
 
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.
 
114
our $AWK_FILE;
 
115
our $HTTPD_FILE;
 
116
our $APR_FILE;
 
117
our $APU_FILE;
 
118
our $API_FILE;
 
119
our $ZLIB_FILE;
 
120
our $OPENSSL_FILE;
 
121
our $PCRE_FILE;
 
122
our $BDB_FILE;
 
123
our $SQLITE_FILE;
 
124
our $SERF_FILE;
 
125
our $NEON_FILE;
 
126
our $PROJREF_FILE;
 
127
 
 
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
 
133
 
 
134
# Some other options
 
135
our $VS_VER;
 
136
our $NEON;
 
137
our $SVN_VER = '1.9.x';
 
138
our $DEBUG = 0;
 
139
 
 
140
# Utility function to remove dots from a string
 
141
sub remove_dots {
 
142
  my $in = shift;
 
143
 
 
144
  $in =~ tr/.//d;
 
145
  return $in;
 
146
}
 
147
 
 
148
# unless the variable is already defined set the value
 
149
sub set_default {
 
150
  my $var = shift;
 
151
  my $value = shift;
 
152
 
 
153
  unless (defined($$var)) {
 
154
    $$var = $value;
 
155
  }
 
156
}
 
157
 
 
158
sub set_svn_ver_defaults {
 
159
  my ($svn_major, $svn_minor, $svn_patch) = $SVN_VER =~ /^(\d+)\.(\d+)\.(.+)$/;
 
160
 
 
161
  if ($svn_major > 1 or ($svn_major == 1 and $svn_minor >= 8)) {
 
162
    $NEON=0 unless defined($NEON);
 
163
  } else {
 
164
    $NEON=1 unless defined($NEON);
 
165
  }
 
166
}
 
167
 
 
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.
 
170
sub set_defaults {
 
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();
 
186
}
 
187
 
 
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.
 
193
package main;
 
194
 
 
195
use warnings;
 
196
use strict;
 
197
 
 
198
use LWP::Simple;
 
199
use File::Path;
 
200
use File::Copy;
 
201
use File::Basename;
 
202
use File::Find;
 
203
use Cwd;
 
204
use Config;
 
205
 
 
206
# Full path to perl, this shouldn't need to be messed with
 
207
my $PERL = $Config{perlpath};
 
208
 
 
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
 
218
 
 
219
# defer setting these values till runtime so users can override the
 
220
# user controlled vars they derive from.
 
221
sub set_paths {
 
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}";
 
233
}
 
234
 
 
235
#####################
 
236
# UTILTIY FUNCTIONS #
 
237
#####################
 
238
 
 
239
# copy a file with error handling
 
240
sub copy_or_die {
 
241
  my $src = shift;
 
242
  my $dest = shift;
 
243
 
 
244
  copy($src, $dest) or die "Failed to copy $src to $dest: $!";
 
245
}
 
246
 
 
247
# Rename a file and deal with errors.
 
248
sub rename_or_die {
 
249
  my $src = shift;
 
250
  my $dest = shift;
 
251
 
 
252
  rename($src, $dest) or die "Failed to rename $src to $dest: $!";
 
253
}
 
254
 
 
255
# Utility function to chdir with error handling.
 
256
sub chdir_or_die {
 
257
  my $dir = shift;
 
258
 
 
259
  chdir($dir) or die "Failed to chdir to $dir: $!";
 
260
}
 
261
 
 
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.
 
265
sub system_or_die {
 
266
  my $error_msg = shift;
 
267
  unless (system(@_) == 0) {
 
268
    if (defined($error_msg)) {
 
269
      die "$error_msg (exit code: $?)";
 
270
    } else {
 
271
      die "Failed while running '@_' (exit code: $?)";
 
272
    }
 
273
  }
 
274
}
 
275
 
 
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 {
 
283
  my $file = shift;
 
284
  my $func = shift;
 
285
  my $bak = shift;
 
286
 
 
287
  unless (defined($bak)) {
 
288
    $bak = '.orig';
 
289
  }
 
290
 
 
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: $!";
 
296
  while (<IN>) {
 
297
    &{$func}();
 
298
    print OUT;
 
299
  }
 
300
  close(IN);
 
301
  close(OUT);
 
302
}
 
303
 
 
304
sub check_vs_ver {
 
305
  return if defined($VS_VER);
 
306
 
 
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;
 
311
 
 
312
  if (defined($major_version)) {
 
313
    if ($major_version eq '12') {
 
314
      $VS_VER = '2013';
 
315
      return;
 
316
    } elsif ($major_version eq '11') {
 
317
      $VS_VER = '2012';
 
318
      return;
 
319
    } elsif ($major_version eq '10') {
 
320
      $VS_VER = '2010';
 
321
      return;
 
322
    }
 
323
  }
 
324
 
 
325
  die("Visual Studio Version Not Supported");
 
326
}
 
327
 
 
328
##################
 
329
# TREE STRUCTURE #
 
330
##################
 
331
 
 
332
# Create directories that this script directly needs
 
333
sub prepare_structure {
 
334
  # ignore errors the directories may already exist.
 
335
  mkdir($BINDIR);
 
336
  mkdir($SRCDIR);
 
337
  mkdir($BLDDIR);
 
338
  mkdir($LIBDIR);
 
339
  mkdir($INCDIR);
 
340
}
 
341
 
 
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
 
344
# leaves them alone.
 
345
sub clean_structure {
 
346
  # ignore errors in this function the paths may not exist
 
347
  my $real_clean = shift;
 
348
 
 
349
  if ($real_clean) {
 
350
    rmtree($SRCDIR);
 
351
  }
 
352
  rmtree($BINDIR);
 
353
  rmtree($BLDDIR);
 
354
  rmtree($INCDIR);
 
355
  rmtree($LIBDIR);
 
356
  rmtree("$INSTDIR\\serf");
 
357
  rmtree("$INSTDIR\\neon");
 
358
  rmtree("$INSTDIR\\sqlite-amalgamation");
 
359
 
 
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");
 
380
}
 
381
 
 
382
############
 
383
# DOWNLOAD #
 
384
############
 
385
 
 
386
# Download a url into a file if successful put the destination into the
 
387
# variable referenced by $dest_ref.
 
388
sub download_file {
 
389
  my $url = shift;
 
390
  my $file = shift;
 
391
  my $dest_ref = shift;
 
392
 
 
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));
 
396
 
 
397
  print "Downloading $url\n";
 
398
  # Using mirror() here so that repeated runs shouldn't try to keep downloading
 
399
  # the file.
 
400
  my $response = mirror($url, $file);
 
401
  if (is_error($response)) {
 
402
    die "Couldn't save $url to $file received $response";
 
403
  }
 
404
  $$dest_ref = $file;
 
405
}
 
406
 
 
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");
 
414
  }
 
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);
 
418
  }
 
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;
 
430
}
 
431
 
 
432
##############
 
433
# EXTRACTION #
 
434
##############
 
435
 
 
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
 
439
sub extract_file {
 
440
  my $file = shift;
 
441
  my $container = shift;
 
442
  my $expected_name = shift;
 
443
  my $rename_to = shift;
 
444
 
 
445
  if (defined($rename_to)) {
 
446
    return if -d $rename_to;
 
447
  } elsif (defined($expected_name)) {
 
448
    return if -d $expected_name;
 
449
  }
 
450
 
 
451
  my $dest_opt = "";
 
452
  if (defined($container)) {
 
453
    $dest_opt = qq(-o"$container" );
 
454
  }
 
455
 
 
456
  my $cmd;
 
457
  if ($file =~ /\.tar\.(bz2|gz)$/) {
 
458
    $cmd = qq("$SEVEN_ZIP" x "$file" -so | "$SEVEN_ZIP" x -y -si -ttar $dest_opt);
 
459
  } else {
 
460
    $cmd = qq("$SEVEN_ZIP" x -y $dest_opt $file);
 
461
  }
 
462
 
 
463
  system_or_die("Problem extracting $file", $cmd);
 
464
  if (defined($rename_to)) {
 
465
    rename_or_die($expected_name, $rename_to);
 
466
  }
 
467
}
 
468
 
 
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;
 
496
}
 
497
 
 
498
#########
 
499
# BUILD #
 
500
#########
 
501
 
 
502
sub build_pcre {
 
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);
 
516
}
 
517
 
 
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.
 
520
sub build_zlib {
 
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';
 
524
 
 
525
  system_or_die("Failure building zilb", qq("$NMAKE" /nologo -f win32\\Makefile.msc STATICLIB=zlibstat.lib all));
 
526
 
 
527
  delete $ENV{CC_OPTS};
 
528
  delete $ENV{COMMON_CC_OPTS};
 
529
 
 
530
  chdir_or_die($TOPDIR);
 
531
}
 
532
 
 
533
sub build_openssl {
 
534
  chdir_or_die("$SRCLIB\\openssl");
 
535
 
 
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.
 
539
 
 
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.
 
543
 
 
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.
 
547
 
 
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);
 
560
}
 
561
 
 
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 {
 
567
  my $file = shift;
 
568
  my $interactive = shift;
 
569
  my $flags = "";
 
570
 
 
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.
 
577
  unless (-e $sln) {
 
578
    open(SLN, ">$sln") or die "Can't create $sln: $!";
 
579
    close(SLN);
 
580
  }
 
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));
 
584
  if ($interactive) {
 
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";
 
589
    <>;
 
590
  }
 
591
}
 
592
 
 
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);
 
600
}
 
601
 
 
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 {
 
606
  my $file = shift;
 
607
 
 
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/;
 
613
    });
 
614
}
 
615
 
 
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 {
 
621
  my $file = shift;
 
622
  my $xml = shift;
 
623
  my $bak = shift;
 
624
 
 
625
  modify_file_in_place($file, sub {
 
626
      s#(^</Project>$)#<PropertyGroup>$xml</PropertyGroup>\n$1#i;
 
627
    }, $bak);
 
628
}
 
629
 
 
630
# Strip pre-compiled headers compile and linker flags from file they follow
 
631
# the form: /Ycfoo.h or /Yufoo.h.
 
632
sub disable_pch {
 
633
  my $file = shift;
 
634
 
 
635
  modify_file_in_place($file, sub {
 
636
      s#/Y[cu][^ ]+##;
 
637
    });
 
638
}
 
639
 
 
640
# Find the first .exe .dll or .so OutputFile in the project
 
641
# provided by file.  There may be macros or paths in the
 
642
# result.
 
643
sub get_output_file {
 
644
  my $file = shift;
 
645
  my $result;
 
646
  local $_; # Don't mess with the $_ from the find callback
 
647
 
 
648
  open(IN, "<$file") or die "Couldn't open file $file: $!";
 
649
  while (<IN>) {
 
650
    if (m#<OutputFile>(.*?\.(?:exec|dll|so))</OutputFile>#) {
 
651
      $result = $1;
 
652
      last;
 
653
    }
 
654
  }
 
655
  close(IN);
 
656
  return $result;
 
657
}
 
658
 
 
659
# Find the name of the bdb library we've installed in our LIBDIR.
 
660
sub find_bdb_lib {
 
661
  my $result;
 
662
  my $debug = $DEBUG ? 'd' : '';
 
663
  find(sub {
 
664
         if (not defined($result) and /^libdb\d+$debug\.lib$/) {
 
665
           $result = $_;
 
666
         }
 
667
       }, $LIBDIR);
 
668
  return $result;
 
669
}
 
670
 
 
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 {
 
674
  my $file = shift;
 
675
  my $dep = shift;
 
676
  my $bak = shift;
 
677
 
 
678
  modify_file_in_place($file, sub {
 
679
      s/(%\(AdditionalDependencies\))/$dep;$1/;
 
680
    }, $bak);
 
681
}
 
682
 
 
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/;
 
688
    });
 
689
 
 
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;
 
694
    }, '.bdb');
 
695
 
 
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');
 
699
}
 
700
 
 
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);
 
705
 
 
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/;
 
709
    }, '.lexical');
 
710
}
 
711
 
 
712
sub build_httpd {
 
713
  chdir_or_die($HTTPD);
 
714
 
 
715
  my $vs_2013 = $VS_VER eq '2013';
 
716
  my $vs_2012 = $VS_VER eq '2012';
 
717
  my $vs_2010 = $VS_VER eq '2010';
 
718
 
 
719
  httpd_fix_debug();
 
720
 
 
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
 
724
  # versions.
 
725
  system_or_die("Failure converting DSP files",
 
726
                qq("$PERL" srclib\\apr\\build\\cvtdsp.pl -2005));
 
727
 
 
728
  upgrade_solution('Apache.dsw', $vs_2010);
 
729
  httpd_enable_bdb();
 
730
  httpd_fix_makefile('Makefile.win');
 
731
 
 
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.
 
736
  find(sub {
 
737
         if (/\.vcxproj$/) {
 
738
           insert_property_group($_, '<TrackFileAccess>false</TrackFileAccess>')
 
739
         }
 
740
       }, 'modules', 'support');
 
741
 
 
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');
 
746
 
 
747
    # ApacheMonitor build fails due a duplicate manifest, turn off
 
748
    # GenerateManifest
 
749
    insert_property_group('support\win32\ApacheMonitor.vcxproj',
 
750
                          '<GenerateManifest>false</GenerateManifest>',
 
751
                          '.dupman');
 
752
 
 
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
 
762
    find(sub {
 
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");
 
772
  } elsif ($vs_2010) {
 
773
    system_or_die("Failed fixing project guid references",
 
774
      qq("$PYTHON" "$BINDIR\\ProjRef.py" -i Apache.sln"));
 
775
  }
 
776
 
 
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"));
 
793
 
 
794
  chdir_or_die($TOPDIR);
 
795
}
 
796
 
 
797
sub build_bdb {
 
798
  chdir_or_die($BDB);
 
799
 
 
800
   print(cwd(),$/);
 
801
  my $sln = 'build_windows\Berkeley_DB_vs2010.sln';
 
802
  upgrade_solution($sln);
 
803
 
 
804
  my $platform = $DEBUG ? 'Debug|Win32' : 'Release|Win32';
 
805
 
 
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));
 
810
 
 
811
  system_or_die("Failed building DBD",
 
812
                qq("$DEVENV" "$sln" /Build "$platform"));
 
813
 
 
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);
 
816
  find(sub {
 
817
     if (/\.(exe|dll|pdb)$/) {
 
818
       copy_or_die($_, $BINDIR);
 
819
     } elsif (/\.lib$/) {
 
820
       copy_or_die($_, $LIBDIR);
 
821
     }
 
822
   }, 'build_windows\\Win32\\' . ($DEBUG ? 'Debug' : 'Release'));
 
823
 
 
824
  chdir_or_die($TOPDIR);
 
825
}
 
826
 
 
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.
 
829
sub build_serf {
 
830
  chdir_or_die("$TOPDIR\\serf");
 
831
 
 
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;
 
836
    }, '.debug');
 
837
 
 
838
  chdir_or_die($TOPDIR);
 
839
}
 
840
 
 
841
sub build_dependencies {
 
842
  build_bdb();
 
843
  build_zlib();
 
844
  build_pcre();
 
845
  build_openssl();
 
846
  build_serf();
 
847
  build_httpd();
 
848
}
 
849
 
 
850
###############
 
851
# COMMANDLINE #
 
852
###############
 
853
 
 
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
 
857
# argv entry).
 
858
sub main {
 
859
  my @commands;
 
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;
 
869
      } else {
 
870
        # Don't allow variables that don't exist already to be touched.
 
871
        die "$lhs is an unknown variable.";
 
872
      }
 
873
    } else {
 
874
      # Not a variable so must be a command
 
875
      push @commands, $arg;
 
876
    }
 
877
  }
 
878
 
 
879
  # No commands so add the implicit all command
 
880
  if ($#commands == -1) {
 
881
    push @commands, 'all';
 
882
  }
 
883
 
 
884
  # Set defaults and paths that have to be set at runtime since they are based
 
885
  # on other variables.
 
886
  Vars::set_defaults();
 
887
  set_paths();
 
888
 
 
889
  # Determine the Visual Studio Version and die if not supported.
 
890
  check_vs_ver();
 
891
 
 
892
  # change directory to our TOPDIR before running any commands
 
893
  # the variable assignment might have changed it.
 
894
  chdir_or_die($TOPDIR);
 
895
 
 
896
  # Run the commands in the order given.
 
897
  foreach my $command (@commands) {
 
898
    if ($command eq 'clean') {
 
899
      clean_structure(0);
 
900
    } elsif ($command eq 'real-clean') {
 
901
      clean_structure(1);
 
902
    } elsif ($command eq 'prepare') {
 
903
      prepare_structure();
 
904
    } elsif ($command eq 'download') {
 
905
      download_dependencies();
 
906
    } elsif ($command eq 'extract') {
 
907
      extract_dependencies();
 
908
    } elsif ($command eq 'all') {
 
909
      prepare_structure();
 
910
      download_dependencies();
 
911
      extract_dependencies();
 
912
      build_dependencies();
 
913
    } else {
 
914
      die "Command '$command' is unknown";
 
915
    }
 
916
  }
 
917
}
 
918
 
 
919
main();