source: box/trunk/infrastructure/makebuildenv.pl.in @ 3013

Revision 3013, 20.2 KB checked in by chris, 4 months ago (diff)

Extra white space.

  • Property svn:eol-style set to native
Line 
1#!@PERL@
2use strict;
3use Symbol;
4
5my @modules;
6my %module_dependency;
7my %module_library_link_opts;
8my %header_dependency;
9
10$|=1;
11
12
13# note: Mac OS X resource forks and .DS_Store files are explicity ignored
14
15print "Box build environment setup.\n";
16
17my @implicit_deps = ('lib/common');
18
19# work out platform variables
20use lib 'infrastructure';
21use BoxPlatform;
22
23print "Building on '$build_os'.\n\n";
24
25# keep copy of command line args
26my $makebuildenv_args = join(' ',@ARGV);
27
28# do command line arguments
29my $compile_line_extra = $platform_compile_line_extra;
30my $link_line_extra = $platform_link_line_extra;
31
32# make sure local files directory exists
33unless(-d 'local')
34{
35        mkdir 'local',0755;
36}
37
38
39# flags about the environment
40my %env_flags;
41
42$module_dependency{"lib/common"} = ["lib/win32"];
43push @implicit_deps, "lib/win32";
44
45# print "Flag: $_\n" for(keys %env_flags);
46
47# seed autogen code
48print "Seeding autogen code...\n";
49open FINDAUTOGEN,"find . -follow -name Makefile.extra |" or die "Can't use find for locating files";
50while(<FINDAUTOGEN>)
51{
52        chomp;
53        my $file = $_;
54        $file =~ m~\A(.+)/[^/]+\Z~;
55        my $dir = $1;
56        open FL,$file or die "Can't open $_ for reading";
57        my %vars;
58        $vars{_PERL} = "@PERL@";
59        my $do_cmds = 0;
60        while(<FL>)
61        {
62                chomp;
63                if(m/\A(.+)\s+=\s+(.+)\Z/)
64                {
65                        # is a variable
66                        $vars{$1} = $2;
67                        next;
68                }
69                next unless m/\S/;
70                if(m/AUTOGEN SEEDING/)
71                {
72                        $do_cmds = 1;
73                }
74                elsif(m/\A\S/)
75                {
76                        $do_cmds = 0 if $do_cmds == 2;
77                }
78                else
79                {
80                        # command, run it?
81                        if($do_cmds)
82                        {
83                                $do_cmds = 2; # flag something has been done
84                               
85                                # subsitute variables, repeatedly
86                                my $c = $_;
87                                $c =~ s/\A\s+//;
88                                while(1)
89                                {
90                                        my $did_subst = 0;
91                                       
92                                        for my $k (keys %vars)
93                                        {
94                                                $did_subst = 1 if $c =~ s/\$\($k\)/$vars{$k}/g;
95                                        }
96                                       
97                                        last unless $did_subst;
98                                }
99                               
100                                # run command
101                                unless (0 == system("(cd $dir; $c)"))
102                                {
103                                        die "Couldn't run command $c " .
104                                                "(in $dir) for $file";
105                                }
106                        }
107                }
108        }
109        close FL;
110}
111close FINDAUTOGEN;
112print "done\n\n";
113
114
115# open test mail program template file
116my $test_template_file = 'infrastructure/buildenv-testmain-template.cpp';
117open FL,$test_template_file or die "Can't open test template file\n";
118my $test_template;
119read FL,$test_template,-s $test_template_file;
120close FL;
121
122
123# extra platform defines
124my $extra_platform_defines = '';
125
126# read in module definitions file, and any files it includes
127my @modules_files;
128sub read_modules_file
129{
130        my ($mf) = @_;
131        my $f = gensym;
132        open $f,$mf or die "Can't open modules file '$mf'\n";
133        while(<$f>)
134        {
135                if(m/\AINCLUDE\s+(\S+)\Z/)
136                {
137                        # include another file
138                        read_modules_file($1)
139                }
140                else
141                {
142                        push @modules_files,$_
143                }
144        }
145        close $f;
146}
147read_modules_file('modules.txt');
148
149# prepare directories...
150mkdir "release",0755;
151mkdir "debug",0755;
152
153# is the library code in another directory?
154my $external_lib = readlink('lib');
155if($external_lib ne '')
156{
157        # adjust to root of the library distribution
158        $external_lib =~ s!/lib\Z!!;
159        $external_lib = '../'.$external_lib;
160        # make symlinks
161        make_obj_symlink('debug');
162        make_obj_symlink('release');
163}
164sub make_obj_symlink
165{
166        my $m = $_[0];
167        my $target = $external_lib."/$m/lib/";
168        my $link = "$m/lib";
169        # check link
170        if(-e $link)
171        {
172                if(-l $link)
173                {
174                        if(readlink($link) ne $target)
175                        {
176                                print "Warning: replacing $link with new link to $target\n";
177                                unlink $link;
178                        }
179                }
180                else
181                {
182                        die "$link already exists, but it isn't a symbolic link"
183                }
184        }
185        if(!-e $link)
186        {
187                symlink $target,$link or die "Can't make $m/lib symlink";
188        }
189}
190
191print "Scanning code...\n";
192
193my $modules_omitted = 0;
194my $modules_omitting = 0;
195
196# process lines in flattened modules files
197for(@modules_files)
198{
199        # clean up line
200        chomp; s/\A\s+//; s/#.*\Z//; s/\s+\Z//; s/\s+/ /g;
201        next unless m/\S/;
202       
203        # omit bits on some platforms?
204        if(m/\AEND-OMIT/)
205        {
206                $modules_omitting = 0;
207                next;
208        }
209
210        next if $modules_omitting;
211
212        if(m/\AOMIT:(.+)/)
213        {
214                if($1 eq $build_os or $1 eq $target_os)
215                {
216                        $modules_omitted = 1;
217                        $modules_omitting = 1;
218                }
219                next;
220        }
221       
222        # split up...
223        my ($mod, @deps_i) = split / /;
224       
225        # ignore this module?
226        next if ignore_module($mod);
227       
228        # deps for this platform
229        my @deps;
230        for(@deps_i)
231        {
232                my ($dep,$exclude_from) = split /!/;
233                # generic library translation
234                $dep = $env_flags{'LIBTRANS_'.$dep} if exists($env_flags{'LIBTRANS_'.$dep});
235                next if $dep eq '';
236                if($exclude_from =~ m/\A\+(.+)\Z/)
237                {
238                        $exclude_from = $1;
239                        my $inc = 0;
240                        for(split /,/,$exclude_from)
241                        {
242                                $inc = 1 if $_ eq $build_os
243                        }
244                        push @deps,$dep if $inc
245                }
246                else
247                {
248                        my $inc = 1;
249                        for(split /,/,$exclude_from)
250                        {
251                                $inc = 0 if $_ eq $build_os
252                        }
253                        push @deps,$dep if $inc
254                }
255        }
256       
257        # check directory exists
258        die "Module $mod can't be found\n" unless -d $mod;
259       
260        # and put in lists
261        push @modules,$mod;
262        my @md; # module dependencies
263        my @lo; # link line options
264        for (@deps)
265        {
266                if(/\A-l/)
267                {
268                        push @lo,$_
269                }
270                else
271                {
272                        push @md,$_ unless ignore_module($_)
273                }
274        }
275        $module_dependency{$mod} = [@implicit_deps,@md];
276        $module_library_link_opts{$mod} = [@lo];
277       
278        # make directories, but not if we're using an external library and this a library module
279        my ($s,$d) = split /\//,$mod;
280        if ($s ne 'lib' or $external_lib eq '')
281        {
282                mkdir "release/$s",0755;
283                mkdir "release/$s/$d",0755;
284                mkdir "debug/$s",0755;
285                mkdir "debug/$s/$d",0755;
286        }
287}
288
289# make dirs for implicit dep
290foreach my $dep (@implicit_deps)
291{
292        mkdir "release/$dep",0755;
293        mkdir "debug/$dep",0755;
294}
295
296# write a list of all the modules we've configured to use
297open CONFIGURED_MODS,'>local/modules.h' or die "Can't write configured modules list";
298print CONFIGURED_MODS <<__E;
299// automatically generated file, do not edit
300#ifndef _CONFIGURED_MODULES__H
301#define _CONFIGURED_MODULES__H
302__E
303for(@implicit_deps,@modules)
304{
305        my $m = $_;
306        $m =~ s~/~_~;
307        print CONFIGURED_MODS "#define MODULE_$m\n";
308}
309print CONFIGURED_MODS <<__E;
310#endif // _CONFIGURED_MODULES__H
311__E
312close CONFIGURED_MODS;
313
314
315# now make a list of all the .h files we can find, recording which module they're in
316my %hfiles;
317for my $mod (@modules, @implicit_deps)
318{
319        opendir DIR,$mod;
320        my @items = readdir DIR;
321        closedir DIR;
322
323        # add in items from autogen directories, and create output directories
324        {
325                my @autogen_items;
326               
327                for my $di (@items)
328                {
329                        if($di =~ m/\Aautogen/ && -d "$mod/$di")
330                        {
331                                # Read items
332                                my $d = "$mod/$di";
333                                opendir DIR,$d;
334                                my @i = readdir DIR;
335                                closedir DIR;
336                                for(@i)
337                                {
338                                        next if m/\A\./;
339                                        push @autogen_items,"$di/$_"
340                                }
341                        }
342                }
343                @items = (@items, @autogen_items);
344        }
345
346        for(grep /\.h\Z/i, @items)
347        {
348                next if /\A\._/;        # Temp Mac OS Resource hack
349                die "Header file $_ already used in module ".$hfiles{$_}.
350                        ", cannot add to $mod\n" if exists $hfiles{$_};
351                $hfiles{$_} = $mod
352        }
353}
354
355for my $mod (@modules, @implicit_deps)
356{
357        opendir DIR,$mod;
358        for my $h (grep /\.h\Z/i, readdir DIR)
359        {
360                next if $h =~ /\A\./;           # Ignore Mac resource forks, autosaves, etc
361
362                open FL,"$mod/$h" or die "can't open $mod/$h";
363                my $f;
364                read FL,$f,-s "$mod/$h";
365                close FL;
366
367                while($f =~ m/\#include\s+"([^"]+?)"/g)
368                {
369                        my $i = $1;
370                        # ignore autogen exceptions
371                        next if $i =~ m/\Aautogen_.+?Exception.h\Z/;
372                        # record dependency
373                        ${$header_dependency{$h}}{$i} = 1 if exists $hfiles{$i};
374                }
375        }
376        closedir DIR;
377}
378
379# Then write a makefile for each module
380print "done\n\nGenerating Makefiles...\n";
381
382my %module_resources_win32;
383
384for my $mod (@implicit_deps, @modules)
385{
386        print $mod,"\n";
387       
388        my ($type,$name) = split /\//,$mod;
389       
390        # add additional files for tests
391        if($type eq 'test')
392        {
393                my $testmain = $test_template;
394                $testmain =~ s/TEST_NAME/$name/g;
395                open TESTMAIN,">$mod/_main.cpp" or die "Can't open test main file for $mod for writing\n";
396                print TESTMAIN $testmain;
397                close TESTMAIN;
398               
399                # test file...
400                sub writetestfile
401                {
402                        my ($filename,$runcmd,$module) = @_;           
403
404                        open TESTFILE,">$filename" or die "Can't open " .
405                                "test script file for $module for writing\n";
406                        print TESTFILE "#!/bin/sh\necho TEST: $module\n";
407
408                        if ($target_windows)
409                        {
410                                print TESTFILE <<__E;
411kill_process()
412{
413        if test -r testfiles/\$1.pid; then
414                /bin/kill -0 -f `cat testfiles/\$1.pid` \\
415                && /bin/kill -f `cat testfiles/\$1.pid`
416                rm testfiles/\$1.pid
417        fi
418}
419__E
420                        }
421                        else
422                        {
423                                print TESTFILE <<__E;
424kill_process()
425{
426        test -r testfiles/\$1.pid \\
427        && kill -0 `cat testfiles/\$1.pid` \\
428        && kill    `cat testfiles/\$1.pid`
429}
430__E
431                        }
432
433                        if (-d "$module/testfiles")
434                        {
435                                print TESTFILE <<__E;
436kill_daemons()
437{
438        kill_process bbackupd
439        kill_process bbstored
440        kill_process httpserver
441        kill_process s3simulator
442}
443
444echo Killing any running daemons...
445kill_daemons
446__E
447                        }
448
449                        print TESTFILE <<__E;
450echo Removing old test files...
451chmod -R a+rwx testfiles
452rm -rf testfiles
453
454echo Copying new test files...
455cp -p -R ../../../$module/testfiles .
456
457__E
458
459                        if (-e "$module/testextra")
460                        {
461                                open FL,"$module/testextra" or die
462                                        "Can't open $module/testextra";
463                                while(<FL>) {print TESTFILE}
464                                close FL;
465                        }
466
467                        print TESTFILE "$runcmd\n";
468
469                        if (-d "$module/testfiles")
470                        {
471                                print TESTFILE <<__E;
472kill_daemons
473__E
474                        }
475
476                        close TESTFILE;
477                }
478               
479                writetestfile("$mod/_t", "GLIBCXX_FORCE_NEW=1 ".
480                        './test' . $platform_exe_ext . ' "$@"', $mod);
481                writetestfile("$mod/_t-gdb", "GLIBCXX_FORCE_NEW=1 ".
482                        'gdb ./test' . $platform_exe_ext . ' "$@"', $mod);
483               
484        }
485       
486        my @all_deps_for_module;
487
488        {
489                # work out what dependencies need to be run
490                my @deps_raw;
491                sub add_mod_deps
492                {
493                        my ($arr_r,$nm) = @_;
494                        if($#{$module_dependency{$nm}} >= 0)
495                        {
496                                push @$arr_r,@{$module_dependency{$nm}};
497                                for(@{$module_dependency{$nm}})
498                                {
499                                        add_mod_deps($arr_r,$_)
500                                }
501                        }
502                }
503                add_mod_deps(\@deps_raw, $mod);
504                # and then dedup and reorder them
505                my %d_done;
506                foreach my $dep (reverse @deps_raw)
507                {
508                        if(!exists $d_done{$dep})
509                        {
510                                # insert
511                                push @all_deps_for_module, $dep;
512                                # mark as done
513                                $d_done{$dep} = 1;
514                        }
515                }
516        }       
517       
518
519        # make include path
520        my $include_paths = join(' ',map {'-I../../'.$_} @all_deps_for_module);
521
522        # is target a library?
523        my $target_is_library = ($type ne 'bin' && $type ne 'test');
524
525        # make target name
526        my $end_target = $name;
527
528        if ($target_is_library)
529        {
530                $end_target .= '.a';
531        }
532        else
533        {
534                $end_target .= $platform_exe_ext;
535        }
536
537        $end_target = 'test'.$platform_exe_ext if $type eq 'test';
538
539        # adjust for outdir
540        $end_target = '$(OUTDIR)/' . $end_target;
541
542        # start the makefile
543        my $mk_name_extra = ($bsd_make)?'':'X';
544        open MAKE,">$mod/Makefile".$mk_name_extra or die "Can't open Makefile for $mod\n";
545        my $debug_link_extra = ($target_is_library)?'':'../../debug/lib/debug/debug.a';
546
547        my $default_cxxflags = '@CXXFLAGS@';
548        $default_cxxflags =~ s/ -O2//g;
549
550        my $release_flags = "-O2";
551        if ($target_windows)
552        {
553                $release_flags = "-O0 -g";
554        }
555
556        print MAKE <<__E;
557#
558# AUTOMATICALLY GENERATED FILE
559#    do not edit!
560#
561#
562CXX = @CXX@
563AR = @AR@
564RANLIB = @RANLIB@
565PERL = @PERL@
566WINDRES = @WINDRES@
567
568DEFAULT_CXXFLAGS = @CPPFLAGS@ $default_cxxflags @CXXFLAGS_STRICT@ \\
569        $include_paths $extra_platform_defines \\
570        -DBOX_VERSION="\\"$product_version\\""
571LDFLAGS += @LDFLAGS@ @LDADD_RDYNAMIC@
572
573.ifdef RELEASE
574CXXFLAGS += -DBOX_RELEASE_BUILD $release_flags \$(DEFAULT_CXXFLAGS)
575OUTBASE = ../../release
576OUTDIR = ../../release/$mod
577DEPENDMAKEFLAGS = -D RELEASE
578VARIENT = RELEASE
579.else
580CXXFLAGS += -g \$(DEFAULT_CXXFLAGS)
581OUTBASE = ../../debug
582OUTDIR = ../../debug/$mod
583DEPENDMAKEFLAGS =
584VARIENT = DEBUG
585.endif
586
587__E
588
589        if ($bsd_make)
590        {
591                print MAKE <<__E;
592.ifdef V
593HIDE     =
594_CXX     = \$(CXX)
595_LINK    = \$(CXX)
596_WINDRES = \$(WINDRES)
597_AR      = \$(AR)
598_RANLIB  = \$(RANLIB)
599_PERL    = \$(PERL)
600.else
601HIDE     = @
602_CXX     = @ echo "  [CXX]    " \$(*F) && \$(CXX)
603_LINK    = @ echo "  [LINK]   " \$(*F) && \$(CXX)
604_WINDRES = @ echo "  [WINDRES]" \$(*F) && \$(WINDRES)
605_AR      = @ echo "  [AR]     " \$(*F) && \$(AR)
606_RANLIB  = @ echo "  [RANLIB] " \$(*F) && \$(RANLIB)
607_PERL    = @ echo "  [PERL]   " \$(*F) && \$(PERL) >/dev/null
608.endif
609
610__E
611        }
612        else
613        {
614                print MAKE <<__E;
615HIDE     = \$(if \$(V),,@)
616_CXX     = \$(if \$(V),\$(CXX),     @ echo "  [CXX]     \$<" && \$(CXX))
617_LINK    = \$(if \$(V),\$(CXX),     @ echo "  [LINK]    \$@" && \$(CXX))
618_WINDRES = \$(if \$(V),\$(WINDRES), @ echo "  [WINDRES] \$<" && \$(WINDRES))
619_AR      = \$(if \$(V),\$(AR),      @ echo "  [AR]      \$@" && \$(AR))
620_RANLIB  = \$(if \$(V),\$(RANLIB),  @ echo "  [RANLIB]  \$@" && \$(RANLIB))
621_PERL    = \$(if \$(V),\$(PERL),    @ echo "  [PERL]    \$@" && \$(PERL) >/dev/null)
622
623__E
624        }
625
626        # if there is a Makefile.pre, include it now
627        if(-e "$mod/Makefile.pre")
628        {
629                print MAKE ".include <Makefile.pre>\n\n";
630        }
631       
632        # read directory
633        opendir DIR,$mod;
634        my @items = readdir DIR;
635        closedir DIR;
636       
637        # add in items from autogen directories, and create output directories
638        {
639                my @autogen_items;
640                for my $di (@items)
641                {
642                        if($di =~ m/\Aautogen/ && -d "$mod/$di")
643                        {
644                                # Read items
645                                my $d = "$mod/$di";
646                                opendir DIR,$d;
647                                my @i = readdir DIR;
648                                closedir DIR;
649                                for(@i)
650                                {
651                                        next if m/\A\./;
652                                        push @autogen_items,"$di/$_"
653                                }
654                               
655                                # output directories
656                                mkdir "release/$mod/$di",0755;
657                                mkdir "debug/$mod/$di",0755;
658                        }
659                }
660                @items = (@items, @autogen_items);
661        }
662       
663        # first, obtain a list of dependencies within the .h files
664        my %headers;
665        for my $h (grep /\.h\Z/i, @items)
666        {
667                open FL,"$mod/$h";
668                my $f;
669                read FL,$f,-s "$mod/$h";
670                close FL;
671
672                while($f =~ m/\#include\s+"([^"]+?)"/g)
673                {
674                        ${$headers{$h}}{$1} = 1 if exists $hfiles{$1};
675                }
676        }
677       
678        # ready for the rest of the details...
679        my $make;
680       
681        # then... do the cpp files...
682        my @obj_base;
683        for my $file (@items)
684        {
685                my $is_cpp = $file =~ m/\A(.+)\.cpp\Z/i;
686                my $is_rc  = $file =~ m/\A(.+)\.rc\Z/i;
687                my $base = $1;
688
689                if ($target_windows)
690                {
691                        next if not $is_cpp and not $is_rc;
692                }
693                else
694                {
695                        next if not $is_cpp;
696                }
697
698                next if $file =~ /\A\._/; # Temp Mac OS Resource hack
699
700                # store for later
701                push @obj_base,$base;
702       
703                # get the file...
704                open FL,"$mod/$file";
705                my $f;
706                read FL,$f,-s "$mod/$file";
707                close FL;
708               
709                my %dep;
710
711                while($f =~ m/\#include\s+"([^"]+?)"/g)
712                {
713                        insert_dep($1, \%dep) if exists $hfiles{$1};
714                }
715               
716                # output filename
717                my $out_name = '$(OUTDIR)/'.$base.'.o';
718               
719                # write the line for this cpp file
720                my @dep_paths = map
721                {
722                        ($hfiles{$_} eq $mod)
723                        ? $_
724                        : '../../'.$hfiles{$_}."/$_"
725                }
726                keys %dep;
727
728                $make .= $out_name.': '.join(' ',$file,@dep_paths)."\n";
729
730                if ($is_cpp)
731                {
732                        $make .= "\t\$(_CXX) \$(CXXFLAGS) $compile_line_extra ".
733                                "-DBOX_MODULE=\"\\\"$mod\\\"\" " .
734                                "-c $file -o $out_name\n\n";
735                }
736                elsif ($is_rc)
737                {
738                        $make .= "\t\$(_WINDRES) $file $out_name\n\n";
739                        my $res_list = $module_resources_win32{$mod};
740                        $res_list ||= [];
741                        push @$res_list, $base.'.o';
742                        $module_resources_win32{$mod} = $res_list;
743                }
744        }
745
746        my $has_deps = ($#{$module_dependency{$mod}} >= 0);
747# ----- # always has dependencies with debug library
748        $has_deps = 1;
749        $has_deps = 0 if $target_is_library;
750
751        # Dependency stuff
752        my $deps_makeinfo;
753        if($has_deps)
754        {
755                if($bsd_make)
756                {
757                        $deps_makeinfo = <<'__E';
758.BEGIN::
759.ifndef NODEPS
760.       if $(.TARGETS) == ""
761__E
762                }
763                else
764                {
765                        # gnu make
766                        $deps_makeinfo = <<'__E';
767.PHONY: dep_modules
768dep_modules:
769ifndef NODEPS
770ifeq ($(strip $(.TARGETS)),)
771__E
772                }
773               
774                # run make for things we require
775                for my $dep (@all_deps_for_module)
776                {
777                        my $dep_target = "";
778                        if ($dep =~ m|^lib/(.*)|)
779                        {
780                                $dep_target = "\$(OUTBASE)/$dep/$1.a";
781                        }
782                        elsif ($dep =~ m|^.*/(.*)|)
783                        {
784                                $dep_target = "\$(OUTBASE)/$dep/$1$platform_exe_ext";
785                        }
786                        else
787                        {
788                                $dep_target = "lib$dep.a";
789                        }
790
791                        $deps_makeinfo .= <<EOF;
792        \$(HIDE) ( \\
793                cd ../../$dep; \\
794                \$(MAKE) $sub_make_options -q \$(DEPENDMAKEFLAGS) -D NODEPS $dep_target \\
795                || \$(MAKE) $sub_make_options \$(DEPENDMAKEFLAGS) -D NODEPS $dep_target \\
796        )
797EOF
798                }
799
800                $deps_makeinfo .= ".\tendif\n.endif\n\n";
801        }
802        print MAKE $deps_makeinfo if $bsd_make;
803       
804        # get the list of library things to add -- in order of dependency
805        # so things link properly
806        my @lib_files;
807        foreach my $dep (reverse @all_deps_for_module)
808        {
809                if ($dep =~ m|^lib\/(.+)$|)
810                {
811                        push @lib_files, "\$(OUTBASE)/$dep/$1.a";
812                }
813                elsif ($dep =~ m|^([^/]+)$|)
814                {
815                        push @lib_files, "../../$dep/lib$1.a";
816                }
817        }
818
819        # need to see if the extra makefile fragments require extra object files
820        # or include any more makefiles
821        my @objs = @obj_base;
822        my @makefile_includes;
823       
824        additional_objects_from_make_fragment("$mod/Makefile.extra", \@objs, \@makefile_includes);
825        additional_objects_from_make_fragment("$mod/Makefile.extra.$build_os", \@objs, \@makefile_includes);
826
827        my $o_file_list = join(' ',map {'$(OUTDIR)/'.$_.'.o'} sort @objs);
828
829        if ($has_deps and not $bsd_make)
830        {
831                print MAKE ".PHONY: all\n" .
832                        "all: dep_modules $end_target\n\n";
833        }
834
835        print MAKE $end_target,': ',$o_file_list;
836        print MAKE " @lib_files" unless $target_is_library;
837        print MAKE "\n";
838       
839        if ($target_windows)
840        {
841                foreach my $dep (@all_deps_for_module)
842                {
843                        my $res_list = $module_resources_win32{$dep};
844                        next unless $res_list;
845                        $o_file_list .= ' '.join(' ',
846                                map {'$(OUTBASE)/'.$dep."/$_"} @$res_list);
847                }
848        }
849
850        # stuff to make the final target...
851        if($target_is_library)
852        {
853                # make a library archive...
854                print MAKE "\t\$(HIDE) (echo -n > $end_target; rm $end_target)\n";
855                print MAKE "\t\$(_AR) cq $end_target $o_file_list\n";
856                print MAKE "\t\$(_RANLIB) $end_target\n";
857        }
858        else
859        {
860                # work out library options
861                # need to be... least used first, in absolute order they appear in the modules.txt file
862                my @libops;
863               
864                sub libops_fill
865                {
866                        my ($module, $libops_ref) = @_;
867                       
868                        my $library_link_opts = $module_library_link_opts{$module};
869                        if ($library_link_opts)
870                        {
871                                push @$libops_ref, @$library_link_opts;
872                        }
873                       
874                        my $deps = $module_dependency{$module};
875                        foreach my $dep (@$deps)
876                        {
877                                libops_fill($dep, $libops_ref);
878                        }
879                }
880               
881                libops_fill($mod,\@libops);
882               
883                my $lo = '';
884                my %ldone;
885                for(@libops)
886                {
887                        next if exists $ldone{$_};
888                        $lo .= ' '.$_;
889                        $ldone{$_} = 1;
890                }
891       
892                # link line...
893                print MAKE "\t\$(_LINK) \$(LDFLAGS) $link_line_extra " .
894                        "-o $end_target $o_file_list " .
895                        "@lib_files $lo $platform_lib_files\n";
896        }
897
898        # tests need to copy the test file over
899        if($type eq 'test')
900        {
901                print MAKE "\tcp _t \$(OUTDIR)/t\n\tchmod u+x \$(OUTDIR)/t\n";
902                print MAKE "\tcp _t-gdb \$(OUTDIR)/t-gdb\n\tchmod u+x \$(OUTDIR)/t-gdb\n";
903        }
904
905        # dependency line?
906        print MAKE "\n";
907
908        # module dependencies for GNU make?
909        print MAKE $deps_makeinfo if !$bsd_make;
910       
911        # print the rest of the file
912        print MAKE $make,"\n";
913       
914        # and a clean target
915        print MAKE <<EOF;
916clean:
917        -rm -rf \$(OUTDIR)/*
918.       ifndef SUBCLEAN
919EOF
920        for my $dep (@all_deps_for_module)
921        {
922                print MAKE "\t\$(HIDE) (cd ../../$dep; \$(MAKE) \$(DEPENDMAKEFLAGS) -D SUBCLEAN clean)\n";
923        }
924        print MAKE ".\tendif\n";
925       
926        # include any extra stuff
927        print MAKE "\n\n";
928        if(-e "$mod/Makefile.extra")
929        {
930                print MAKE ".include <Makefile.extra>\n\n";
931        }
932        if(-e "$mod/Makefile.extra.$build_os")
933        {
934                print MAKE ".include <Makefile.extra.$build_os>\n\n";
935        }
936        for(@makefile_includes)
937        {
938                print MAKE ".include <$_>\n\n";
939        }
940       
941        # and finally a target for rebuilding the build system
942        print MAKE "\nbuildsystem:\n\t(cd ../..; perl ./infrastructure/makebuildenv.pl $makebuildenv_args)\n\n";
943       
944        close MAKE;
945
946        if(!$bsd_make)
947        {
948                # need to post process this into a GNU makefile
949                open MAKE,">$mod/Makefile";
950                open MAKEB,"$mod/MakefileX";
951
952                while(<MAKEB>)
953                {
954                        s/\A\.\s*(ifdef|else|endif|ifndef)/$1/;
955                        s/\A\.\s*include\s+<(.+?)>/include $1/;
956                        s/-D\s+(\w+)/$1=1/g;
957                        print MAKE;
958                }
959
960                close MAKEB;
961                close MAKE;
962                unlink "$mod/MakefileX";
963        }
964}
965
966print "\nType 'cd <module_dir>; $make_command' to build a module\n\n";
967
968if($modules_omitted)
969{
970        print "\nNOTE: Some modules have been omitted on this platform\n\n"
971}
972
973sub insert_dep
974{
975        my ($h,$dep_r) = @_;
976       
977        # stop random recusion
978        return if exists $$dep_r{$h};
979       
980        # insert more depencies
981        insert_dep($_,$dep_r) for keys %{$header_dependency{$h}};
982
983        # mark this one as a dependency
984        $$dep_r{$h} = 1;
985}
986
987
988sub additional_objects_from_make_fragment
989{
990        my ($fn,$objs_r,$include_r) = @_;
991       
992        if(-e $fn)
993        {
994                open FL,$fn or die "Can't open $fn";
995               
996                while(<FL>)
997                {
998                        chomp;
999                        if(m/link-extra:\s*(.+)\Z/)
1000                        {
1001                                my $extra = $1;
1002                                do
1003                                {
1004                                        my @o = split /\s+/, $extra;
1005                                        for(@o)
1006                                        {
1007                                                push @$objs_r,$1 if m/\A(.+)\.o\Z/;
1008                                        }
1009                                        last unless $extra =~ m'\\$';
1010                                        $extra = <FL>;
1011                                }
1012                                while(1);
1013                        }
1014                        elsif(m/include-makefile:\s*(\S+)/)
1015                        {
1016                                push @$include_r,$1
1017                        }
1018                }
1019               
1020                close FL;
1021        }
1022}
1023
1024
1025sub ignore_module
1026{
1027        exists $env_flags{'IGNORE_'.$_[0]}
1028}
Note: See TracBrowser for help on using the repository browser.