w32locatedb.pl 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #! perl -w
  2. #
  3. # w32locatedb.pl -- Build apr-util with Berkeley DB on Win32
  4. #
  5. # Usage: perl w32locatedb.pl <type> <incdir> <libdir>
  6. # type: Library type to link with ('lib' or 'dll')
  7. # incdir: BDB includes directory (for db.h)
  8. # libdir: Library directory (for libdbXY[s][d].lib)
  9. #
  10. # This script falls under the Apache License.
  11. # See http://www.apache.org/docs/LICENSE
  12. require 5.008;
  13. use strict;
  14. use File::Spec::Functions qw(canonpath rel2abs
  15. splitpath catpath splitdir catdir);
  16. ########
  17. # Subroutine prototypes
  18. sub usage();
  19. sub find_srcdir();
  20. sub get_lib_name($$);
  21. sub edit_header($$);
  22. sub edit_project($$);
  23. ########
  24. # Parse program arguments and set globals
  25. die usage() unless scalar @ARGV >= 3;
  26. my $type = lc($ARGV[0]);
  27. die "Invalid library type '$type'\n"
  28. unless $type eq 'lib' or $type eq 'dll';
  29. my $incdir = $ARGV[1];
  30. die "No 'db.h' in $incdir\n" unless -f "$incdir/db.h";
  31. my $libdir = $ARGV[2];
  32. die "$libdir: $!" unless -d $libdir;
  33. my $libname = get_lib_name($type, $incdir);
  34. die "No '$libname.lib' in $libdir" unless -f "$libdir/$libname.lib";
  35. die "No '${libname}d.lib' in $libdir" unless -f "$libdir/${libname}d.lib";
  36. my $srcdir = find_srcdir();
  37. my $apu_hw = canonpath("$srcdir/include/apu.hw");
  38. my $apu_want_hw = canonpath("$srcdir/include/apu_want.hw");
  39. my $apu_select_dbm_hw = canonpath("$srcdir/include/private/apu_select_dbm.hw");
  40. my $aprutil_dsp = canonpath("$srcdir/aprutil.dsp");
  41. my $libaprutil_dsp = canonpath("$srcdir/libaprutil.dsp");
  42. die "Can't find $apu_hw" unless -f $apu_hw;
  43. die "Can't find $apu_want_hw" unless -f $apu_want_hw;
  44. die "Can't find $apu_select_dbm_hw" unless -f $apu_select_dbm_hw;
  45. die "Can't find $aprutil_dsp" unless -f $aprutil_dsp;
  46. die "Can't find $libaprutil_dsp" unless -f $libaprutil_dsp;
  47. ########
  48. # Edit the header file templates
  49. my $db_h = rel2abs(canonpath("$incdir/db.h"));
  50. $db_h =~ s/\\/\//g;
  51. edit_header($apu_hw,
  52. [['^\s*\#\s*define\s+APU_HAVE_DB\s+0\s*$',
  53. '#define APU_HAVE_DB 1']]);
  54. edit_header($apu_want_hw,
  55. [['^\s*\#\s*include\s+\<db\.h\>\s*$',
  56. "#include \"$db_h\""]]);
  57. edit_header($apu_select_dbm_hw,
  58. [['^\s*\#\s*define\s+APU_USE_DB\s+0\s*$',
  59. '#define APU_USE_DB 1'],
  60. ['^\s*\#\s*include\s+\<db\.h\>\s*$',
  61. "#include \"$db_h\""]]);
  62. ########
  63. # Edit the .dsp files
  64. my $libpath = rel2abs(canonpath("$libdir/$libname"));
  65. edit_project($aprutil_dsp, $libpath);
  66. edit_project($libaprutil_dsp, $libpath);
  67. ########
  68. # Print usage
  69. sub usage()
  70. {
  71. return ("Usage: perl w32locatedb.pl <type> <incdir> <libdir>\n"
  72. . " type: Library type to link with ('lib' or 'dll')\n"
  73. . " incdir: BDB includes directory (for db.h)\n"
  74. . " libdir: Library directory (for libdbXY[s][d].lib)\n");
  75. }
  76. ########
  77. # Calculate the (possibly relative) path to the top of the apr-util
  78. # source dir.
  79. sub find_srcdir()
  80. {
  81. my $srcdir = rel2abs(canonpath($0));
  82. my ($vol, $dir, $file) = splitpath($srcdir);
  83. my @dirs = splitdir($dir);
  84. die if scalar @dirs < 1;
  85. do { $_ = pop @dirs } while ($_ eq '');
  86. return catpath($vol, catdir(@dirs), '');
  87. }
  88. ########
  89. # Construct the name of the BDB library, based on the type and
  90. # version information in db.h
  91. sub get_lib_name($$)
  92. {
  93. my ($type, $incdir) = @_;
  94. my $major = undef;
  95. my $minor = undef;
  96. my $patch = undef;
  97. open(DBH, "< $incdir/db.h")
  98. or die "Can't open $incdir/db.h: $!";
  99. while (<DBH>) {
  100. chomp;
  101. m/^\s*\#\s*define\s+DB_VERSION_(MAJOR|MINOR|PATCH)\s+(\d+)\s*$/;
  102. next unless defined $1 and defined $2;
  103. if ($1 eq 'MAJOR') { $major = $2; }
  104. elsif ($1 eq 'MINOR') { $minor = $2; }
  105. elsif ($1 eq 'PATCH') { $patch = $2; }
  106. last if defined $major and defined $minor and defined $patch;
  107. }
  108. close(DBH);
  109. die "Can't determine BDB version\n"
  110. unless defined $major and defined $minor and defined $patch;
  111. print "Using BDB version $major.$minor.$patch\n";
  112. my $libname = "libdb$major$minor";
  113. $libname .= 's' if $type eq 'lib';
  114. return $libname;
  115. }
  116. ########
  117. # Replace a file, keeping a backup copy
  118. sub maybe_rename_with_backup($$$)
  119. {
  120. my ($tmpfile, $file, $maybe) = @_;
  121. if ($maybe) {
  122. # Make the file writable by the owner. On Windows, this removes
  123. # any read-only bits.
  124. chmod((stat($file))[2] | 0600, $file);
  125. rename($file, "${file}~");
  126. rename($tmpfile, $file);
  127. } else {
  128. print "No changes in $file\n";
  129. unlink($tmpfile);
  130. }
  131. }
  132. ########
  133. # Edit a header template in-place.
  134. sub edit_header($$)
  135. {
  136. my ($file, $pairs) = @_;
  137. my $tmpfile = "$file.tmp";
  138. my $substs = 0;
  139. open(IN, "< $file") or die "Can't open $file: $!";
  140. open(TMP, "> $tmpfile") or die "Can't open $tmpfile: $!";
  141. while (<IN>) {
  142. chomp;
  143. foreach my $pair (@$pairs) {
  144. $substs += s/${$pair}[0]/${$pair}[1]/;
  145. }
  146. print TMP $_, "\n";
  147. }
  148. close(IN);
  149. close(TMP);
  150. maybe_rename_with_backup($tmpfile, $file, $substs > 0);
  151. }
  152. ########
  153. # Edit a project file in-place
  154. sub edit_project($$)
  155. {
  156. my ($file, $libpath) = @_;
  157. my $tmpfile = "$file.tmp";
  158. my $substs = 0;
  159. my ($prog, $debug) = (undef, undef);
  160. my $libsearch = $libpath;
  161. $libsearch =~ s/\\/\\\\/g;
  162. open(IN, "< $file") or die "Can't open $file: $!";
  163. open(TMP, "> $tmpfile") or die "Can't open $tmpfile: $!";
  164. while (<IN>) {
  165. chomp;
  166. if (m/^\# TARGTYPE \"[^\"]+\" 0x([0-9A-Za-z]+)/
  167. and defined $1) {
  168. $prog = 'LINK32' if $1 eq '0102';
  169. $prog = 'LIB32' if $1 eq '0104';
  170. die "Unknown project type 0x$1" unless defined $prog;
  171. } elsif (defined $prog
  172. and m/^\# PROP Use_Debug_Libraries ([01])/
  173. and defined $1) {
  174. $debug = $1;
  175. } elsif (defined $prog and defined $debug
  176. and m/^\# ADD $prog (\"$libsearch)?/
  177. and not defined $1) {
  178. my $fullpath =
  179. ($debug eq '1' ? "${libpath}d.lib" : "$libpath.lib");
  180. $substs += s/^\# ADD $prog /\# ADD $prog \"$fullpath\" /;
  181. } elsif (m/^\# ADD CPP/) {
  182. $substs += s/APU_USE_SDBM/APU_USE_DB/g;
  183. }
  184. print TMP $_, "\n";
  185. }
  186. close(IN);
  187. close(TMP);
  188. maybe_rename_with_backup($tmpfile, $file, $substs > 0);
  189. }