summaryrefslogtreecommitdiff
path: root/infrastructure/makebuildenv.pl
diff options
context:
space:
mode:
Diffstat (limited to 'infrastructure/makebuildenv.pl')
-rwxr-xr-xinfrastructure/makebuildenv.pl841
1 files changed, 841 insertions, 0 deletions
diff --git a/infrastructure/makebuildenv.pl b/infrastructure/makebuildenv.pl
new file mode 100755
index 00000000..94efa981
--- /dev/null
+++ b/infrastructure/makebuildenv.pl
@@ -0,0 +1,841 @@
+#!/usr/bin/perl
+# distribution boxbackup-0.10 (svn version: 494)
+#
+# Copyright (c) 2003 - 2006
+# Ben Summers and contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All use of this software and associated advertising materials must
+# display the following acknowledgment:
+# This product includes software developed by Ben Summers.
+# 4. The names of the Authors may not be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# [Where legally impermissible the Authors do not disclaim liability for
+# direct physical injury or death caused solely by defects in the software
+# unless it is modified by a third party.]
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#
+#
+use strict;
+use Symbol;
+
+my @modules;
+my %module_dependency;
+my %module_library_link_opts;
+my %header_dependency;
+
+$|=1;
+
+
+# note: Mac OS X resource forks and .DS_Store files are explicity ignored
+
+print "Box build environment setup.\n\n";
+
+
+my $implicit_dep = 'lib/common';
+
+# work out platform variables
+use lib 'infrastructure';
+use BoxPlatform;
+
+# 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')
+{
+ mkdir 'local',0755;
+}
+
+
+# flags about the environment
+my %env_flags;
+
+my $windows_include_path = "-I../../lib/win32 ";
+if ($target_os ne "mingw32" && $target_os ne "winnt")
+{
+ $windows_include_path = "";
+ $env_flags{'IGNORE_lib/win32'} = 1;
+}
+
+# print "Flag: $_\n" for(keys %env_flags);
+
+# seed autogen code
+print "Seeding autogen code...\n";
+open FINDAUTOGEN,"find . -follow -name Makefile.extra |" or die "Can't use find for locating files";
+while(<FINDAUTOGEN>)
+{
+ chomp;
+ my $file = $_;
+ $file =~ m~\A(.+)/[^/]+\Z~;
+ my $dir = $1;
+ open FL,$file or die "Can't open $_ for reading";
+ my %vars;
+ my $do_cmds = 0;
+ while(<FL>)
+ {
+ chomp;
+ if(m/\A(.+)\s+=\s+(.+)\Z/)
+ {
+ # is a variable
+ $vars{$1} = $2;
+ next;
+ }
+ next unless m/\S/;
+ if(m/AUTOGEN SEEDING/)
+ {
+ $do_cmds = 1;
+ }
+ elsif(m/\A\S/)
+ {
+ $do_cmds = 0 if $do_cmds == 2;
+ }
+ else
+ {
+ # command, run it?
+ if($do_cmds)
+ {
+ $do_cmds = 2; # flag something has been done
+
+ # subsitute variables, repeatedly
+ my $c = $_;
+ $c =~ s/\A\s+//;
+ while(1)
+ {
+ my $did_subst = 0;
+
+ for my $k (keys %vars)
+ {
+ $did_subst = 1 if $c =~ s/\$\($k\)/$vars{$k}/g;
+ }
+
+ last unless $did_subst;
+ }
+
+ # run command
+ die "Couldn't run command $c" unless (0 == system("(cd $dir; $c)"))
+ }
+ }
+ }
+ close FL;
+}
+close FINDAUTOGEN;
+print "done\n\n";
+
+
+# open test mail program template file
+my $test_template_file = 'infrastructure/buildenv-testmain-template.cpp';
+open FL,$test_template_file or die "Can't open test template file\n";
+my $test_template;
+read FL,$test_template,-s $test_template_file;
+close FL;
+
+
+# extra platform defines
+my $extra_platform_defines = '';
+
+# read in module definitions file, and any files it includes
+my @modules_files;
+sub read_modules_file
+{
+ my ($mf) = @_;
+ my $f = gensym;
+ open $f,$mf or die "Can't open modules file '$mf'\n";
+ while(<$f>)
+ {
+ if(m/\AINCLUDE\s+(\S+)\Z/)
+ {
+ # include another file
+ read_modules_file($1)
+ }
+ else
+ {
+ push @modules_files,$_
+ }
+ }
+ close $f;
+}
+read_modules_file('modules.txt');
+
+# prepare directories...
+mkdir "release",0755;
+mkdir "debug",0755;
+
+# is the library code in another directory?
+my $external_lib = readlink('lib');
+if($external_lib ne '')
+{
+ # adjust to root of the library distribution
+ $external_lib =~ s!/lib\Z!!;
+ $external_lib = '../'.$external_lib;
+ # make symlinks
+ make_obj_symlink('debug');
+ make_obj_symlink('release');
+}
+sub make_obj_symlink
+{
+ my $m = $_[0];
+ my $target = $external_lib."/$m/lib/";
+ my $link = "$m/lib";
+ # check link
+ if(-e $link)
+ {
+ if(-l $link)
+ {
+ if(readlink($link) ne $target)
+ {
+ print "Warning: replacing $link with new link to $target\n";
+ unlink $link;
+ }
+ }
+ else
+ {
+ die "$link already exists, but it isn't a symbolic link"
+ }
+ }
+ if(!-e $link)
+ {
+ symlink $target,$link or die "Can't make $m/lib symlink";
+ }
+}
+
+print "Scanning code...\n";
+
+my $modules_omitted = 0;
+my $modules_omitting = 0;
+
+# process lines in flattened modules files
+for(@modules_files)
+{
+ # clean up line
+ chomp; s/\A\s+//; s/#.*\Z//; s/\s+\Z//; s/\s+/ /g;
+ next unless m/\S/;
+
+ # omit bits on some platforms?
+ if(m/\AEND-OMIT/)
+ {
+ $modules_omitting = 0;
+ next;
+ }
+
+ next if $modules_omitting;
+
+ if(m/\AOMIT:(.+)/)
+ {
+ if($1 eq $build_os or $1 eq $target_os)
+ {
+ $modules_omitted = 1;
+ $modules_omitting = 1;
+ }
+ next;
+ }
+
+ # split up...
+ my ($mod, @deps_i) = split / /;
+
+ # ignore this module?
+ next if ignore_module($mod);
+
+ # deps for this platform
+ my @deps;
+ for(@deps_i)
+ {
+ my ($dep,$exclude_from) = split /!/;
+ # generic library translation
+ $dep = $env_flags{'LIBTRANS_'.$dep} if exists($env_flags{'LIBTRANS_'.$dep});
+ next if $dep eq '';
+ if($exclude_from =~ m/\A\+(.+)\Z/)
+ {
+ $exclude_from = $1;
+ my $inc = 0;
+ for(split /,/,$exclude_from)
+ {
+ $inc = 1 if $_ eq $build_os
+ }
+ push @deps,$dep if $inc
+ }
+ else
+ {
+ my $inc = 1;
+ for(split /,/,$exclude_from)
+ {
+ $inc = 0 if $_ eq $build_os
+ }
+ push @deps,$dep if $inc
+ }
+ }
+
+ # check directory exists
+ die "Module $mod can't be found\n" unless -d $mod;
+
+ # and put in lists
+ push @modules,$mod;
+ my @md; # module dependencies
+ my @lo; # link line options
+ for(@deps)
+ {
+ if(/\A-l/)
+ {
+ push @lo,$_
+ }
+ else
+ {
+ push @md,$_ unless ignore_module($_)
+ }
+ }
+ $module_dependency{$mod} = [$implicit_dep,@md];
+ $module_library_link_opts{$mod} = [@lo];
+
+ # make directories, but not if we're using an external library and this a library module
+ my ($s,$d) = split /\//,$mod;
+ if($s ne 'lib' || $external_lib eq '')
+ {
+ mkdir "release/$s",0755;
+ mkdir "release/$s/$d",0755;
+ mkdir "debug/$s",0755;
+ mkdir "debug/$s/$d",0755;
+ }
+}
+
+# make dirs for implicit dep
+mkdir "release/$implicit_dep",0755;
+mkdir "debug/$implicit_dep",0755;
+
+# write a list of all the modules we've configured to use
+open CONFIGURED_MODS,'>local/modules.h' or die "Can't write configured modules list";
+print CONFIGURED_MODS <<__E;
+// automatically generated file, do not edit
+#ifndef _CONFIGURED_MODULES__H
+#define _CONFIGURED_MODULES__H
+__E
+for($implicit_dep,@modules)
+{
+ my $m = $_;
+ $m =~ s~/~_~;
+ print CONFIGURED_MODS "#define MODULE_$m\n";
+}
+print CONFIGURED_MODS <<__E;
+#endif // _CONFIGURED_MODULES__H
+__E
+close CONFIGURED_MODS;
+
+
+# now make a list of all the .h files we can find, recording which module they're in
+my %hfiles;
+for my $mod (@modules, $implicit_dep)
+{
+ opendir DIR,$mod;
+ my @items = readdir DIR;
+ closedir DIR;
+
+ # add in items from autogen directories, and create output directories
+ {
+ my @autogen_items;
+
+ for my $di (@items)
+ {
+ if($di =~ m/\Aautogen/ && -d "$mod/$di")
+ {
+ # Read items
+ my $d = "$mod/$di";
+ opendir DIR,$d;
+ my @i = readdir DIR;
+ closedir DIR;
+ for(@i)
+ {
+ next if m/\A\./;
+ push @autogen_items,"$di/$_"
+ }
+ }
+ }
+ @items = (@items, @autogen_items);
+ }
+
+ for(grep /\.h\Z/i, @items)
+ {
+ next if /\A\._/; # Temp Mac OS Resource hack
+ die "Header file $_ already used in module ".$hfiles{$_}."\n" if exists $hfiles{$_};
+ $hfiles{$_} = $mod
+ }
+}
+
+for my $mod (@modules, $implicit_dep)
+{
+ opendir DIR,$mod;
+ for my $h (grep /\.h\Z/i, readdir DIR)
+ {
+ next if $h =~ /\A\./; # Ignore Mac resource forks, autosaves, etc
+
+ open FL,"$mod/$h" or die "can't open $mod/$h";
+ my $f;
+ read FL,$f,-s "$mod/$h";
+ close FL;
+
+ while($f =~ m/\#include\s+"([^"]+?)"/g)
+ {
+ my $i = $1;
+ # ignore autogen exceptions
+ next if $i =~ m/\Aautogen_.+?Exception.h\Z/;
+ # record dependency
+ ${$header_dependency{$h}}{$i} = 1 if exists $hfiles{$i};
+ }
+ }
+ closedir DIR;
+}
+
+print "done\n\nGenerating Makefiles...\n";
+
+
+# Then write a makefile for each module
+for my $mod (@modules, $implicit_dep)
+{
+ print $mod,"\n";
+
+ my ($type,$name) = split /\//,$mod;
+
+ # add additional files for tests
+ if($type eq 'test')
+ {
+ my $testmain = $test_template;
+ $testmain =~ s/TEST_NAME/$name/g;
+ open TESTMAIN,">$mod/_main.cpp" or die "Can't open test main file for $mod for writing\n";
+ print TESTMAIN $testmain;
+ close TESTMAIN;
+
+ # test file...
+ sub writetestfile
+ {
+ my ($filename,$runcmd,$module) = @_;
+ open TESTFILE,">$filename" or die "Can't open test script file for $module for writing\n";
+ print TESTFILE "#!/bin/sh\necho TEST: $module\n";
+ if(-d "$module/testfiles")
+ {
+ print TESTFILE <<__E;
+echo Removing old test files...
+rm -rf testfiles
+echo Copying new test files...
+cp -p -R ../../../$module/testfiles .
+__E
+ }
+ if(-e "$module/testextra")
+ {
+ open FL,"$module/testextra" or die "Can't open $module/testextra";
+ while(<FL>) {print TESTFILE}
+ close FL;
+ }
+ print TESTFILE "$runcmd\n";
+ close TESTFILE;
+ }
+
+ writetestfile("$mod/_t",
+ './test' . $platform_exe_ext . '$1 $2 $3 $4 $5', $mod);
+ writetestfile("$mod/_t-gdb",
+ 'gdb ./test ' . $platform_exe_ext, $mod);
+
+ }
+
+ my @all_deps_for_module;
+ {
+ # work out what dependencies need to be run
+ my @deps_raw;
+ sub add_mod_deps
+ {
+ my ($arr_r,$nm) = @_;
+ if($#{$module_dependency{$nm}} >= 0)
+ {
+ push @$arr_r,@{$module_dependency{$nm}};
+ for(@{$module_dependency{$nm}})
+ {
+ add_mod_deps($arr_r,$_)
+ }
+ }
+ }
+ add_mod_deps(\@deps_raw, $mod);
+ # and then dedup and reorder them
+ my %d_done;
+ for(my $a = $#deps_raw; $a >= 0; $a--)
+ {
+ if(!exists $d_done{$deps_raw[$a]})
+ {
+ # insert
+ push @all_deps_for_module, $deps_raw[$a];
+ # mark as done
+ $d_done{$deps_raw[$a]} = 1;
+ }
+ }
+ }
+
+
+ # make include path
+ my $include_paths = $windows_include_path .
+ 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;
+
+ if ($target_is_library)
+ {
+ $end_target .= '.a';
+ }
+ else
+ {
+ $end_target .= $platform_exe_ext;
+ }
+
+ $end_target = 'test'.$platform_exe_ext if $type eq 'test';
+
+ # adjust for outdir
+ $end_target = '$(OUTDIR)/' . $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 $release_flags = "-O2";
+ if ($target_os eq "mingw32")
+ {
+ $release_flags = "-O0 -g";
+ }
+
+ print MAKE <<__E;
+#
+# AUTOMATICALLY GENERATED FILE
+# do not edit!
+#
+#
+CXX = g++
+AR = ar
+RANLIB = ranlib
+.ifdef RELEASE
+CXXFLAGS = -DNDEBUG $release_flags -Wall $include_paths $extra_platform_defines -DBOX_VERSION="\\"$product_version\\""
+OUTBASE = ../../release
+OUTDIR = ../../release/$mod
+DEPENDMAKEFLAGS = -D RELEASE
+VARIENT = RELEASE
+.else
+CXXFLAGS = -g -Wall $include_paths $extra_platform_defines -DBOX_VERSION="\\"$product_version\\""
+OUTBASE = ../../debug
+OUTDIR = ../../debug/$mod
+DEPENDMAKEFLAGS =
+VARIENT = DEBUG
+.endif
+
+__E
+
+ # read directory
+ opendir DIR,$mod;
+ my @items = readdir DIR;
+ closedir DIR;
+
+ # add in items from autogen directories, and create output directories
+ {
+ my @autogen_items;
+ for my $di (@items)
+ {
+ if($di =~ m/\Aautogen/ && -d "$mod/$di")
+ {
+ # Read items
+ my $d = "$mod/$di";
+ opendir DIR,$d;
+ my @i = readdir DIR;
+ closedir DIR;
+ for(@i)
+ {
+ next if m/\A\./;
+ push @autogen_items,"$di/$_"
+ }
+
+ # output directories
+ mkdir "release/$mod/$di",0755;
+ mkdir "debug/$mod/$di",0755;
+ }
+ }
+ @items = (@items, @autogen_items);
+ }
+
+ # first, obtain a list of depenencies within the .h files
+ my %headers;
+ for my $h (grep /\.h\Z/i, @items)
+ {
+ open FL,"$mod/$h";
+ my $f;
+ read FL,$f,-s "$mod/$h";
+ close FL;
+
+ while($f =~ m/\#include\s+"([^"]+?)"/g)
+ {
+ ${$headers{$h}}{$1} = 1 if exists $hfiles{$1};
+ }
+ }
+
+ # ready for the rest of the details...
+ my $make;
+
+ # then... do the cpp files...
+ my @obj_base;
+ for my $cpp (@items)
+ {
+ next unless $cpp =~ m/\A(.+)\.cpp\Z/i;
+ next if $cpp =~ /\A\._/; # Temp Mac OS Resource hack
+
+ # store for later
+ my $base = $1;
+ push @obj_base,$base;
+
+ # get the file...
+ open FL,"$mod/$cpp";
+ my $f;
+ read FL,$f,-s "$mod/$cpp";
+ close FL;
+
+ my %dep;
+
+ while($f =~ m/\#include\s+"([^"]+?)"/g)
+ {
+ insert_dep($1, \%dep) if exists $hfiles{$1};
+ }
+
+ # output filename
+ my $out_name = '$(OUTDIR)/'.$base.'.o';
+
+ # write the line for this cpp file
+ $make .= $out_name.': '.join(' ',$cpp,map
+ { ($hfiles{$_} eq $mod)?$_:'../../'.$hfiles{$_}."/$_" } keys %dep)."\n";
+ $make .= "\t\$(CXX) \$(CXXFLAGS) $compile_line_extra -c $cpp -o $out_name\n\n";
+
+ }
+
+ my $has_deps = ($#{$module_dependency{$mod}} >= 0);
+# ----- # always has dependencies with debug library
+ $has_deps = 1;
+ $has_deps = 0 if $target_is_library;
+
+ # Depenency stuff
+ my $deps_makeinfo;
+ if($has_deps)
+ {
+ if($bsd_make)
+ {
+ $deps_makeinfo = <<'__E';
+.BEGIN::
+.ifndef NODEPS
+. if $(.TARGETS) == ""
+__E
+ }
+ else
+ {
+ # gnu make
+ $deps_makeinfo = <<'__E';
+.PHONY: dep_modules
+dep_modules:
+ifndef NODEPS
+ifeq ($(strip $(.TARGETS)),)
+__E
+ }
+
+ # run make for things we require
+ for my $dep (@all_deps_for_module)
+ {
+ $deps_makeinfo .= "\t\t(cd ../../$dep; \$(MAKE)$sub_make_options \$(DEPENDMAKEFLAGS) -D NODEPS)\n";
+ }
+ $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 = join(' ',map {($_ =~ m/lib\/(.+)\Z/)?('$(OUTBASE)/'.$_.'/'.$1.'.a'):undef} (reverse(@all_deps_for_module)));
+
+ # 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);
+
+ my $o_file_list = join(' ',map {'$(OUTDIR)/'.$_.'.o'} @objs);
+ print MAKE $end_target,': ',$o_file_list;
+ print MAKE ' dep_modules' if $has_deps and not $bsd_make;
+ print MAKE " ",$lib_files unless $target_is_library;
+ print MAKE "\n";
+
+ # stuff to make the final target...
+ if($target_is_library)
+ {
+ # make a library archive...
+ print MAKE "\t(echo -n > $end_target; rm $end_target)\n";
+ print MAKE "\t\$(AR) -q $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
+ {
+ my ($m,$r) = @_;
+ push @$r,$_ for(@{$module_library_link_opts{$m}});
+ libops_fill($_,$r) for(@{$module_dependency{$m}});
+ }
+ libops_fill($mod,\@libops);
+ my $lo = '';
+ my %ldone;
+ for(@libops)
+ {
+ next if exists $ldone{$_};
+ $lo .= ' '.$_;
+ $ldone{$_} = 1;
+ }
+
+ # link line...
+ print MAKE "\t\$(CXX) $link_line_extra -o $end_target $o_file_list $lib_files$lo $platform_lib_files\n";
+ }
+ # 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";
+ }
+ # dependency line?
+ print MAKE "\n";
+
+ # 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 "clean:\n\t-rm -rf \$(OUTDIR)/*\n.\tifndef SUBCLEAN\n";
+ for my $dep (@all_deps_for_module)
+ {
+ print MAKE "\t(cd ../../$dep; \$(MAKE) \$(DEPENDMAKEFLAGS) -D SUBCLEAN clean)\n";
+ }
+ print MAKE ".\tendif\n";
+
+ # 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")
+ {
+ print MAKE ".include <Makefile.extra.$build_os>\n\n";
+ }
+ for(@makefile_includes)
+ {
+ print MAKE ".include <$_>\n\n";
+ }
+
+ # 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;
+
+ if(!$bsd_make)
+ {
+ # need to post process this into a GNU makefile
+ open MAKE,">$mod/Makefile";
+ open MAKEB,"$mod/MakefileX";
+
+ while(<MAKEB>)
+ {
+ s/\A\.\s*(ifdef|else|endif|ifndef)/$1/;
+ s/\A\.\s*include\s+<(.+?)>/include $1/;
+ s/-D\s+(\w+)/$1=1/;
+ print MAKE;
+ }
+
+ close MAKEB;
+ close MAKE;
+ unlink "$mod/MakefileX";
+ }
+}
+
+print "\nType 'cd <module_dir>; $make_command' to build a module\n\n";
+
+if($modules_omitted)
+{
+ print "\nNOTE: Some modules have been omitted on this platform\n\n"
+}
+
+sub insert_dep
+{
+ my ($h,$dep_r) = @_;
+
+ # stop random recusion
+ return if exists $$dep_r{$h};
+
+ # insert more depencies
+ insert_dep($_,$dep_r) for keys %{$header_dependency{$h}};
+
+ # mark this one as a dependency
+ $$dep_r{$h} = 1;
+}
+
+
+sub additional_objects_from_make_fragment
+{
+ my ($fn,$objs_r,$include_r) = @_;
+
+ if(-e $fn)
+ {
+ open FL,$fn or die "Can't open $fn";
+
+ while(<FL>)
+ {
+ chomp;
+ if(m/link-extra:\s*(.+)\Z/)
+ {
+ my @o = split /\s+/,$1;
+ for(@o)
+ {
+ push @$objs_r,$1 if m/\A(.+)\.o\Z/;
+ }
+ }
+ elsif(m/include-makefile:\s*(\S+)/)
+ {
+ push @$include_r,$1
+ }
+ }
+
+ close FL;
+ }
+}
+
+
+sub ignore_module
+{
+ exists $env_flags{'IGNORE_'.$_[0]}
+}