summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2016-08-30 22:44:36 +0100
committerChris Wilson <chris+github@qwirx.com>2016-08-28 21:47:18 +0100
commit0ebfa6464b9987b5bd2a084872f7511625647391 (patch)
tree8d6abc564823f68d2efe3f3f37383ab15543c4d4
parentbaf19fe9e7dd689597b3320202efeb69c61838a8 (diff)
Merge makebuildenv.pl and makeparcels.pl, write monolithic Makefiles.
This is necessary to fix compilation on machines with large numbers of cores (e.g. Travis build workers) because the build system automatically attempts maximum parallelism, and the old one is broken and tries to build multiple libraries simultaneously. The new buildsystem almost entirely avoids recursive Make: only trivial Makefiles in target directories (which invoke the top-level Makefile to build the appropriate output file) and the old docs makefile are not part of the new master Makefile. Due to higher parallelism and better dependency checking, Make should be much faster now. Not all old targets are supported though. I've removed implicit dependencies hard-coded in the build system, and expressed all dependencies in modules.txt, since the implicit dependencies were confusing, obscure and unnecessary, and it was hard to express their own dependencies on each other. Test both the default target and explicitly "parcels" for release builds on Travis.
-rw-r--r--configure.ac4
-rw-r--r--infrastructure/cmake/CMakeLists.txt14
-rwxr-xr-xinfrastructure/makebuildenv.pl.in1032
-rwxr-xr-xinfrastructure/makeparcels.pl.in417
-rwxr-xr-xinfrastructure/travis-build.sh6
-rw-r--r--modules.txt19
-rw-r--r--parcels.txt2
7 files changed, 717 insertions, 777 deletions
diff --git a/configure.ac b/configure.ac
index 272044f7..f9f481d5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -107,7 +107,6 @@ AX_CONFIG_SCRIPTS([bin/bbackupd/bbackupd-config
contrib/solaris/bbstored-smf-method
contrib/windows/installer/boxbackup.mpi
infrastructure/makebuildenv.pl
- infrastructure/makeparcels.pl
infrastructure/makedistribution.pl
lib/bbackupquery/makedocumentation.pl
lib/common/makeexception.pl
@@ -124,8 +123,7 @@ AC_OUTPUT
# Configure the Box build system
echo
-if ! $PERL ./infrastructure/makebuildenv.pl \
-|| ! $PERL ./infrastructure/makeparcels.pl; then
+if ! $PERL ./infrastructure/makebuildenv.pl; then
echo "Making infrastructure failed!"
exit 1
fi
diff --git a/infrastructure/cmake/CMakeLists.txt b/infrastructure/cmake/CMakeLists.txt
index a9bd549f..1d28b313 100644
--- a/infrastructure/cmake/CMakeLists.txt
+++ b/infrastructure/cmake/CMakeLists.txt
@@ -31,7 +31,6 @@ set(files_to_configure
contrib/windows/installer/boxbackup.mpi
infrastructure/BoxPlatform.pm
infrastructure/makebuildenv.pl
- infrastructure/makeparcels.pl
infrastructure/makedistribution.pl
lib/bbackupquery/makedocumentation.pl
lib/common/BoxPortsAndFiles.h
@@ -148,12 +147,7 @@ foreach(documentation_file ${documentation_files})
endforeach()
file(STRINGS ${base_dir}/modules.txt module_deps REGEX "^[^#]")
-# qdbm, lib/common and lib/win32 aren't listed in modules.txt, so hard-code them.
-foreach(module_dep
- "qdbm"
- "lib/win32"
- "lib/common qdbm lib/win32"
- ${module_deps})
+foreach(module_dep ${module_deps})
string(REGEX MATCH "([^ ]+)[ ]*(.*)" valid_module_line ${module_dep})
if(valid_module_line)
@@ -169,12 +163,6 @@ foreach(module_dep
${module_path}/*.h)
set(module_files ${module_files} ${${module_name}_extra_files})
- # everything except qdbm, lib/common and lib/win32 implicitly depend on
- # lib/common, so express that dependency here.
- if(module_name MATCHES "^(qdbm|lib_(common|win32))$")
- else()
- set(dependencies "${dependencies} lib_common")
- endif()
string(REGEX REPLACE "^ " "" dependencies "${dependencies}")
string(REGEX REPLACE " $" "" dependencies "${dependencies}")
diff --git a/infrastructure/makebuildenv.pl.in b/infrastructure/makebuildenv.pl.in
index 5f1b0618..60c6d854 100755
--- a/infrastructure/makebuildenv.pl.in
+++ b/infrastructure/makebuildenv.pl.in
@@ -14,7 +14,10 @@ $|=1;
print "Box build environment setup.\n";
-my @implicit_deps = ('lib/common');
+# Modules that everything else depends on, without being explicitly specified.
+# Deprecated because we can't specify dependencies between them in the usual way,
+# and it's totally unnecessary anyway:
+my @implicit_deps;
# work out platform variables
use lib 'infrastructure';
@@ -26,10 +29,6 @@ print "Building on '$build_os $build_os_ver' using ".
# keep copy of command line args
my $makebuildenv_args = join(' ',@ARGV);
-# do command line arguments
-my $compile_line_extra = $platform_compile_line_extra;
-my $link_line_extra = $platform_link_line_extra;
-
# make sure local files directory exists
unless(-d 'local')
{
@@ -40,9 +39,6 @@ unless(-d 'local')
# flags about the environment
my %env_flags;
-$module_dependency{"lib/common"} = ["lib/win32"];
-push @implicit_deps, "lib/win32";
-
# print "Flag: $_\n" for(keys %env_flags);
# seed autogen code
@@ -377,17 +373,156 @@ for my $mod (@modules, @implicit_deps)
closedir DIR;
}
-# Then write a makefile for each module
+my $default_cflags = '@CFLAGS@';
+my $default_cxxflags = '@CXXFLAGS@';
+$default_cflags =~ s/ -O2//g;
+$default_cxxflags =~ s/ -O2//g;
+my $debug_base_dir = 'debug';
+my $release_base_dir = 'release';
+
+my $release_flags = "-O2";
+if ($target_windows)
+{
+ $release_flags = "-O0 -g";
+}
+
+# Then write a master Makefile, and a mini-Makefile for each module
print "done\n\nGenerating Makefiles...\n";
-my %module_resources_win32;
+my $makefile_ifdef_prefix = $bsd_make ? "." : "";
+
+open MASTER_MAKEFILE, ">Makefile" or die "Makefile: $!";
+print MASTER_MAKEFILE <<__E;
+#
+# AUTOMATICALLY GENERATED FILE
+# do not edit!
+#
+#
+
+# "parcels" is defined near the end of this Makefile.
+default: parcels
+
+CC = @CC@
+CXX = @CXX@
+AR = @AR@
+RANLIB = @RANLIB@
+PERL = @PERL@
+WINDRES = @WINDRES@
+
+# Work around a mistake in QDBM (using <angled> includes for a file not in the
+# system path) by adding it to the include path with -I.
+DEFAULT_CFLAGS = \@CPPFLAGS@ $default_cflags \@CXXFLAGS_STRICT@ \\
+ $extra_platform_defines $platform_compile_line_extra \\
+ -DBOX_VERSION="\\"$product_version\\"" -Iqdbm
+DEFAULT_CXXFLAGS = \@CPPFLAGS@ $default_cxxflags \@CXXFLAGS_STRICT@ \\
+ $extra_platform_defines $platform_compile_line_extra \\
+ -DBOX_VERSION="\\"$product_version\\""
+LDFLAGS += \@LDFLAGS@ \@LDADD_RDYNAMIC@ $platform_link_line_extra
+
+RELEASE_CFLAGS = \$(DEFAULT_CFLAGS) -DBOX_RELEASE_BUILD $release_flags
+RELEASE_CXXFLAGS = \$(DEFAULT_CXXFLAGS) -DBOX_RELEASE_BUILD $release_flags
+RELEASE_OUTBASE = $release_base_dir
+# http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode_using.html#debug_mode.using.mode
+DEBUG_CFLAGS = \$(DEFAULT_CFLAGS) -g -O0 -D_GLIBCXX_DEBUG
+DEBUG_CXXFLAGS = \$(DEFAULT_CXXFLAGS) -g -O0 -D_GLIBCXX_DEBUG
+DEBUG_OUTBASE = $debug_base_dir
+
+__E
+
+if ($bsd_make)
+{
+ print MASTER_MAKEFILE <<__E;
+.ifdef V
+HIDE =
+_CC = \$(CC)
+_CXX = \$(CXX)
+_LINK = \$(CXX)
+_WINDRES = \$(WINDRES)
+_AR = \$(AR)
+_RANLIB = \$(RANLIB)
+_PERL = \$(PERL)
+.else
+HIDE = @
+_CC = @ echo " [CC] " \$(*F) && \$(CC)
+_CXX = @ echo " [CXX] " \$(*F) && \$(CXX)
+_LINK = @ echo " [LINK] " \$(*F) && \$(CXX)
+_WINDRES = @ echo " [WINDRES]" \$(*F) && \$(WINDRES)
+_AR = @ echo " [AR] " \$(*F) && \$(AR)
+_RANLIB = @ echo " [RANLIB] " \$(*F) && \$(RANLIB)
+_PERL = @ echo " [PERL] " \$(*F) && \$(PERL) >/dev/null
+.endif
+
+__E
+}
+else
+{
+ print MASTER_MAKEFILE <<__E;
+HIDE = \$(if \$(V),,@)
+_CC = \$(if \$(V),\$(CC), @ echo " [CC] \$<" && \$(CC))
+_CXX = \$(if \$(V),\$(CXX), @ echo " [CXX] \$<" && \$(CXX))
+_LINK = \$(if \$(V),\$(CXX), @ echo " [LINK] \$@" && \$(CXX))
+_WINDRES = \$(if \$(V),\$(WINDRES), @ echo " [WINDRES] \$<" && \$(WINDRES))
+_AR = \$(if \$(V),\$(AR), @ echo " [AR] \$@" && \$(AR))
+_RANLIB = \$(if \$(V),\$(RANLIB), @ echo " [RANLIB] \$@" && \$(RANLIB))
+_PERL = \$(if \$(V),\$(PERL), @ echo " [PERL] \$@" && \$(PERL) >/dev/null)
+
+__E
+}
+my %module_resources_win32;
+my @debug_build_targets;
+my @release_build_targets;
+my @all_clean_targets;
+my %mod_type_name;
+my %mod_end_targets;
+my %library_targets;
+
+# First, loop over all modules and quickly categorise them and generate the target filenames.
+# We need this to write correct dependency info into the makefile when modules are listed
+# out of order in modules.txt, which isn't strictly necessary but may look tidier.
for my $mod (@implicit_deps, @modules)
{
print $mod,"\n";
my ($type,$name) = split /\//,$mod;
-
+ if (not $name)
+ {
+ # External modules such as qdbm have no "type" in the directory path.
+ $name = $mod;
+ $type = 'lib';
+ }
+
+ # is target a library?
+ my $target_is_library = ($type ne 'bin' && $type ne 'test');
+
+ # make target name
+ my $end_target_file = $name;
+
+ if ($target_is_library)
+ {
+ $end_target_file .= '.a';
+ }
+ else
+ {
+ $end_target_file .= $platform_exe_ext;
+ }
+
+ $end_target_file = '_test'.$platform_exe_ext if $type eq 'test';
+
+ $mod_type_name{$mod} = [$type, $name];
+ $mod_end_targets{$mod} = $end_target_file;
+ $library_targets{$mod} = $target_is_library;
+}
+
+# Now loop over them again, generating makefile instructions etc.
+for my $mod (@implicit_deps, @modules)
+{
+ my ($type,$name) = @{$mod_type_name{$mod}};
+ my $end_target_file = $mod_end_targets{$mod};
+ my $target_is_library = $library_targets{$mod};
+
+ print $mod,": $type\n";
+
# add additional files for tests
if($type eq 'test')
{
@@ -478,9 +613,9 @@ __E
close TESTFILE;
}
- writetestfile("$mod/_t", "GLIBCXX_FORCE_NEW=1 ".
+ writetestfile("$mod/t", "GLIBCXX_FORCE_NEW=1 ".
'./_test' . $platform_exe_ext . ' "$@"', $mod);
- writetestfile("$mod/_t-gdb", "GLIBCXX_FORCE_NEW=1 ".
+ writetestfile("$mod/t-gdb", "GLIBCXX_FORCE_NEW=1 ".
'gdb ./_test' . $platform_exe_ext . ' "$@"', $mod);
}
@@ -516,124 +651,62 @@ __E
}
}
}
-
- # make include path
- my $include_paths = join(' ',map {'-I../../'.$_} @all_deps_for_module);
-
- # is target a library?
- my $target_is_library = ($type ne 'bin' && $type ne 'test');
-
- # make target name
- my $end_target = $name;
+ # get the list of library things to add -- in order of dependency
+ # so things link properly
+ my @lib_files;
+ my @dep_targets;
+ my @include_search_dirs;
- if ($target_is_library)
- {
- $end_target .= '.a';
- }
- else
+ foreach my $dep (reverse @all_deps_for_module)
{
- $end_target .= $platform_exe_ext;
+ my $dep_target = $mod_end_targets{$dep};
+ die "No output file found for $dep" unless $dep_target;
+ $dep_target = "$dep/$dep_target";
+ push @dep_targets, $dep_target;
+
+ if ($dep =~ m|^lib\/(.+)$|)
+ {
+ push @lib_files, $dep_target;
+ push @include_search_dirs, $dep;
+ }
+ elsif ($dep =~ m|^([^/]+)$|)
+ {
+ push @lib_files, $dep_target;
+ push @include_search_dirs, $dep;
+ }
}
- $end_target = '_test'.$platform_exe_ext if $type eq 'test';
+ # make include path
+ my $cpp_include_paths = join(' ',map {"-I$_"} @include_search_dirs);
+ print MASTER_MAKEFILE "${type}_${name}_includes = $cpp_include_paths\n";
# adjust for outdir
- $end_target = '$(OUTDIR)/' . $end_target;
+ my $debug_end_target = "\$(DEBUG_OUTBASE)/$mod/$end_target_file";
+ my $release_end_target = "\$(RELEASE_OUTBASE)/$mod/$end_target_file";
+ push @debug_build_targets, $debug_end_target;
+ push @release_build_targets, $release_end_target;
# start the makefile
- my $mk_name_extra = ($bsd_make)?'':'X';
- open MAKE,">$mod/Makefile".$mk_name_extra or die "Can't open Makefile for $mod\n";
- my $debug_link_extra = ($target_is_library)?'':'../../debug/lib/debug/debug.a';
-
- my $default_cxxflags = '@CXXFLAGS@';
- $default_cxxflags =~ s/ -O2//g;
-
- my $release_flags = "-O2";
- if ($target_windows)
- {
- $release_flags = "-O0 -g";
- }
-
- print MAKE <<__E;
+ open MINI_MODULE_MAKEFILE,">$mod/Makefile" or die "Can't open Makefile for $mod\n";
+ print MINI_MODULE_MAKEFILE <<__E;
#
# AUTOMATICALLY GENERATED FILE
# do not edit!
#
-#
-CXX = @CXX@
-AR = @AR@
-RANLIB = @RANLIB@
-PERL = @PERL@
-WINDRES = @WINDRES@
-
-DEFAULT_CXXFLAGS = @CPPFLAGS@ $default_cxxflags @CXXFLAGS_STRICT@ \\
- $include_paths $extra_platform_defines \\
- -DBOX_VERSION="\\"$product_version\\""
-LDFLAGS += @LDFLAGS@ @LDADD_RDYNAMIC@
-
-.ifdef RELEASE
-CXXFLAGS += \$(DEFAULT_CXXFLAGS) -DBOX_RELEASE_BUILD $release_flags
-OUTBASE = ../../release
-OUTDIR = ../../release/$mod
-DEPENDMAKEFLAGS = -D RELEASE
-VARIENT = RELEASE
-.else
-# http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode_using.html#debug_mode.using.mode
-CXXFLAGS += \$(DEFAULT_CXXFLAGS) -g -O0 -D_GLIBCXX_DEBUG
-OUTBASE = ../../debug
-OUTDIR = ../../debug/$mod
-DEPENDMAKEFLAGS =
-VARIENT = DEBUG
-.endif
-
-__E
-
- if ($bsd_make)
- {
- print MAKE <<__E;
-.ifdef V
-HIDE =
-_CXX = \$(CXX)
-_LINK = \$(CXX)
-_WINDRES = \$(WINDRES)
-_AR = \$(AR)
-_RANLIB = \$(RANLIB)
-_PERL = \$(PERL)
-.else
-HIDE = @
-_CXX = @ echo " [CXX] " \$(*F) && \$(CXX)
-_LINK = @ echo " [LINK] " \$(*F) && \$(CXX)
-_WINDRES = @ echo " [WINDRES]" \$(*F) && \$(WINDRES)
-_AR = @ echo " [AR] " \$(*F) && \$(AR)
-_RANLIB = @ echo " [RANLIB] " \$(*F) && \$(RANLIB)
-_PERL = @ echo " [PERL] " \$(*F) && \$(PERL) >/dev/null
-.endif
-
-__E
- }
- else
- {
- print MAKE <<__E;
-HIDE = \$(if \$(V),,@)
-_CXX = \$(if \$(V),\$(CXX), @ echo " [CXX] $mod/\$<" && \$(CXX))
-_LINK = \$(if \$(V),\$(CXX), @ echo " [LINK] $mod/\$@" && \$(CXX))
-_WINDRES = \$(if \$(V),\$(WINDRES), @ echo " [WINDRES] $mod/\$<" && \$(WINDRES))
-_AR = \$(if \$(V),\$(AR), @ echo " [AR] $mod/\$@" && \$(AR))
-_RANLIB = \$(if \$(V),\$(RANLIB), @ echo " [RANLIB] $mod/\$@" && \$(RANLIB))
-_PERL = \$(if \$(V),\$(PERL), @ echo " [PERL] $mod/\$@" && \$(PERL) >/dev/null)
-
+${makefile_ifdef_prefix}ifdef RELEASE
+TARGET = $release_base_dir/$mod/$end_target_file
+${makefile_ifdef_prefix}else
+TARGET = $debug_base_dir/$mod/$end_target_file
+${makefile_ifdef_prefix}endif
+
+.PHONY: default
+default:
+ \$(MAKE) -C ../.. \$(TARGET)
__E
- }
+ close MINI_MODULE_MAKEFILE;
- # if there is a Makefile.pre, include it now
- if(-e "$mod/Makefile.pre")
- {
- print MAKE ".include <Makefile.pre>\n\n";
- }
-
- # read directory
- opendir DIR,$mod;
+ opendir DIR, $mod;
my @items = readdir DIR;
closedir DIR;
@@ -646,10 +719,10 @@ __E
{
# Read items
my $d = "$mod/$di";
- opendir DIR,$d;
+ opendir DIR, $d;
my @i = readdir DIR;
closedir DIR;
- for(@i)
+ for (@i)
{
next if m/\A\./;
push @autogen_items,"$di/$_"
@@ -678,294 +751,583 @@ __E
}
}
- # ready for the rest of the details...
- my $make;
-
- # then... do the cpp files...
- my @obj_base;
- for my $file (@items)
+ # write the recipes for debug and release builds of each file
+ foreach my $var_prefix ('DEBUG', 'RELEASE')
{
- my $is_cpp = $file =~ m/\A(.+)\.cpp\Z/i;
- my $is_rc = $file =~ m/\A(.+)\.rc\Z/i;
- my $base = $1;
+ my $make;
- if ($target_windows)
- {
- next if not $is_cpp and not $is_rc;
- }
- else
+ # then... do the cpp files...
+ my @obj_base;
+ for my $file (@items)
{
- next if not $is_cpp;
- }
+ my $is_c = $file =~ m/\A(.+)\.c\Z/i;
+ my $is_cpp = $file =~ m/\A(.+)\.cpp\Z/i;
+ my $is_rc = $file =~ m/\A(.+)\.rc\Z/i;
+ my $base = $1;
- next if $file =~ /\A\._/; # Temp Mac OS Resource hack
+ # Don't try to compile .rc files except on Windows:
+ next if not $is_c and not $is_cpp and not ($is_rc and $target_windows);
+ next if $file =~ /\A\._/; # Temp Mac OS Resource hack
- # store for later
- push @obj_base,$base;
-
- # get the file...
- open FL,"$mod/$file";
- my $f;
- read FL,$f,-s "$mod/$file";
- close FL;
+ # store for later
+ push @obj_base, $base;
- my %dep;
+ # get the file...
+ open FL, "$mod/$file";
+ my $f;
+ read FL, $f, -s "$mod/$file";
+ close FL;
+
+ my %dep;
- while($f =~ m/\#include\s+"([^"]+?)"/g)
- {
- insert_dep($1, \%dep) if exists $hfiles{$1};
+ while($f =~ m/\#include\s+"([^"]+?)"/g)
+ {
+ insert_dep($1, \%dep) if exists $hfiles{$1};
+ }
+
+ # output filename
+ my $out_name = "\$(${var_prefix}_OUTBASE)/$mod/$base.o";
+
+ # write the line for this cpp file
+ my @dep_paths = map
+ {
+ ($hfiles{$_} eq $mod)
+ ? "$mod/$_"
+ : $hfiles{$_}."/$_"
+ }
+ keys %dep;
+
+ $make .= "$out_name: $mod/$file @dep_paths\n";
+
+ if ($is_c)
+ {
+ $make .= "\t\$(_CC) \$(${var_prefix}_CFLAGS) ".
+ "\$(${type}_${name}_includes) -DBOX_MODULE=\"\\\"$mod\\\"\" " .
+ "-c $mod/$file -o $out_name\n\n";
+ }
+ if ($is_cpp)
+ {
+ $make .= "\t\$(_CXX) \$(${var_prefix}_CXXFLAGS) ".
+ "\$(${type}_${name}_includes) -DBOX_MODULE=\"\\\"$mod\\\"\" " .
+ "-c $mod/$file -o $out_name\n\n";
+ }
+ elsif ($is_rc)
+ {
+ $make .= "\t\$(_WINDRES) $file $out_name\n\n";
+ my $res_list = $module_resources_win32{$mod};
+ $res_list ||= [];
+ push @$res_list, $base.'.o';
+ $module_resources_win32{$mod} = $res_list;
+ }
}
+
+ # need to see if the extra makefile fragments require extra object files
+ # or include any more makefiles
+ my @objs = @obj_base;
+ my @makefile_includes;
- # output filename
- my $out_name = '$(OUTDIR)/'.$base.'.o';
+ additional_objects_from_make_fragment("$mod/Makefile.extra", \@objs, \@makefile_includes);
+ additional_objects_from_make_fragment("$mod/Makefile.extra.$build_os", \@objs, \@makefile_includes);
+
+ my $prefixed_end_target = "\$(${var_prefix}_OUTBASE)/$mod/$end_target_file";
+ my $o_file_list = join(' ',map {"\$(${var_prefix}_OUTBASE)/$mod/$_.o"} sort @objs);
+ my @prefixed_lib_files = map {"\$(${var_prefix}_OUTBASE)/$_"} @lib_files;
+ my @prefixed_dep_targets = map {"\$(${var_prefix}_OUTBASE)/$_"} @dep_targets;
+
+ print MASTER_MAKEFILE "$prefixed_end_target: $o_file_list";
+ print MASTER_MAKEFILE " @prefixed_dep_targets" unless $target_is_library;
+ print MASTER_MAKEFILE "\n";
- # write the line for this cpp file
- my @dep_paths = map
- {
- ($hfiles{$_} eq $mod)
- ? $_
- : '../../'.$hfiles{$_}."/$_"
+ if ($target_windows)
+ {
+ foreach my $dep (@all_deps_for_module)
+ {
+ my $res_list = $module_resources_win32{$dep};
+ next unless $res_list;
+ $o_file_list .= ' '.join(' ',
+ map {"\$(${var_prefix}_OUTBASE)/$dep/$_"} @$res_list);
+ }
}
- keys %dep;
- $make .= $out_name.': '.join(' ',$file,@dep_paths)."\n";
-
- if ($is_cpp)
+ # stuff to make the final target...
+ if($target_is_library)
{
- $make .= "\t\$(_CXX) \$(CXXFLAGS) $compile_line_extra ".
- "-DBOX_MODULE=\"\\\"$mod\\\"\" " .
- "-c $file -o $out_name\n\n";
+ # make a library archive...
+ print MASTER_MAKEFILE "\t\$(HIDE) (rm -f $prefixed_end_target)\n";
+ print MASTER_MAKEFILE "\t\$(_AR) cq $prefixed_end_target $o_file_list\n";
+ print MASTER_MAKEFILE "\t\$(_RANLIB) $prefixed_end_target\n";
}
- elsif ($is_rc)
+ else
{
- $make .= "\t\$(_WINDRES) $file $out_name\n\n";
- my $res_list = $module_resources_win32{$mod};
- $res_list ||= [];
- push @$res_list, $base.'.o';
- $module_resources_win32{$mod} = $res_list;
+ # work out library options
+ # need to be... least used first, in absolute order they appear in the modules.txt file
+ my @libops;
+
+ sub libops_fill
+ {
+ my ($module, $libops_ref) = @_;
+
+ my $library_link_opts = $module_library_link_opts{$module};
+ if ($library_link_opts)
+ {
+ push @$libops_ref, @$library_link_opts;
+ }
+
+ my $deps = $module_dependency{$module};
+ foreach my $dep (@$deps)
+ {
+ libops_fill($dep, $libops_ref);
+ }
+ }
+
+ libops_fill($mod,\@libops);
+
+ my $lo = '';
+ my %ldone;
+ for(@libops)
+ {
+ next if exists $ldone{$_};
+ $lo .= ' '.$_;
+ $ldone{$_} = 1;
+ }
+
+ # link line...
+ print MASTER_MAKEFILE "\t\$(_LINK) \$(LDFLAGS) " .
+ "-o $prefixed_end_target $o_file_list " .
+ "@prefixed_lib_files $lo $platform_lib_files\n";
}
- }
-
- my $has_deps = ($#{$module_dependency{$mod}} >= 0);
-# ----- # always has dependencies with debug library
- $has_deps = 1;
- $has_deps = 0 if $target_is_library;
- # Dependency stuff
- my $deps_makeinfo;
- if($has_deps)
- {
- if($bsd_make)
+ # tests need to copy the test file over
+ if($type eq 'test')
{
- $deps_makeinfo = <<'__E';
-.BEGIN::
-.ifndef NODEPS
-. if $(.TARGETS) == ""
+ print MASTER_MAKEFILE <<__E;
+ \$(HIDE) cp $mod/t \$(${var_prefix}_OUTBASE)/$mod/t
+ \$(HIDE) chmod u+x \$(${var_prefix}_OUTBASE)/$mod/t
+ \$(HIDE) cp $mod/t-gdb \$(${var_prefix}_OUTBASE)/$mod/t-gdb
+ \$(HIDE) chmod u+x \$(${var_prefix}_OUTBASE)/$mod/t-gdb
__E
}
- else
+
+ print MASTER_MAKEFILE $make,"\n";
+
+ for(@makefile_includes)
{
- # gnu make
- $deps_makeinfo = <<'__E';
-.PHONY: dep_modules
-dep_modules:
-ifndef NODEPS
-ifeq ($(strip $(.TARGETS)),)
-__E
+ print MASTER_MAKEFILE "\n.include <$_>\n";
}
+}
+
+ print MASTER_MAKEFILE <<__E;
+clean_${type}_${name}:
+ rm -rf \$(DEBUG_OUTBASE)/$mod/*
+ rm -rf \$(RELEASE_OUTBASE)/$mod/*
+__E
+ push @all_clean_targets, "clean_${type}_${name}";
+
+ my $includes = "";
+
+ if(-e "$mod/Makefile.extra")
+ {
+ $includes .= ".include <$mod/Makefile.extra>\n\n";
+ }
+ if(-e "$mod/Makefile.extra.$build_os")
+ {
+ $includes .= ".include <$mod/Makefile.extra.$build_os>\n\n";
+ }
+
+ if(!$bsd_make)
+ {
+ # need to post process this into a GNU makefile
+ $includes =~ s/\A\.\s*(ifdef|else|endif|ifndef)/$1/;
+ $includes =~ s/\A\.\s*include\s+<(.+?)>/include $1/;
+ $includes =~ s/-D\s+(\w+)/$1=1/g;
+ }
+
+ print MASTER_MAKEFILE $includes;
+}
+
+my @parcels;
+my %parcel_contents;
+
+sub starts_with ($$)
+{
+ my ($string,$expected) = @_;
+ return substr($string, 0, length $expected) eq $expected;
+}
+
+sub os_matches ($)
+{
+ my ($prefix_string) = @_;
+ my @prefixes = split m'\,', $prefix_string;
+ foreach my $prefix (@prefixes)
+ {
+ return 1 if starts_with($build_os, $prefix);
+ return 1 if starts_with($ac_target_os, $prefix);
+ return 1 if starts_with("$ac_target_cpu-$ac_target_os",
+ $prefix);
+ return 1 if starts_with($ac_target, $prefix);
+ }
+ return 0;
+}
+
+my $copy_command = "cp -p";
+
+open PARCELS,"parcels.txt" or die "Can't open parcels file";
+{
+ my $cur_parcel = '';
+ while(<PARCELS>)
+ {
+ chomp; s/#.+\Z//; s/\s+\Z//; s/\s+/ /g;
+ next unless m/\S/;
- # run make for things we require
- for my $dep (@all_deps_for_module)
+ # omit bits on some platforms?
+ next if m/\AEND-OMIT/;
+ if(m/\AOMIT:(.+)/)
{
- my $dep_target = "";
- if ($dep =~ m|^lib/(.*)|)
+ if (os_matches($1))
{
- $dep_target = "\$(OUTBASE)/$dep/$1.a";
+ while(<PARCELS>)
+ {
+ last if m/\AEND-OMIT/;
+ }
}
- elsif ($dep =~ m|^.*/(.*)|)
+ next;
+ }
+
+ if (m'\AONLY:(.+)')
+ {
+ if (not os_matches($1))
{
- $dep_target = "\$(OUTBASE)/$dep/$1$platform_exe_ext";
+ while (<PARCELS>)
+ {
+ last if m'\AEND-ONLY';
+ }
}
- else
+ next;
+ }
+ next if (m'\AEND-ONLY');
+
+ if (m'\AEXCEPT:(.+)')
+ {
+ if (os_matches($1))
{
- $dep_target = "lib$dep.a";
+ while (<PARCELS>)
+ {
+ last if m'\AEND-EXCEPT';
+ }
}
-
- $deps_makeinfo .= <<EOF;
- \$(HIDE) ( \\
- cd ../../$dep; \\
- \$(MAKE) $sub_make_options -q \$(DEPENDMAKEFLAGS) -D NODEPS $dep_target \\
- || \$(MAKE) $sub_make_options \$(DEPENDMAKEFLAGS) -D NODEPS $dep_target \\
- )
-EOF
+ next;
}
-
- $deps_makeinfo .= ".\tendif\n.endif\n\n";
- }
- print MAKE $deps_makeinfo if $bsd_make;
-
- # get the list of library things to add -- in order of dependency
- # so things link properly
- my @lib_files;
- foreach my $dep (reverse @all_deps_for_module)
- {
- if ($dep =~ m|^lib\/(.+)$|)
+ next if (m'\AEND-EXCEPT');
+
+ # new parcel, or a new parcel definition?
+ if(m/\A\s+(.+)\Z/)
{
- push @lib_files, "\$(OUTBASE)/$dep/$1.a";
+ push @{$parcel_contents{$cur_parcel}},$1
}
- elsif ($dep =~ m|^([^/]+)$|)
+ else
{
- push @lib_files, "../../$dep/lib$1.a";
+ $cur_parcel = $_;
+ push @parcels,$_;
}
}
+}
+close PARCELS;
- # need to see if the extra makefile fragments require extra object files
- # or include any more makefiles
- my @objs = @obj_base;
- my @makefile_includes;
-
- additional_objects_from_make_fragment("$mod/Makefile.extra", \@objs, \@makefile_includes);
- additional_objects_from_make_fragment("$mod/Makefile.extra.$build_os", \@objs, \@makefile_includes);
+# create parcels directory
+mkdir "parcels",0755;
+mkdir "parcels/scripts",0755;
+
+print MASTER_MAKEFILE "parcels:\t",join(' ',map {"build-".$_} @parcels),"\n\n";
+
+my $runtest_script = $target_windows ? './infrastructure/mingw/runtest.sh'
+ : './runtest.pl';
+
+print MASTER_MAKEFILE <<__END_OF_FRAGMENT;
+.PHONY: test
+test: debug_tests release_tests
+
+.PHONY: debug_tests
+debug_tests:
+ $runtest_script ALL debug
+
+.PHONY: release_tests
+release_tests:
+ $runtest_script ALL release
+
+.PHONY: docs
+docs:
+ cd docs; \$(MAKE)
- my $o_file_list = join(' ',map {'$(OUTDIR)/'.$_.'.o'} sort @objs);
+__END_OF_FRAGMENT
- if ($has_deps and not $bsd_make)
+my $release_flag = BoxPlatform::make_flag('RELEASE');
+my @parcel_targets;
+
+for my $parcel (@parcels)
+{
+ my $version = BoxPlatform::parcel_root($parcel);
+ my $make_target = BoxPlatform::parcel_target($parcel);
+ my $dir = BoxPlatform::parcel_dir($parcel);
+ my @parcel_deps;
+
+ # Need to use BSD install on Solaris
+ my $install_bin = $build_os eq 'SunOS' ? '/usr/ucb/install' : 'install';
+
+ unless ($target_windows)
{
- print MAKE ".PHONY: all\n" .
- "all: dep_modules $end_target\n\n";
+ open SCRIPT,">parcels/scripts/install-$parcel" or die
+ "Can't open installer script for $parcel for writing";
+ print SCRIPT "#!/bin/sh\n\n";
}
- print MAKE $end_target,': ',$o_file_list;
- print MAKE " @lib_files" unless $target_is_library;
- print MAKE "\n";
-
- if ($target_windows)
+ for(@{$parcel_contents{$parcel}})
{
- foreach my $dep (@all_deps_for_module)
+ my @args = split /\s+/;
+
+ my ($type,$name,$dest) = @args;
+ my $optional = 0;
+ my $install = 1;
+
+ if ($type eq 'optional')
{
- my $res_list = $module_resources_win32{$dep};
- next unless $res_list;
- $o_file_list .= ' '.join(' ',
- map {'$(OUTBASE)/'.$dep."/$_"} @$res_list);
+ $optional = 1;
+ shift @args;
+ ($type,$name,$dest) = @args;
}
- }
- # stuff to make the final target...
- if($target_is_library)
- {
- # make a library archive...
- print MAKE "\t\$(HIDE) (echo -n > $end_target; rm $end_target)\n";
- print MAKE "\t\$(_AR) cq $end_target $o_file_list\n";
- print MAKE "\t\$(_RANLIB) $end_target\n";
- }
- else
- {
- # work out library options
- # need to be... least used first, in absolute order they appear in the modules.txt file
- my @libops;
-
- sub libops_fill
+ if ($type eq 'noinstall')
{
- my ($module, $libops_ref) = @_;
-
- my $library_link_opts = $module_library_link_opts{$module};
- if ($library_link_opts)
+ $install = 0;
+ shift @args;
+ ($type,$name,$dest) = @args;
+ }
+
+ if($type eq 'bin')
+ {
+ my $exeext = $platform_exe_ext;
+ print MASTER_MAKEFILE <<EOF;
+$dir/$name$exeext: release/bin/$name/$name$exeext
+ mkdir -p $dir
+ $copy_command release/bin/$name/$name$exeext $dir
+
+EOF
+ push @parcel_deps, "$dir/$name$exeext";
+ }
+ elsif ($type eq 'script')
+ {
+ # Replace any variables ($ac_target etc.) with their
+ # values.
+ $name =~ s|(\$[^/ ]+)|$1|eeg;
+ my $fullpath = $name;
+ my $filename = $name;
+ # remove path from script name
+ $filename =~ s{.*/}{};
+
+ print MASTER_MAKEFILE <<EOF;
+$dir/$filename: $fullpath
+ mkdir -p $dir
+EOF
+
+ if ($optional)
{
- push @$libops_ref, @$library_link_opts;
+ print MASTER_MAKEFILE "\ttest -r $fullpath " .
+ "&& $copy_command $fullpath $dir || true\n";
}
-
- my $deps = $module_dependency{$module};
- foreach my $dep (@$deps)
+ else
{
- libops_fill($dep, $libops_ref);
+ print MASTER_MAKEFILE "\t$copy_command $fullpath $dir\n";
}
+
+ print MASTER_MAKEFILE "\n";
+
+ push @parcel_deps, "$dir/$filename";
}
-
- libops_fill($mod,\@libops);
-
- my $lo = '';
- my %ldone;
- for(@libops)
+ elsif($type eq 'man')
{
- next if exists $ldone{$_};
- $lo .= ' '.$_;
- $ldone{$_} = 1;
+ print MASTER_MAKEFILE <<EOF;
+$dir/${name}.gz: docs/man/${name}.gz
+ mkdir -p $dir
+ $copy_command docs/man/${name}.gz $dir
+
+EOF
+ # Releases have the docs pre-made, but users
+ # may want to rebuild them for some reason.
+ my $docbook_source = "docs/docbook/${name}";
+ $docbook_source =~ s/\.[58]$/.xml/;
+ print MASTER_MAKEFILE <<EOF;
+docs/man/${name}.gz: $docbook_source docs/docbook/bb-man.xsl
+ cd docs; \$(MAKE) man/${name}.gz
+
+EOF
+ push @parcel_deps, "$dir/${name}.gz";
}
-
- # link line...
- print MAKE "\t\$(_LINK) \$(LDFLAGS) $link_line_extra " .
- "-o $end_target $o_file_list " .
- "@lib_files $lo $platform_lib_files\n";
- }
+ elsif($type eq 'html')
+ {
+ print MASTER_MAKEFILE <<EOF;
+$dir/docs/${name}.html: docs/htmlguide/man-html/${name}.html
+ mkdir -p $dir/docs
+ $copy_command docs/htmlguide/man-html/${name}.html $dir/docs
- # tests need to copy the test file over
- if($type eq 'test')
- {
- print MAKE "\tcp _t \$(OUTDIR)/t\n\tchmod u+x \$(OUTDIR)/t\n";
- print MAKE "\tcp _t-gdb \$(OUTDIR)/t-gdb\n\tchmod u+x \$(OUTDIR)/t-gdb\n";
+EOF
+ # Releases have the docs pre-made, but users
+ # may want to rebuild them for some reason.
+ my $docbook_source = "docs/docbook/${name}.xml";
+ print MASTER_MAKEFILE <<EOF;
+docs/htmlguide/man-html/${name}.html: $docbook_source docs/docbook/bb-nochunk-book.xsl
+ cd docs; \$(MAKE) htmlguide/man-html/${name}.html
+
+EOF
+ push @parcel_deps, "$dir/docs/${name}.html";
+ }
+ elsif ($type eq 'subdir')
+ {
+ push @parcel_deps, "build_${type}_${name}";
+ }
}
- # dependency line?
- print MAKE "\n";
+ print MASTER_MAKEFILE <<EOF;
+build-$parcel: $make_target
- # module dependencies for GNU make?
- print MAKE $deps_makeinfo if !$bsd_make;
-
- # print the rest of the file
- print MAKE $make,"\n";
-
- # and a clean target
- print MAKE <<EOF;
-clean:
- -rm -rf \$(OUTDIR)/*
-. ifndef SUBCLEAN
+$make_target: @parcel_deps
+ test -d $dir || mkdir $dir
EOF
- for my $dep (@all_deps_for_module)
- {
- print MAKE "\t\$(HIDE) (cd ../../$dep; \$(MAKE) \$(DEPENDMAKEFLAGS) -D SUBCLEAN clean)\n";
- }
- print MAKE ".\tendif\n";
+
+ push @parcel_targets, "build-$parcel";
- # include any extra stuff
- print MAKE "\n\n";
- if(-e "$mod/Makefile.extra")
- {
- print MAKE ".include <Makefile.extra>\n\n";
- }
- if(-e "$mod/Makefile.extra.$build_os")
+ for(@{$parcel_contents{$parcel}})
{
- print MAKE ".include <Makefile.extra.$build_os>\n\n";
+ my @args = split /\s+/;
+
+ my ($type,$name,$dest) = @args;
+
+ my $optional = 0;
+ my $install = 1;
+
+ if ($type eq 'optional')
+ {
+ $optional = 1;
+ shift @args;
+ ($type,$name,$dest) = @args;
+ }
+
+ if ($type eq 'noinstall')
+ {
+ $install = 0;
+ shift @args;
+ ($type,$name,$dest) = @args;
+ }
+
+ if ($type eq 'script')
+ {
+ # remove path from script name
+ $name =~ s{.*/}{};
+ }
+
+ if ($type eq 'html')
+ {
+ $dest = "share/doc/@PACKAGE_TARNAME@";
+ $name = "docs/$name.html";
+ }
+
+ if ($type eq 'man')
+ {
+ $name =~ /([0-9])$/;
+ $dest = "man/man$1";
+ $name =~ s/$/\.gz/;
+ }
+
+ if ($install and not $target_windows and not $type eq "subdir")
+ {
+ my $local_install_dir = $install_into_dir;
+ if (defined $dest)
+ {
+ if ($dest =~ m,^/,)
+ {
+ # Don't add $prefix if $dest is a literal path
+ $local_install_dir = $dest;
+ }
+ else
+ {
+ $local_install_dir = "@prefix@/$dest";
+ }
+ }
+ print SCRIPT "mkdir -p " .
+ "\${DESTDIR}$local_install_dir/\n";
+ print SCRIPT "$install_bin $name " .
+ "\${DESTDIR}$local_install_dir\n";
+ }
}
- for(@makefile_includes)
- {
- print MAKE ".include <$_>\n\n";
+
+ unless ($target_windows)
+ {
+ close SCRIPT;
+ chmod 0755,"parcels/scripts/install-$parcel";
}
- # and finally a target for rebuilding the build system
- print MAKE "\nbuildsystem:\n\t(cd ../..; perl ./infrastructure/makebuildenv.pl $makebuildenv_args)\n\n";
-
- close MAKE;
+ my $root = BoxPlatform::parcel_root($parcel);
- if(!$bsd_make)
+ unless ($target_windows)
{
- # need to post process this into a GNU makefile
- open MAKE,">$mod/Makefile";
- open MAKEB,"$mod/MakefileX";
+ print MAKE "\tcp parcels/scripts/install-$parcel $dir\n";
+ }
- while(<MAKEB>)
- {
- s/\A\.\s*(ifdef|else|endif|ifndef)/$1/;
- s/\A\.\s*include\s+<(.+?)>/include $1/;
- s/-D\s+(\w+)/$1=1/g;
- print MAKE;
- }
+ print MASTER_MAKEFILE "\t(cd parcels; tar cf - $root | gzip -9 - > $root.tgz )\n";
+
+ print MASTER_MAKEFILE "\n";
- close MAKEB;
- close MAKE;
- unlink "$mod/MakefileX";
+ unless ($target_windows)
+ {
+ print MASTER_MAKEFILE "install-$parcel:\n";
+ print MASTER_MAKEFILE "\t(cd $dir; ./install-$parcel)\n\n";
}
}
+print MASTER_MAKEFILE <<EOF;
+
+debug_build: @debug_build_targets
+release_build: @release_build_targets
+parcels: @parcel_targets
+
+# well-known targets that users might expect to be able to build:
+install:
+ cat local/install.msg
+
+clean: @all_clean_targets
+ cd docs; \$(MAKE) clean
+
+realclean: clean
+ find . -name 'autogen_*' -type f -exec rm -f {} \\;
+ find release debug -type f -exec rm -f {} \\;
+
+# and finally a target for rebuilding the build system:
+buildsystem:
+ perl ./infrastructure/makebuildenv.pl $makebuildenv_args
+EOF
+
+for my $parcel (@parcels)
+{
+ # need to use -f to avoid error if they don't exist (already cleaned)
+ print MASTER_MAKEFILE "\trm -rf ", BoxPlatform::parcel_dir($parcel), "\n";
+ print MASTER_MAKEFILE "\trm -f ", BoxPlatform::parcel_target($parcel), "\n";
+}
+
+open INSTALLMSG,">local/install.msg" or die "Can't open install message file for writing";
+print INSTALLMSG <<__E;
+
+Parcels need to be installed separately, and as root. Type one of the following:
+
+__E
+
+for(@parcels)
+{
+ print INSTALLMSG " $make_command install-".$_."\n";
+}
+print INSTALLMSG "\n";
+
+close INSTALLMSG;
+
+close MASTER_MAKEFILE;
+
print "\nType 'cd <module_dir>; $make_command' to build a module\n\n";
if($modules_omitted)
diff --git a/infrastructure/makeparcels.pl.in b/infrastructure/makeparcels.pl.in
deleted file mode 100755
index 56c4ca66..00000000
--- a/infrastructure/makeparcels.pl.in
+++ /dev/null
@@ -1,417 +0,0 @@
-#!@PERL@
-
-use strict;
-use lib 'infrastructure';
-use BoxPlatform;
-
-my @parcels;
-my %parcel_contents;
-
-sub starts_with ($$)
-{
- my ($string,$expected) = @_;
- return substr($string, 0, length $expected) eq $expected;
-}
-
-sub os_matches ($)
-{
- my ($prefix_string) = @_;
- my @prefixes = split m'\,', $prefix_string;
- foreach my $prefix (@prefixes)
- {
- return 1 if starts_with($build_os, $prefix);
- return 1 if starts_with($ac_target_os, $prefix);
- return 1 if starts_with("$ac_target_cpu-$ac_target_os",
- $prefix);
- return 1 if starts_with($ac_target, $prefix);
- }
- return 0;
-}
-
-my $copy_command = "cp -p";
-
-if ($build_os eq 'CYGWIN')
-{
- $copy_command = "cp -pu"; # faster
-}
-
-open PARCELS,"parcels.txt" or die "Can't open parcels file";
-{
- my $cur_parcel = '';
- while(<PARCELS>)
- {
- chomp; s/#.+\Z//; s/\s+\Z//; s/\s+/ /g;
- next unless m/\S/;
-
- # omit bits on some platforms?
- next if m/\AEND-OMIT/;
- if(m/\AOMIT:(.+)/)
- {
- if (os_matches($1))
- {
- while(<PARCELS>)
- {
- last if m/\AEND-OMIT/;
- }
- }
- next;
- }
-
- if (m'\AONLY:(.+)')
- {
- if (not os_matches($1))
- {
- while (<PARCELS>)
- {
- last if m'\AEND-ONLY';
- }
- }
- next;
- }
- next if (m'\AEND-ONLY');
-
- if (m'\AEXCEPT:(.+)')
- {
- if (os_matches($1))
- {
- while (<PARCELS>)
- {
- last if m'\AEND-EXCEPT';
- }
- }
- next;
- }
- next if (m'\AEND-EXCEPT');
-
- # new parcel, or a new parcel definition?
- if(m/\A\s+(.+)\Z/)
- {
- push @{$parcel_contents{$cur_parcel}},$1
- }
- else
- {
- $cur_parcel = $_;
- push @parcels,$_;
- }
- }
-}
-close PARCELS;
-
-# create parcels directory
-mkdir "parcels",0755;
-mkdir "parcels/scripts",0755;
-
-# write master makefile
-
-open MAKE,">Makefile" or die "Can't open master Makefile for writing";
-
-print MAKE <<__E;
-#
-# AUTOMATICALLY GENERATED FILE
-# do not edit!
-#
-#
-
-MAKE = $make_command
-
-__E
-
-print MAKE "all:\t",join(' ',map {"build-".$_} @parcels),"\n\n";
-
-my $runtest_script = $target_windows ? './infrastructure/mingw/runtest.sh'
- : './runtest.pl';
-
-print MAKE <<__END_OF_FRAGMENT;
-test: debug/common/test release/common/test
-
-debug/common/test:
- $runtest_script ALL debug
-
-release/common/test:
- $runtest_script ALL release
-
-.PHONY: docs
-docs:
- cd docs; \$(MAKE)
-
-__END_OF_FRAGMENT
-
-my $release_flag = BoxPlatform::make_flag('RELEASE');
-my @clean_deps;
-
-for my $parcel (@parcels)
-{
- my $version = BoxPlatform::parcel_root($parcel);
- my $make_target = BoxPlatform::parcel_target($parcel);
- my $dir = BoxPlatform::parcel_dir($parcel);
- my @parcel_deps;
-
- # Need to use BSD install on Solaris
- my $install_bin = $build_os eq 'SunOS' ? '/usr/ucb/install' : 'install';
-
- unless ($target_windows)
- {
- open SCRIPT,">parcels/scripts/install-$parcel" or die
- "Can't open installer script for $parcel for writing";
- print SCRIPT "#!/bin/sh\n\n";
- }
-
- for(@{$parcel_contents{$parcel}})
- {
- my @args = split /\s+/;
-
- my ($type,$name,$dest) = @args;
- my $optional = 0;
- my $install = 1;
-
- if ($type eq 'optional')
- {
- $optional = 1;
- shift @args;
- ($type,$name,$dest) = @args;
- }
-
- if ($type eq 'noinstall')
- {
- $install = 0;
- shift @args;
- ($type,$name,$dest) = @args;
- }
-
- if($type eq 'bin')
- {
- my $exeext = $platform_exe_ext;
- print MAKE <<EOF;
-$dir/$name$exeext: release/bin/$name/$name$exeext
- mkdir -p $dir
- $copy_command release/bin/$name/$name$exeext $dir
-
-.PHONY: release/bin/$name/$name$exeext
-release/bin/$name/$name$exeext:
- (cd bin/$name; \$(MAKE) $release_flag)
-
-EOF
- push @parcel_deps, "$dir/$name$exeext";
- }
- elsif ($type eq 'script')
- {
- # Replace any variables ($ac_target etc.) with their
- # values.
- $name =~ s|(\$[^/ ]+)|$1|eeg;
- my $fullpath = $name;
- my $filename = $name;
- # remove path from script name
- $filename =~ s{.*/}{};
-
- print MAKE <<EOF;
-$dir/$filename: $fullpath
- mkdir -p $dir
-EOF
-
- if ($optional)
- {
- print MAKE "\ttest -r $fullpath " .
- "&& $copy_command $fullpath $dir || true\n";
- }
- else
- {
- print MAKE "\t$copy_command $fullpath $dir\n";
- }
-
- print MAKE "\n";
-
- push @parcel_deps, "$dir/$filename";
- }
- elsif($type eq 'man')
- {
- print MAKE <<EOF;
-$dir/${name}.gz: docs/man/${name}.gz
- mkdir -p $dir
- $copy_command docs/man/${name}.gz $dir
-
-EOF
- # Releases have the docs pre-made, but users
- # may want to rebuild them for some reason.
- my $docbook_source = "docs/docbook/${name}";
- $docbook_source =~ s/\.[58]$/.xml/;
- print MAKE <<EOF;
-docs/man/${name}.gz: $docbook_source docs/docbook/bb-man.xsl
- cd docs; \$(MAKE) man/${name}.gz
-
-EOF
- push @parcel_deps, "$dir/${name}.gz";
- }
- elsif($type eq 'html')
- {
- print MAKE <<EOF;
-$dir/docs/${name}.html: docs/htmlguide/man-html/${name}.html
- mkdir -p $dir/docs
- $copy_command docs/htmlguide/man-html/${name}.html $dir/docs
-
-EOF
- # Releases have the docs pre-made, but users
- # may want to rebuild them for some reason.
- my $docbook_source = "docs/docbook/${name}.xml";
- print MAKE <<EOF;
-docs/htmlguide/man-html/${name}.html: $docbook_source docs/docbook/bb-nochunk-book.xsl
- cd docs; \$(MAKE) htmlguide/man-html/${name}.html
-
-EOF
- push @parcel_deps, "$dir/docs/${name}.html";
- }
- elsif ($type eq 'subdir')
- {
- shift @args;
- my $subdir = shift @args;
- print MAKE <<EOF;
-.PHONY: $name-build $name-clean
-
-$name-build:
- cd $subdir; \$(MAKE) @args
-
-$name-clean:
- cd $name; \$(MAKE) clean
-EOF
- push @parcel_deps, "$name-build";
- push @clean_deps, "$name-clean";
- }
- }
-
- print MAKE <<EOF;
-build-$parcel: $make_target
-
-$make_target: @parcel_deps
- test -d $dir || mkdir $dir
-EOF
-
- for(@{$parcel_contents{$parcel}})
- {
- my @args = split /\s+/;
-
- my ($type,$name,$dest) = @args;
-
- my $optional = 0;
- my $install = 1;
-
- if ($type eq 'optional')
- {
- $optional = 1;
- shift @args;
- ($type,$name,$dest) = @args;
- }
-
- if ($type eq 'noinstall')
- {
- $install = 0;
- shift @args;
- ($type,$name,$dest) = @args;
- }
-
- if ($type eq 'script')
- {
- # remove path from script name
- $name =~ s{.*/}{};
- }
-
- if ($type eq 'html')
- {
- $dest = "share/doc/@PACKAGE_TARNAME@";
- $name = "docs/$name.html";
- }
-
- if ($type eq 'man')
- {
- $name =~ /([0-9])$/;
- $dest = "man/man$1";
- $name =~ s/$/\.gz/;
- }
-
- if ($install and not $target_windows and not $type eq "subdir")
- {
- my $local_install_dir = $install_into_dir;
- if (defined $dest)
- {
- if ($dest =~ m,^/,)
- {
- # Don't add $prefix if $dest is a literal path
- $local_install_dir = $dest;
- }
- else
- {
- $local_install_dir = "@prefix@/$dest";
- }
- }
- print SCRIPT "mkdir -p " .
- "\${DESTDIR}$local_install_dir/\n";
- print SCRIPT "$install_bin $name " .
- "\${DESTDIR}$local_install_dir\n";
- }
- }
-
- unless ($target_windows)
- {
- close SCRIPT;
- chmod 0755,"parcels/scripts/install-$parcel";
- }
-
- my $root = BoxPlatform::parcel_root($parcel);
-
- unless ($target_windows)
- {
- print MAKE "\tcp parcels/scripts/install-$parcel $dir\n";
- }
-
- print MAKE "\t(cd parcels; tar cf - $root | gzip -9 - > $root.tgz )\n";
-
- print MAKE "\n";
-
- unless ($target_windows)
- {
- print MAKE "install-$parcel:\n";
- print MAKE "\t(cd $dir; ./install-$parcel)\n\n";
- }
-}
-
-print MAKE <<EOF;
-install:
- cat local/install.msg
-
-clean: @clean_deps
- cd docs; \$(MAKE) clean
-EOF
-
-if ($build_os eq 'CYGWIN')
-{
- print MAKE "\tfind release debug -type f | xargs -r rm\n";
- print MAKE "\tfind . -name 'autogen_*' -type f | xargs -r rm\n";
-}
-else
-{
- print MAKE "\tfind release debug -type f -exec rm -f {} \\;\n";
- print MAKE "\tfind . -name 'autogen_*' -type f -exec rm -f {} \\;\n";
-}
-
-for my $parcel (@parcels)
-{
- # need to use -f to avoid error if they don't exist (already cleaned)
- print MAKE "\trm -rf ", BoxPlatform::parcel_dir($parcel), "\n";
- print MAKE "\trm -f ", BoxPlatform::parcel_target($parcel), "\n";
-}
-
-close MAKE;
-
-open INSTALLMSG,">local/install.msg" or die "Can't open install message file for writing";
-print INSTALLMSG <<__E;
-
-Parcels need to be installed separately, and as root. Type one of the following:
-
-__E
-
-for(@parcels)
-{
- print INSTALLMSG " $make_command install-".$_."\n";
-}
-print INSTALLMSG "\n";
-
-close INSTALLMSG;
-
diff --git a/infrastructure/travis-build.sh b/infrastructure/travis-build.sh
index f4cd4ef4..aa9f62c2 100755
--- a/infrastructure/travis-build.sh
+++ b/infrastructure/travis-build.sh
@@ -11,5 +11,11 @@ cd `dirname $0`/..
grep CXX config.status
make V=1
./runtest.pl ALL $TEST_TARGET
+# When making a release build, also check that we can build the default
+# target and "parcels" (which is the same thing):
+if [ "$TEST_TARGET" = "release" ]; then
+ make
+ make parcels
+fi
ccache -s
diff --git a/modules.txt b/modules.txt
index 71ae16fd..4fd27a2d 100644
--- a/modules.txt
+++ b/modules.txt
@@ -7,15 +7,20 @@
# -l libaries must be in the order they should appear on the command line.
# Note that order is important on platforms which do not have shared libraries.
+# QDBM is currently built from a copy distributed in-tree, which we need to fix.
+qdbm
+
# Generic support code and modules
-lib/raidfile
-lib/crypto
+lib/win32
+lib/common lib/win32
+lib/raidfile lib/common
+lib/crypto lib/common
lib/server qdbm lib/crypto
-lib/compress
-lib/intercept
+lib/compress lib/common
+lib/intercept lib/common
-test/common qdbm
+test/common qdbm lib/common
test/crypto qdbm lib/crypto
test/compress qdbm lib/compress
test/raidfile qdbm lib/raidfile lib/intercept
@@ -38,11 +43,11 @@ bin/bbackupd lib/bbackupd
bin/bbackupquery lib/bbackupquery
bin/bbackupctl lib/backupclient qdbm lib/bbackupd
-test/backupstore bin/bbstored bin/bbstoreaccounts lib/server lib/backupstore lib/backupclient lib/raidfile
+test/backupstore bin/bbstored bin/bbstoreaccounts lib/backupclient lib/raidfile
test/backupstorefix bin/bbstored bin/bbstoreaccounts lib/backupclient bin/bbackupquery bin/bbackupd bin/bbackupctl
test/backupstorepatch bin/bbstored bin/bbstoreaccounts lib/backupclient
test/backupdiff lib/backupclient
-test/bbackupd bin/bbackupd bin/bbstored bin/bbstoreaccounts bin/bbackupquery bin/bbackupctl lib/bbackupquery lib/bbackupd lib/server lib/backupstore lib/backupclient lib/intercept lib/bbstored
+test/bbackupd bin/bbackupd bin/bbstored bin/bbstoreaccounts bin/bbackupquery bin/bbackupctl lib/bbackupquery lib/bbackupd lib/bbstored lib/server lib/intercept
bin/s3simulator lib/httpserver
test/s3store lib/backupclient lib/httpserver bin/s3simulator bin/bbstoreaccounts
diff --git a/parcels.txt b/parcels.txt
index 474c576b..7f961b10 100644
--- a/parcels.txt
+++ b/parcels.txt
@@ -18,8 +18,6 @@ backup-client
html bbackupd-config
html bbackupd.conf
- subdir qdbm libqdbm.a
-
EXCEPT:mingw32,mingw32msvc
man bbackupd.8
man bbackupquery.8