Skip to content

Commit

Permalink
Custom build system: fix autogen dependencies
Browse files Browse the repository at this point in the history
Remove useless inclusion of Makefile.extras with paths in subdirs that will
never match anything, and replace those inclusions with recursive Make calls to
build those targets. This allows changes to exception and protocol files to be
detected automatically, and the C++ code regenerated.
  • Loading branch information
qris committed Aug 4, 2017
1 parent a28369d commit 026b645
Showing 1 changed file with 84 additions and 47 deletions.
131 changes: 84 additions & 47 deletions infrastructure/makebuildenv.pl.in
Expand Up @@ -41,19 +41,42 @@ my %env_flags;

# print "Flag: $_\n" for(keys %env_flags);

sub substitute_make_vars($$)
{
my ($input, $vars) = @_;
$vars->{_PERL} = '@PERL@';

# substitute variables, repeatedly
while(1)
{
my $did_subst = 0;

for my $k (keys %$vars)
{
$did_subst = 1 if $input =~ s/\$\($k\)/$vars->{$k}/g;
}

last unless $did_subst;
}

return $input;
}

# 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;
$vars{_PERL} = "@PERL@";
my $do_cmds = 0;

while(<FL>)
{
chomp;
Expand All @@ -80,19 +103,8 @@ while(<FINDAUTOGEN>)
$do_cmds = 2; # flag something has been done

# substitute variables, repeatedly
my $c = $_;
my $c = substitute_make_vars($_, \%vars);
$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
unless (0 == system("(cd $dir; $c)"))
Expand Down Expand Up @@ -375,6 +387,7 @@ $default_cxxflags =~ s/ -O2//g;
my $debug_base_dir = 'debug';
my $release_base_dir = 'release';
my $debugger = '@with_debugger@';
my $perl = '@PERL@';

my $release_flags = "-O2";
if ($target_windows)
Expand Down Expand Up @@ -783,13 +796,51 @@ __E
}
}

# need to see if the extra makefile fragments require extra object files
# or include any more makefiles
my @objs_extra;
my @makefile_includes;
my %autogen_targets_global;
my %autogen_targets_platform;

my %makefile_to_autogen = (
"$mod/Makefile.extra" => \%autogen_targets_global,
"$mod/Makefile.extra.$build_os" => \%autogen_targets_platform,
);

while (my ($makefile, $autogens) = each %makefile_to_autogen)
{
additional_objects_from_make_fragment($makefile, \@objs_extra,
\@makefile_includes, $autogens);
}

while (my ($makefile, $autogens) = each %makefile_to_autogen)
{
$makefile =~ s|^$mod/||g or die "$makefile should start with $mod";
while (my ($outputs, $inputs) = each %$autogens)
{
my @prefixed_inputs = map {"$mod/$_"} (split /\s+/, $inputs);
my @prefixed_outputs = map {"$mod/$_"} (split /\s+/, $outputs);
# Delegate to the extra sub-makefile:
print MASTER_MAKEFILE "\n";
print MASTER_MAKEFILE "@prefixed_outputs: @prefixed_inputs\n";
# Since the command produces all $outputs, to avoid a spurious "target
# is up to date" message for the 2nd+ targets, we only make the first:
my $first_output = $outputs;
$first_output =~ s/\s+.*//;
print MASTER_MAKEFILE "\t\$(MAKE) _PERL='$perl' -C $mod -f $makefile $first_output\n";
}
}

print MASTER_MAKEFILE "\n";

# write the recipes for debug and release builds of each file
foreach my $var_prefix ('DEBUG', 'RELEASE')
{
my $make;

# then... do the cpp files...
my @obj_base;
my @objs = @objs_extra;
for my $file (@items)
{
my $is_c = $file =~ m@(([^/]+)\.c)\Z@i;
Expand All @@ -803,7 +854,7 @@ __E
next if $file =~ /\A\._/; # Temp Mac OS Resource hack

# store for later
push @obj_base, $base;
push @objs, $base;

# get the file...
open FL, $file or die "$file: $!";
Expand Down Expand Up @@ -854,14 +905,6 @@ __E
}
}

# 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 $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;
Expand Down Expand Up @@ -960,27 +1003,6 @@ realclean_${type}_${name}: clean_${type}_${name}
__E
push @all_clean_targets, "clean_${type}_${name}";
push @all_realclean_targets, "realclean_${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;
Expand Down Expand Up @@ -1389,16 +1411,23 @@ sub insert_dep

sub additional_objects_from_make_fragment
{
my ($fn,$objs_r,$include_r) = @_;
my ($fn,$objs_r,$include_r,$autogen_targets_r) = @_;

if(-e $fn)
{
open FL,$fn or die "Can't open $fn";
my %vars;

while(<FL>)
{
chomp;
if(m/link-extra:\s*(.+)\Z/)
if(m/\A(.+)\s+=\s+(.+)\Z/)
{
# is a variable
$vars{$1} = $2;
next;
}
elsif(m/link-extra:\s*(.+)\Z/)
{
my $extra = $1;
do
Expand All @@ -1417,6 +1446,14 @@ sub additional_objects_from_make_fragment
{
push @$include_r,$1
}
elsif(m/^(\S.*\S)\s*:\s*(\S.*\S)\s*$/)
{
my $outputs = $1;
my $inputs = $2;
$outputs = substitute_make_vars($outputs, \%vars);
$inputs = substitute_make_vars($inputs, \%vars);
$autogen_targets_r->{$outputs} = $inputs;
}
}

close FL;
Expand Down

0 comments on commit 026b645

Please sign in to comment.