diff options
Diffstat (limited to 'source4/build/smb_build')
-rw-r--r-- | source4/build/smb_build/README.txt | 83 | ||||
-rw-r--r-- | source4/build/smb_build/TODO | 25 | ||||
-rw-r--r-- | source4/build/smb_build/config_mk.pm | 284 | ||||
-rwxr-xr-x | source4/build/smb_build/dot.pl | 63 | ||||
-rw-r--r-- | source4/build/smb_build/input.pm | 277 | ||||
-rw-r--r-- | source4/build/smb_build/main.pl | 104 | ||||
-rw-r--r-- | source4/build/smb_build/makefile.pm | 281 | ||||
-rw-r--r-- | source4/build/smb_build/output.pm | 172 | ||||
-rw-r--r-- | source4/build/smb_build/summary.pm | 79 |
9 files changed, 1368 insertions, 0 deletions
diff --git a/source4/build/smb_build/README.txt b/source4/build/smb_build/README.txt new file mode 100644 index 0000000000..eac3905cce --- /dev/null +++ b/source4/build/smb_build/README.txt @@ -0,0 +1,83 @@ +The Samba Build System
+======================
+
+The build system basically has two main parts: the autoconf-generated
+shell scripts which check for availability of functions and libraries
+which is stored in the .m4 files and the information about the various
+subsystems which is stored in the .mk files.
+
+Object Types
+------------
+the build system knows about the following object types
+
+SUBSYSTEM:
+ a SUBSYSTEM is basicly a collection of functions, which provide an
+ an generic API for a specific problem (e.g. libldb provides an api
+ for gneric ldb databases. libldb_plugin provides a generic api
+ for calling ldb plugins, so 'libldb' and 'libldb_plugin' are subsystems)
+
+MODULE:
+ a MODULE is a specify implementation of a API provided by a SUBSYSTEM.
+ (e.g. 'libldb_tdb' and 'libldb_ldap' are implementations of the subsystem 'libldb' API,
+ and 'libldb_plugin_timestamp' is a module of the 'libldb_plugin' subsystem)
+
+EXT_LIB:
+ an EXT_LIB is an external library which is needed by a SUBSYSTEM, MODULE, BINARY or LIBRARY.
+ (e.g. 'gtk' or 'KRB5')
+
+BINARY:
+ a BINARY means a executable binary file.
+ (e.g. 'smbtorture' or 'ldbedit')
+ a BINARY typically has only commandline handling and basic
+ functionality code in it and depends on the functions of
+ SUBSYSTEM's (REQUIRED_SUBSYSTEMS).
+
+LIBRARY:
+ a LIBRARY means a static and/or shared library,
+ which depends on the used OS.
+ (e.g. for libldb 'libldb.so', 'libldb.so.0' 'libldb.so.0.0.1'
+ and libldb.a are created on linux)
+ a LIBRARY typicly has only glue code in it and depends on
+ SUBSYSTEM's (REQUIRED_SUBSYSTEMS).
+
+File summary:
+-------------
+public.m4 - public M4 macros of the build system
+config_mk.pm - Support for reading .mk files
+dot.pm - Support for generating .dot files for analysis of dependencies
+input.pm - Input validation
+main.pm - Main
+makefile.pm - Makefile generation
+output.pm - Dependency calculation
+
+Layout
+-------
+
+Toplevel file: configure.in
+- included by autogen.sh: aclocal.m4
+ which includes the SMB_YXZ*() macros
+
+- default tests of the build system
+ are in build/smb_build/check_*.m4
+ (mostly compiler and basic C type and function
+ checks)
+
+- subsystem specific stuff should be included by 'SMB_INCLUDE_M4()'
+
+
+Generating the configure file
+-------------------------
+you need to rerun ./autogen.sh when 'configure.in' or any
+'.m4' file was modified, then you need to rerun configure.
+
+
+Generating config.status
+-----------------------------
+you need to run ./config.status (or 'configure') after a '.mk'
+file was changed.
+
+
+Examples
+--------
+for now please take a look at the .m4 and .mk files
+you find in the source tree, they should be a good reference to start.
diff --git a/source4/build/smb_build/TODO b/source4/build/smb_build/TODO new file mode 100644 index 0000000000..adfe17d423 --- /dev/null +++ b/source4/build/smb_build/TODO @@ -0,0 +1,25 @@ +- use pkg-config files in the buildsystem? +- let the build system implement some make functions($(patsubst),$(wildcard),...) and use our own implementations where `make' does not support them +- include extra_flags.txt using Makefile construction if + supported by current make +- fix shared module loading for selftest during builds without install +- remove recursive dependency between LIBSOCKET, LIBCLI_NBT and LIBCLI_RESOLVE +- clearer distinction between dcerpc and ndr. seperate interface tables? Maybe get rid of + NDR's table altogether and use dlopen/dlsym ? +- saner names for: + libcli.so.0.0.1 (rename to libsmb?) + libcli_cldap.so.0.0.1 (rename to libcldap?) + libcli_nbt.so.0.0.1 (rename to libnbt?) + libcli_wrepl.so.0.0.1 (rename to libwrepl?) +- generate headermap.txt + +set of test scripts that check the code: +- configure_check_unused.pl +- find_unused_macros.pl +- find_unused_makefilevars.pl +- find_unused_options.sh +- findstatic.pl +- minimal_includes.pl +- check dependencies based on #include lines ? +- check whether private headers are not used outside their own subsystem +- undocumented (no manpage) installed binaries diff --git a/source4/build/smb_build/config_mk.pm b/source4/build/smb_build/config_mk.pm new file mode 100644 index 0000000000..8c7d75221c --- /dev/null +++ b/source4/build/smb_build/config_mk.pm @@ -0,0 +1,284 @@ +# Samba Build System +# - config.mk parsing functions +# +# Copyright (C) Stefan (metze) Metzmacher 2004 +# Copyright (C) Jelmer Vernooij 2005 +# Released under the GNU GPL +# + +package smb_build::config_mk; +use smb_build::input; +use File::Basename; + +use strict; + +my $section_types = { + "EXT_LIB" => { + "LIBS" => "list", + "CFLAGS" => "list", + "CPPFLAGS" => "list", + "LDFLAGS" => "list", + }, + "PYTHON" => { + "LIBRARY_REALNAME" => "string", + "PRIVATE_DEPENDENCIES" => "list", + "PUBLIC_DEPENDENCIES" => "list", + "ENABLE" => "bool", + "LDFLAGS" => "list", + }, + "SUBSYSTEM" => { + "PRIVATE_DEPENDENCIES" => "list", + "PUBLIC_DEPENDENCIES" => "list", + + "ENABLE" => "bool", + + "CFLAGS" => "list", + "LDFLAGS" => "list", + "STANDARD_VISIBILITY" => "string", + "INIT_FUNCTION_SENTINEL" => "string" + }, + "MODULE" => { + "SUBSYSTEM" => "string", + + "INIT_FUNCTION" => "string", + + "PRIVATE_DEPENDENCIES" => "list", + + "ALIASES" => "list", + + "ENABLE" => "bool", + + "OUTPUT_TYPE" => "list", + + "CFLAGS" => "list" + }, + "BINARY" => { + + "PRIVATE_DEPENDENCIES" => "list", + + "ENABLE" => "bool", + + "INSTALLDIR" => "string", + "LDFLAGS" => "list", + "STANDARD_VISIBILITY" => "string", + + "USE_HOSTCC" => "bool" + }, + "LIBRARY" => { + "LIBRARY_REALNAME" => "string", + + "INIT_FUNCTION_TYPE" => "string", + "INIT_FUNCTION_SENTINEL" => "string", + "OUTPUT_TYPE" => "list", + + "PRIVATE_DEPENDENCIES" => "list", + "PUBLIC_DEPENDENCIES" => "list", + + "ENABLE" => "bool", + + "CFLAGS" => "list", + "LDFLAGS" => "list", + "STANDARD_VISIBILITY" => "string" + } +}; + +use vars qw(@parsed_files); + +@parsed_files = (); + +sub _read_config_file($$$) +{ + use Cwd; + + my ($srcdir, $builddir, $filename) = @_; + my @dirlist; + + # We need to change our working directory because config.mk files can + # give shell commands as the argument to "include". These shell + # commands can take arguments that are relative paths and we don't have + # a way of sensibly rewriting these. + my $cwd = getcwd; + chomp $cwd; + + if ($srcdir ne $builddir) { + # Push the builddir path on the front, so we prefer builddir + # to srcdir when the file exists in both. + @dirlist = ($builddir, $srcdir); + } else { + @dirlist = ($srcdir); + } + + foreach my $d (@dirlist) { + my @lines; + my $basedir; + + chdir $cwd; + chdir $d; + + # We need to catch the exception from open in the case where + # the filename is actually a shell pipeline. Why is this + # different to opening a regular file? Because this is perl! + eval { + open(CONFIG_MK, "./$filename"); + @lines = <CONFIG_MK>; + close(CONFIG_MK); + }; + + chdir $cwd; + next unless (@lines); + + # I blame abartlett for this crazy hack -- jpeach + if ($filename =~ /\|$/) { + $basedir = $builddir; + } else { + $basedir = dirname($filename); + push(@parsed_files, $filename); + } + $basedir =~ s!^($builddir|$srcdir)[/]!!; + return ($filename, $basedir, @lines); + } + + chdir $cwd; + return; +} + +########################################################### +# The parsing function which parses the file +# +# $result = _parse_config_mk($input, $srcdir, $builddir, $filename) +# +# $filename - the path of the config.mk file +# which should be parsed +sub run_config_mk($$$$) +{ + sub run_config_mk($$$$); + my ($input, $srcdir, $builddir, $filename) = @_; + my $result; + my $linenum = -1; + my $infragment = 0; + my $section = "GLOBAL"; + my $makefile = ""; + + my $basedir; + + my $parsing_file; + my @lines; + + $ENV{builddir} = $builddir; + $ENV{srcdir} = $srcdir; + + ($parsing_file, $basedir, @lines) = + _read_config_file($srcdir, $builddir, $filename); + + die ("$0: can't open '$filename'") + unless ($parsing_file and $basedir and @lines); + + my $line = ""; + my $prev = ""; + + # Emit a line that lets us match up final makefile output with the + # corresponding input files. The curlies are so you can match the + # BEGIN/END pairs in a text editor. + $makefile .= "# BEGIN{ $parsing_file\n"; + + foreach (@lines) { + $linenum++; + + # lines beginning with '#' are ignored + next if (/^\#.*$/); + + if (/^(.*)\\$/) { + $prev .= $1; + next; + } else { + $line = "$prev$_"; + $prev = ""; + } + + if ($line =~ /^\[([-a-zA-Z0-9_.:]+)\][\t ]*$/) + { + $section = $1; + $infragment = 0; + + $result->{$section}{EXISTS}{KEY} = "EXISTS"; + $result->{$section}{EXISTS}{VAL} = 1; + next; + } + + # include + if ($line =~ /^mkinclude (.*)$/) { + my $subfile= $1; + my $subdir = dirname($filename); + $subdir =~ s/^\.$//g; + $subdir =~ s/^\.\///g; + $subdir .= "/" if ($subdir ne ""); + $makefile .= "basedir := $subdir\n"; + $makefile .= run_config_mk($input, $srcdir, $builddir, $subdir.$subfile); + next; + } + + # empty line + if ($line =~ /^[ \t]*$/) { + $section = "GLOBAL"; + if ($infragment) { $makefile.="\n"; } + next; + } + + # global stuff is considered part of the makefile + if ($section eq "GLOBAL") { + if (!$infragment) { $makefile.="\n"; } + $makefile .= $line; + $infragment = 1; + next; + } + + # Assignment + if ($line =~ /^([a-zA-Z0-9_]+)[\t ]*=(.*)$/) { + $result->{$section}{$1}{VAL} = $2; + $result->{$section}{$1}{KEY} = $1; + + next; + } + + die("$parsing_file:$linenum: Bad line"); + } + + $makefile .= "# }END $parsing_file\n"; + + foreach my $section (keys %{$result}) { + my ($type, $name) = split(/::/, $section, 2); + + my $sectype = $section_types->{$type}; + if (not defined($sectype)) { + die($parsing_file.":[".$section."] unknown section type \"".$type."\"!"); + } + + $input->{$name}{NAME} = $name; + $input->{$name}{TYPE} = $type; + $input->{$name}{MK_FILE} = $parsing_file; + $input->{$name}{BASEDIR} = $basedir; + + foreach my $key (values %{$result->{$section}}) { + next if ($key->{KEY} eq "EXISTS"); + $key->{VAL} = smb_build::input::strtrim($key->{VAL}); + my $vartype = $sectype->{$key->{KEY}}; + if (not defined($vartype)) { + die($parsing_file.":[".$section."]: unknown attribute type \"$key->{KEY}\"!"); + } + if ($vartype eq "string") { + $input->{$name}{$key->{KEY}} = $key->{VAL}; + } elsif ($vartype eq "list") { + $input->{$name}{$key->{KEY}} = [smb_build::input::str2array($key->{VAL})]; + } elsif ($vartype eq "bool") { + if (($key->{VAL} ne "YES") and ($key->{VAL} ne "NO")) { + die("Invalid value for bool attribute $key->{KEY}: $key->{VAL} in section $section"); + } + $input->{$name}{$key->{KEY}} = $key->{VAL}; + } + } + } + + return $makefile; +} + +1; diff --git a/source4/build/smb_build/dot.pl b/source4/build/smb_build/dot.pl new file mode 100755 index 0000000000..b30c320c6e --- /dev/null +++ b/source4/build/smb_build/dot.pl @@ -0,0 +1,63 @@ +#!/usr/bin/perl +# Samba4 Dependency Graph Generator +# (C) 2004-2005 Jelmer Vernooij <jelmer@samba.org> +# Published under the GNU GPL + +use strict; +use lib 'build'; +use smb_build::config_mk; + +my $subsys = shift @ARGV; + +sub contains($$) +{ + my ($haystack,$needle) = @_; + foreach (@$haystack) { + return 1 if ($_ eq $needle); + } + return 0; +} + +sub generate($$$) +{ + my ($depend,$only,$name) = @_; + my $res = "digraph $name {\n"; + + foreach my $part (values %{$depend}) { + next if (defined($only) and not contains($only,$part->{NAME})); + foreach my $elem (@{$part->{PUBLIC_DEPENDENCIES}}) { + $res .= "\t\"$part->{NAME}\" -> \"$elem\" [style=filled]; /* public */\n"; + } + foreach my $elem (@{$part->{PRIVATE_DEPENDENCIES}}) { + $res .= "\t\"$part->{NAME}\" -> \"$elem\" [style=dotted]; /* private */\n"; + } + } + + return $res . "}\n"; +} + +my $INPUT = {}; +smb_build::config_mk::run_config_mk($INPUT, '.', '.', "main.mk"); + +my $name = "samba4"; + +my $only; +if (defined($subsys)) { + my $DEPEND = smb_build::input::check($INPUT, \%config::enabled, + "MERGED_OBJ", "SHARED_LIBRARY", "SHARED_LIBRARY"); + + die("No such subsystem $subsys") unless (defined($DEPEND->{$subsys})); + + $only = $DEPEND->{$subsys}->{UNIQUE_DEPENDENCIES_ALL}; + push (@$only, "$subsys"); + + $name = $subsys; +} + +my $fname = "$name-deps.dot"; +print __FILE__.": creating $fname\n"; +open DOTTY, ">$fname"; +print DOTTY generate($INPUT, $only, $name); +close DOTTY; + +1; diff --git a/source4/build/smb_build/input.pm b/source4/build/smb_build/input.pm new file mode 100644 index 0000000000..1696a364b2 --- /dev/null +++ b/source4/build/smb_build/input.pm @@ -0,0 +1,277 @@ +# Samba Build System +# - the input checking functions +# +# Copyright (C) Stefan (metze) Metzmacher 2004 +# Copyright (C) Jelmer Vernooij 2004 +# Released under the GNU GPL + +use strict; +package smb_build::input; +use File::Basename; + +sub strtrim($) +{ + $_ = shift; + s/^[\t\n ]*//g; + s/[\t\n ]*$//g; + return $_; +} + +sub str2array($) +{ + $_ = shift; + s/^[\t\n ]*//g; + s/[\t\n ]*$//g; + s/([\t\n ]+)/ /g; + + return () if (length($_)==0); + return split /[ \t\n]/; +} + +sub add_libreplace($) +{ + my ($part) = @_; + + return if ($part->{NAME} eq "LIBREPLACE"); + return if ($part->{NAME} eq "LIBREPLACE_HOSTCC"); + return if ($part->{NAME} eq "REPLACE_READDIR"); + + foreach my $n (@{$part->{PRIVATE_DEPENDENCIES}}) { + return if ($n eq "LIBREPLACE"); + return if ($n eq "LIBREPLACE_HOSTCC"); + } + foreach my $n (@{$part->{PUBLIC_DEPENDENCIES}}) { + return if ($n eq "LIBREPLACE"); + return if ($n eq "LIBREPLACE_HOSTCC"); + } + + if (defined($part->{USE_HOSTCC}) && $part->{USE_HOSTCC} eq "YES") { + unshift (@{$part->{PRIVATE_DEPENDENCIES}}, "LIBREPLACE_HOSTCC"); + } else { + unshift (@{$part->{PRIVATE_DEPENDENCIES}}, "LIBREPLACE"); + } +} + +sub check_subsystem($$$) +{ + my ($INPUT, $subsys, $default_ot) = @_; + return if ($subsys->{ENABLE} ne "YES"); + + unless (defined($subsys->{OUTPUT_TYPE})) { $subsys->{OUTPUT_TYPE} = $default_ot; } + unless (defined($subsys->{INIT_FUNCTION_TYPE})) { $subsys->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; } + unless (defined($subsys->{INIT_FUNCTION_SENTINEL})) { $subsys->{INIT_FUNCTION_SENTINEL} = "NULL"; } +} + +sub check_module($$$) +{ + my ($INPUT, $mod, $default_ot) = @_; + + die("Module $mod->{NAME} does not have a SUBSYSTEM set") if not defined($mod->{SUBSYSTEM}); + + if (not exists($INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTIONS})) { + $INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTIONS} = []; + } + + if (!(defined($INPUT->{$mod->{SUBSYSTEM}}))) { + die("Unknown subsystem $mod->{SUBSYSTEM} for module $mod->{NAME}"); + } + + if ($INPUT->{$mod->{SUBSYSTEM}} eq "NO") { + warn("Disabling module $mod->{NAME} because subsystem $mod->{SUBSYSTEM} is disabled"); + $mod->{ENABLE} = "NO"; + return; + } + + return if ($mod->{ENABLE} ne "YES"); + + if (exists($INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTION_TYPE})) { + $mod->{INIT_FUNCTION_TYPE} = $INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTION_TYPE}; + } else { + $mod->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; + } + + unless (defined($mod->{INIT_FUNCTION_SENTINEL})) { $mod->{INIT_FUNCTION_SENTINEL} = "NULL"; } + + if (not defined($mod->{OUTPUT_TYPE})) { + if ((not defined($INPUT->{$mod->{SUBSYSTEM}}->{TYPE})) or + $INPUT->{$mod->{SUBSYSTEM}}->{TYPE} eq "EXT_LIB") { + $mod->{OUTPUT_TYPE} = undef; + } else { + $mod->{OUTPUT_TYPE} = $default_ot; + } + } + + if (grep(/SHARED_LIBRARY/, @{$mod->{OUTPUT_TYPE}})) { + my $sane_subsystem = lc($mod->{SUBSYSTEM}); + $sane_subsystem =~ s/^lib//; + $mod->{INSTALLDIR} = "MODULESDIR/$sane_subsystem"; + push (@{$mod->{PUBLIC_DEPENDENCIES}}, $mod->{SUBSYSTEM}); + add_libreplace($mod); + } + if (grep(/MERGED_OBJ/, @{$mod->{OUTPUT_TYPE}})) { + push (@{$INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTIONS}}, $mod->{INIT_FUNCTION}) if defined($mod->{INIT_FUNCTION}); + push (@{$INPUT->{$mod->{SUBSYSTEM}}{PRIVATE_DEPENDENCIES}}, $mod->{NAME}); + } +} + +sub check_library($$$) +{ + my ($INPUT, $lib, $default_ot) = @_; + + return if ($lib->{ENABLE} ne "YES"); + + unless (defined($lib->{OUTPUT_TYPE})) { $lib->{OUTPUT_TYPE} = $default_ot; } + + unless (defined($lib->{INIT_FUNCTION_TYPE})) { $lib->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; } + unless (defined($lib->{INIT_FUNCTION_SENTINEL})) { $lib->{INIT_FUNCTION_SENTINEL} = "NULL"; } + unless (defined($lib->{INSTALLDIR})) { $lib->{INSTALLDIR} = "LIBDIR"; } + + add_libreplace($lib); +} + +sub check_python($$$) +{ + my ($INPUT, $python, $default_ot) = @_; + + return if ($INPUT->{LIBPYTHON}{ENABLE} ne "YES"); + + $python->{INSTALLDIR} = "PYTHONDIR"; + unless (defined($python->{CFLAGS})) { $python->{CFLAGS} = []; } + my $basename = $python->{NAME}; + $basename =~ s/^python_//g; + unless (defined($python->{LIBRARY_REALNAME})) { + $python->{LIBRARY_REALNAME} = "$basename.\$(SHLIBEXT)"; + } + $python->{INIT_FUNCTION} = "{ (char *)\"$basename\", init$basename }"; + push (@{$python->{CFLAGS}}, "\$(EXT_LIB_PYTHON_CFLAGS)"); + + $python->{SUBSYSTEM} = "LIBPYTHON"; + + check_module($INPUT, $python, $default_ot); +} + +sub check_binary($$) +{ + my ($INPUT, $bin) = @_; + + return if ($bin->{ENABLE} ne "YES"); + + ($bin->{BINARY} = (lc $bin->{NAME})) if not defined($bin->{BINARY}); + unless (defined($bin->{INIT_FUNCTION_SENTINEL})) { $bin->{INIT_FUNCTION_SENTINEL} = "NULL"; } + unless (defined($bin->{INIT_FUNCTION_TYPE})) { $bin->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; } + + $bin->{OUTPUT_TYPE} = ["BINARY"]; + add_libreplace($bin); +} + +sub add_implicit($$) +{ + my ($INPUT, $n) = @_; + + $INPUT->{$n}->{TYPE} = "MAKE_RULE"; + $INPUT->{$n}->{NAME} = $n; + $INPUT->{$n}->{OUTPUT_TYPE} = undef; + $INPUT->{$n}->{LIBS} = ["\$(".uc($n)."_LIBS)"]; + $INPUT->{$n}->{LDFLAGS} = ["\$(".uc($n)."_LDFLAGS)"]; + $INPUT->{$n}->{CFLAGS} = ["\$(".uc($n)."_CFLAGS)"]; + $INPUT->{$n}->{CPPFLAGS} = ["\$(".uc($n)."_CPPFLAGS)"]; + $INPUT->{$n}->{ENABLE} = "YES"; +} + +sub calc_unique_deps($$$$$$$$) +{ + sub calc_unique_deps($$$$$$$$); + my ($name, $INPUT, $deps, $udeps, $withlibs, $forward, $pubonly, $busy) = @_; + + foreach my $n (@$deps) { + add_implicit($INPUT, $n) unless (defined($INPUT->{$n}) and defined($INPUT->{$n}->{TYPE})); + my $dep = $INPUT->{$n}; + if (grep (/^$n$/, @$busy)) { + next if (@{$dep->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ"); + die("Recursive dependency: $n, list: " . join(',', @$busy)); + } + next if (grep /^$n$/, @$udeps); + + push (@{$udeps}, $n) if $forward; + + if (defined ($dep->{OUTPUT_TYPE}) && + ($withlibs or + (@{$dep->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ") or + (@{$dep->{OUTPUT_TYPE}}[0] eq "STATIC_LIBRARY"))) { + push (@$busy, $n); + calc_unique_deps($n, $INPUT, $dep->{PUBLIC_DEPENDENCIES}, $udeps, $withlibs, $forward, $pubonly, $busy); + calc_unique_deps($n, $INPUT, $dep->{PRIVATE_DEPENDENCIES}, $udeps, $withlibs, $forward, $pubonly, $busy) unless $pubonly; + pop (@$busy); + } + + unshift (@{$udeps}, $n) unless $forward; + } +} + +sub check($$$$$) +{ + my ($INPUT, $enabled, $subsys_ot, $lib_ot, $module_ot) = @_; + + foreach my $part (values %$INPUT) { + if (defined($enabled->{$part->{NAME}})) { + $part->{ENABLE} = $enabled->{$part->{NAME}}; + next; + } + + unless(defined($part->{ENABLE})) { + if ($part->{TYPE} eq "EXT_LIB") { + $part->{ENABLE} = "NO"; + } else { + $part->{ENABLE} = "YES"; + } + } + } + + foreach my $part (values %$INPUT) { + $part->{LINK_FLAGS} = []; + $part->{FULL_OBJ_LIST} = ["\$($part->{NAME}_OBJ_FILES)"]; + + if ($part->{TYPE} eq "SUBSYSTEM") { + check_subsystem($INPUT, $part, $subsys_ot); + } elsif ($part->{TYPE} eq "MODULE") { + check_module($INPUT, $part, $module_ot); + } elsif ($part->{TYPE} eq "LIBRARY") { + check_library($INPUT, $part, $lib_ot); + } elsif ($part->{TYPE} eq "BINARY") { + check_binary($INPUT, $part); + } elsif ($part->{TYPE} eq "PYTHON") { + check_python($INPUT, $part, $module_ot); + } elsif ($part->{TYPE} eq "EXT_LIB") { + } else { + die("Unknown type $part->{TYPE}"); + } + } + + foreach my $part (values %$INPUT) { + if (defined($part->{INIT_FUNCTIONS})) { + push (@{$part->{LINK_FLAGS}}, "\$(DYNEXP)"); + } + } + + foreach my $part (values %$INPUT) { + $part->{UNIQUE_DEPENDENCIES_LINK} = []; + calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_LINK}, 0, 0, 0, []); + calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_LINK}, 0, 0, 0, []); + } + + foreach my $part (values %$INPUT) { + $part->{UNIQUE_DEPENDENCIES_COMPILE} = []; + calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_COMPILE}, 1, 1, 1, []); + calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_COMPILE}, 1, 1, 1, []); + } + + foreach my $part (values %$INPUT) { + $part->{UNIQUE_DEPENDENCIES_ALL} = []; + calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_ALL}, 1, 0, 0, []); + calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_ALL}, 1, 0, 0, []); + } + + return $INPUT; +} + +1; diff --git a/source4/build/smb_build/main.pl b/source4/build/smb_build/main.pl new file mode 100644 index 0000000000..3c84a91a59 --- /dev/null +++ b/source4/build/smb_build/main.pl @@ -0,0 +1,104 @@ +# Samba Build System +# - the main program +# +# Copyright (C) Stefan (metze) Metzmacher 2004 +# Copyright (C) Jelmer Vernooij 2005 +# Released under the GNU GPL + +use smb_build::makefile; +use smb_build::input; +use smb_build::config_mk; +use smb_build::output; +use smb_build::summary; +use smb_build::config; +use Getopt::Long; +use strict; + +my $output_file = "data.mk"; + +my $result = GetOptions ( + 'output=s' => \$output_file); + +if (not $result) { + exit(1); +} + +my $input_file = shift @ARGV; + +my $INPUT = {}; +my $mkfile = smb_build::config_mk::run_config_mk($INPUT, $config::config{srcdir}, $config::config{builddir}, $input_file); + +my $subsys_output_type = ["MERGED_OBJ"]; + +my $library_output_type; +my $useshared = (defined($ENV{USESHARED})?$ENV{USESHARED}:$config::config{USESHARED}); + +if ($useshared eq "true") { + $library_output_type = ["SHARED_LIBRARY", "MERGED_OBJ"]; +} else { + $library_output_type = ["MERGED_OBJ"]; + push (@$library_output_type, "SHARED_LIBRARY") if + ($config::config{BLDSHARED} eq "true") +} + +my $module_output_type; +if ($useshared eq "true") { + $module_output_type = ["SHARED_LIBRARY"]; +} else { + $module_output_type = ["MERGED_OBJ"]; +} + +my $DEPEND = smb_build::input::check($INPUT, \%config::enabled, + $subsys_output_type, + $library_output_type, + $module_output_type); +my $OUTPUT = output::create_output($DEPEND, \%config::config); +my $mkenv = new smb_build::makefile(\%config::config, $mkfile); + +my $shared_libs_used = 0; +foreach my $key (values %$OUTPUT) { + next if ($key->{ENABLE} ne "YES"); + push(@{$mkenv->{all_objs}}, "\$($key->{NAME}_OBJ_FILES)"); +} + +foreach my $key (values %$OUTPUT) { + next unless defined $key->{OUTPUT_TYPE}; + + $mkenv->StaticLibraryPrimitives($key) if grep(/STATIC_LIBRARY/, @{$key->{OUTPUT_TYPE}}); + $mkenv->MergedObj($key) if grep(/MERGED_OBJ/, @{$key->{OUTPUT_TYPE}}); + $mkenv->SharedLibraryPrimitives($key) if ($key->{TYPE} eq "LIBRARY") and + grep(/SHARED_LIBRARY/, @{$key->{OUTPUT_TYPE}}); + if ($key->{TYPE} eq "LIBRARY" and + ${$key->{OUTPUT_TYPE}}[0] eq "SHARED_LIBRARY") { + $shared_libs_used = 1; + } + if ($key->{TYPE} eq "MODULE" and @{$key->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ" and defined($key->{INIT_FUNCTION})) { + $mkenv->output("$key->{SUBSYSTEM}_INIT_FUNCTIONS += $key->{INIT_FUNCTION},\n"); + } + $mkenv->CFlags($key); +} + +foreach my $key (values %$OUTPUT) { + next unless defined $key->{OUTPUT_TYPE}; + + $mkenv->Integrated($key) if grep(/INTEGRATED/, @{$key->{OUTPUT_TYPE}}); +} + +foreach my $key (values %$OUTPUT) { + next unless defined $key->{OUTPUT_TYPE}; + $mkenv->StaticLibrary($key) if grep(/STATIC_LIBRARY/, @{$key->{OUTPUT_TYPE}}); + + $mkenv->SharedLibrary($key) if ($key->{TYPE} eq "LIBRARY") and + grep(/SHARED_LIBRARY/, @{$key->{OUTPUT_TYPE}}); + $mkenv->SharedModule($key) if ($key->{TYPE} eq "MODULE" and + grep(/SHARED_LIBRARY/, @{$key->{OUTPUT_TYPE}})); + $mkenv->PythonModule($key) if ($key->{TYPE} eq "PYTHON"); + $mkenv->Binary($key) if grep(/BINARY/, @{$key->{OUTPUT_TYPE}}); + $mkenv->InitFunctions($key) if defined($key->{INIT_FUNCTIONS}); +} + +$mkenv->write($output_file); + +summary::show($OUTPUT, \%config::config); + +1; diff --git a/source4/build/smb_build/makefile.pm b/source4/build/smb_build/makefile.pm new file mode 100644 index 0000000000..d9cbca0614 --- /dev/null +++ b/source4/build/smb_build/makefile.pm @@ -0,0 +1,281 @@ +# Samba Build System +# - create output for Makefile +# +# Copyright (C) Stefan (metze) Metzmacher 2004 +# Copyright (C) Jelmer Vernooij 2005 +# Released under the GNU GPL + +package smb_build::makefile; +use smb_build::output; +use File::Basename; +use strict; + +use Cwd 'abs_path'; + +sub new($$$) +{ + my ($myname, $config, $mkfile) = @_; + my $self = {}; + + bless($self, $myname); + + $self->_set_config($config); + + $self->{output} = ""; + + $self->output("################################################\n"); + $self->output("# Autogenerated by build/smb_build/makefile.pm #\n"); + $self->output("################################################\n"); + $self->output("\n"); + $self->output($mkfile); + + return $self; +} + +sub _set_config($$) +{ + my ($self, $config) = @_; + + $self->{config} = $config; + + if (not defined($self->{config}->{srcdir})) { + $self->{config}->{srcdir} = '.'; + } + + if (not defined($self->{config}->{builddir})) { + $self->{config}->{builddir} = '.'; + } + + if ($self->{config}->{prefix} eq "NONE") { + $self->{config}->{prefix} = $self->{config}->{ac_default_prefix}; + } + + if ($self->{config}->{exec_prefix} eq "NONE") { + $self->{config}->{exec_prefix} = $self->{config}->{prefix}; + } +} + +sub output($$) +{ + my ($self, $text) = @_; + + $self->{output} .= $text; +} + +sub _prepare_mk_files($) +{ + my $self = shift; + my @tmp = (); + + foreach (@smb_build::config_mk::parsed_files) { + s/ .*$//g; + push (@tmp, $_); + } + + $self->output("MK_FILES = " . array2oneperline(\@tmp) . "\n"); +} + +sub array2oneperline($) +{ + my $array = shift; + my $output = ""; + + foreach (@$array) { + next unless defined($_); + + $output .= " \\\n\t\t$_"; + } + + return $output; +} + +sub _prepare_list($$$) +{ + my ($self,$ctx,$var) = @_; + my @tmparr = (); + + push(@tmparr, @{$ctx->{$var}}) if defined($ctx->{$var}); + + my $tmplist = array2oneperline(\@tmparr); + return if ($tmplist eq ""); + + $self->output("$ctx->{NAME}_$var =$tmplist\n"); +} + +sub PythonModule($$) +{ + my ($self,$ctx) = @_; + + $self->_prepare_list($ctx, "FULL_OBJ_LIST"); + $self->_prepare_list($ctx, "DEPEND_LIST"); + $self->_prepare_list($ctx, "LINK_FLAGS"); + + $self->output("\$(eval \$(call python_c_module_template,$ctx->{LIBRARY_REALNAME},\$($ctx->{NAME}_DEPEND_LIST) \$($ctx->{NAME}_FULL_OBJ_LIST), \$($ctx->{NAME}\_FULL_OBJ_LIST) \$($ctx->{NAME}_LINK_FLAGS)))\n"); +} + +sub SharedModule($$) +{ + my ($self,$ctx) = @_; + + my $sane_subsystem = lc($ctx->{SUBSYSTEM}); + $sane_subsystem =~ s/^lib//; + + $self->output("PLUGINS += $ctx->{SHAREDDIR}/$ctx->{LIBRARY_REALNAME}\n"); + $self->output("\$(eval \$(call shared_module_install_template,$sane_subsystem,$ctx->{LIBRARY_REALNAME}))\n"); + + $self->_prepare_list($ctx, "FULL_OBJ_LIST"); + $self->_prepare_list($ctx, "DEPEND_LIST"); + $self->_prepare_list($ctx, "LINK_FLAGS"); + + if (defined($ctx->{INIT_FUNCTION}) and $ctx->{INIT_FUNCTION_TYPE} =~ /\(\*\)/ and not ($ctx->{INIT_FUNCTION} =~ /\(/)) { + $self->output("\$($ctx->{NAME}_OBJ_FILES): CFLAGS+=-D$ctx->{INIT_FUNCTION}=init_module\n"); + } + + $self->output("\$(eval \$(call shared_module_template,$ctx->{SHAREDDIR}/$ctx->{LIBRARY_REALNAME}, \$($ctx->{NAME}_DEPEND_LIST) \$($ctx->{NAME}_FULL_OBJ_LIST), \$($ctx->{NAME}\_FULL_OBJ_LIST) \$($ctx->{NAME}_LINK_FLAGS)))\n"); + + + if (defined($ctx->{ALIASES})) { + $self->output("\$(eval \$(foreach alias,". join(' ', @{$ctx->{ALIASES}}) . ",\$(call shared_module_alias_template,$ctx->{SHAREDDIR}/$ctx->{LIBRARY_REALNAME},$sane_subsystem,\$(alias))))\n"); + } +} + +sub StaticLibraryPrimitives($$) +{ + my ($self,$ctx) = @_; + + $self->output("$ctx->{NAME}_OUTPUT = $ctx->{OUTPUT}\n"); + $self->_prepare_list($ctx, "FULL_OBJ_LIST"); +} + +sub SharedLibraryPrimitives($$) +{ + my ($self,$ctx) = @_; + + if (not grep(/STATIC_LIBRARY/, @{$ctx->{OUTPUT_TYPE}})) { + $self->output("$ctx->{NAME}_OUTPUT = $ctx->{OUTPUT}\n"); + $self->_prepare_list($ctx, "FULL_OBJ_LIST"); + } +} + +sub SharedLibrary($$) +{ + my ($self,$ctx) = @_; + + $self->output("SHARED_LIBS += $ctx->{RESULT_SHARED_LIBRARY}\n"); + + $self->_prepare_list($ctx, "DEPEND_LIST"); + $self->_prepare_list($ctx, "LINK_FLAGS"); + + $self->output("\$(eval \$(call shared_library_template,$ctx->{RESULT_SHARED_LIBRARY}, \$($ctx->{NAME}_DEPEND_LIST) \$($ctx->{NAME}_FULL_OBJ_LIST), \$($ctx->{NAME}\_FULL_OBJ_LIST) \$($ctx->{NAME}_LINK_FLAGS),$ctx->{SHAREDDIR}/$ctx->{LIBRARY_SONAME},$ctx->{SHAREDDIR}/$ctx->{LIBRARY_DEBUGNAME}))\n"); +} + +sub MergedObj($$) +{ + my ($self, $ctx) = @_; + + $self->output("\$(call partial_link_template, $ctx->{OUTPUT}, \$($ctx->{NAME}_OBJ_FILES))\n"); +} + +sub InitFunctions($$) +{ + my ($self, $ctx) = @_; + $self->output("\$($ctx->{NAME}_OBJ_FILES): CFLAGS+=-DSTATIC_$ctx->{NAME}_MODULES=\"\$($ctx->{NAME}_INIT_FUNCTIONS)$ctx->{INIT_FUNCTION_SENTINEL}\"\n"); +} + +sub StaticLibrary($$) +{ + my ($self,$ctx) = @_; + + $self->output("STATIC_LIBS += $ctx->{RESULT_STATIC_LIBRARY}\n") if ($ctx->{TYPE} eq "LIBRARY"); + $self->output("$ctx->{NAME}_OUTPUT = $ctx->{OUTPUT}\n"); + $self->output("$ctx->{RESULT_STATIC_LIBRARY}: \$($ctx->{NAME}_FULL_OBJ_LIST)\n"); +} + +sub Binary($$) +{ + my ($self,$ctx) = @_; + + unless (defined($ctx->{INSTALLDIR})) { + } elsif ($ctx->{INSTALLDIR} eq "SBINDIR") { + $self->output("\$(eval \$(call sbinary_install_template,$ctx->{RESULT_BINARY}))\n"); + } elsif ($ctx->{INSTALLDIR} eq "BINDIR") { + $self->output("\$(eval \$(call binary_install_template,$ctx->{RESULT_BINARY}))\n"); + } + + $self->_prepare_list($ctx, "FULL_OBJ_LIST"); + $self->_prepare_list($ctx, "DEPEND_LIST"); + $self->_prepare_list($ctx, "LINK_FLAGS"); + + if (defined($ctx->{USE_HOSTCC}) && $ctx->{USE_HOSTCC} eq "YES") { +$self->output("\$(eval \$(call host_binary_link_template, $ctx->{RESULT_BINARY}, \$($ctx->{NAME}_FULL_OBJ_LIST) \$($ctx->{NAME}_DEPEND_LIST), \$($ctx->{NAME}_LINK_FLAGS)))\n"); + } else { +$self->output("\$(eval \$(call binary_link_template, $ctx->{RESULT_BINARY}, \$($ctx->{NAME}_FULL_OBJ_LIST) \$($ctx->{NAME}_DEPEND_LIST), \$($ctx->{NAME}_LINK_FLAGS)))\n"); + } +} + +sub write($$) +{ + my ($self, $file) = @_; + + $self->_prepare_mk_files(); + + $self->output("ALL_OBJS = " . array2oneperline($self->{all_objs}) . "\n"); + + open(MAKEFILE,">$file") || die ("Can't open $file\n"); + print MAKEFILE $self->{output}; + close(MAKEFILE); + + print __FILE__.": creating $file\n"; +} + +my $sort_available = eval "use sort 'stable'; return 1;"; +$sort_available = 0 unless defined($sort_available); + +sub by_path { + return 1 if($a =~ m#^\-I/#); + return -1 if($b =~ m#^\-I/#); + return 0; +} + +sub CFlags($$) +{ + my ($self, $key) = @_; + + my $srcdir = $self->{config}->{srcdir}; + my $builddir = $self->{config}->{builddir}; + + my $src_ne_build = ($srcdir ne $builddir) ? 1 : 0; + + return unless defined ($key->{FINAL_CFLAGS}); + return unless (@{$key->{FINAL_CFLAGS}} > 0); + + my @sorted_cflags = @{$key->{FINAL_CFLAGS}}; + if ($sort_available) { + @sorted_cflags = sort by_path @{$key->{FINAL_CFLAGS}}; + } + + # Rewrite CFLAGS so that both the source and the build + # directories are in the path. + my @cflags = (); + foreach my $flag (@sorted_cflags) { + if($src_ne_build) { + if($flag =~ m#^-I([^/].*$)#) { + my $dir = $1; + if ($dir =~ /^\$\(/) { + push (@cflags, $flag); + next; + } + $dir =~ s#^\$\((?:src|build)dir\)/?##; + push(@cflags, "-I$builddir/$dir", "-I$srcdir/$dir"); + next; + } + } + push(@cflags, $flag); + } + + my $cflags = join(' ', @cflags); + + $self->output("\$(patsubst %.ho,%.d,\$($key->{NAME}_OBJ_FILES:.o=.d)) \$($key->{NAME}_OBJ_FILES): CFLAGS+= $cflags\n"); +} + +1; diff --git a/source4/build/smb_build/output.pm b/source4/build/smb_build/output.pm new file mode 100644 index 0000000000..76c6d3fc8f --- /dev/null +++ b/source4/build/smb_build/output.pm @@ -0,0 +1,172 @@ +# SMB Build System +# - the output generating functions +# +# Copyright (C) Stefan (metze) Metzmacher 2004 +# Copyright (C) Jelmer Vernooij 2004 +# Released under the GNU GPL + +package output; +use strict; + +sub generate_shared_library($) +{ + my $lib = shift; + my $link_name; + my $lib_name; + + $lib->{DEPEND_LIST} = []; + + $link_name = lc($lib->{NAME}); + $lib_name = $link_name; + + if ($lib->{TYPE} eq "LIBRARY") { + $link_name = $lib->{NAME}; + $link_name =~ s/^LIB//; + $link_name = lc($link_name); + $lib_name = "lib$link_name"; + } + + if ($lib->{TYPE} eq "PYTHON") { + $lib->{SHAREDDIR} = "bin/python"; + } elsif (defined($lib->{LIBRARY_REALNAME})) { + $lib->{BASEDIR} =~ s/^\.\///g; + $lib->{SHAREDDIR} = $lib->{BASEDIR}; + } else { + if ($lib->{TYPE} eq "MODULE") { + my $sane_subsystem = lc($lib->{SUBSYSTEM}); + $sane_subsystem =~ s/^lib//; + $lib->{SHAREDDIR} = "bin/modules/$sane_subsystem"; + $lib->{LIBRARY_REALNAME} = $link_name; + $lib->{LIBRARY_REALNAME} =~ s/^$sane_subsystem\_//g; + $lib->{LIBRARY_REALNAME}.= ".\$(SHLIBEXT)"; + } else { + $lib->{SHAREDDIR} = "bin/shared"; + $lib->{LIBRARY_REALNAME} = "$lib_name.\$(SHLIBEXT)"; + } + } + + $lib->{LIBRARY_DEBUGNAME} = $lib->{LIBRARY_REALNAME}; + + $lib->{LIBRARY_SONAME} = "\$(if \$($lib->{NAME}_SOVERSION),$lib->{LIBRARY_REALNAME}.\$($lib->{NAME}_SOVERSION),$lib->{LIBRARY_REALNAME})"; + $lib->{LIBRARY_REALNAME} = "\$(if \$($lib->{NAME}_VERSION),$lib->{LIBRARY_REALNAME}.\$($lib->{NAME}_VERSION),$lib->{LIBRARY_REALNAME})"; + + $lib->{RESULT_SHARED_LIBRARY} = "$lib->{SHAREDDIR}/$lib->{LIBRARY_REALNAME}"; + $lib->{OUTPUT_SHARED_LIBRARY} = "-l$link_name"; + $lib->{TARGET_SHARED_LIBRARY} = "$lib->{SHAREDDIR}/$lib->{LIBRARY_DEBUGNAME}"; +} + +sub generate_merged_obj($) +{ + my $lib = shift; + + my $link_name = $lib->{NAME}; + $link_name =~ s/^LIB//; + + $lib->{MERGED_OBJNAME} = lc($link_name).".o"; + $lib->{RESULT_MERGED_OBJ} = $lib->{OUTPUT_MERGED_OBJ} = "bin/mergedobj/$lib->{MERGED_OBJNAME}"; + $lib->{TARGET_MERGED_OBJ} = $lib->{RESULT_MERGED_OBJ}; +} + +sub generate_static_library($) +{ + my $lib = shift; + my $link_name; + + $lib->{DEPEND_LIST} = []; + + $link_name = $lib->{NAME}; + $link_name =~ s/^LIB//; + + $lib->{LIBRARY_NAME} = "lib".lc($link_name).".a"; + + $lib->{RESULT_STATIC_LIBRARY} = "bin/static/$lib->{LIBRARY_NAME}"; + $lib->{TARGET_STATIC_LIBRARY} = $lib->{RESULT_STATIC_LIBRARY}; + $lib->{STATICDIR} = 'bin/static'; + $lib->{OUTPUT_STATIC_LIBRARY} = "-l".lc($link_name); +} + +sub generate_binary($) +{ + my $bin = shift; + + $bin->{DEPEND_LIST} = []; + push(@{$bin->{LINK_FLAGS}}, "\$($bin->{NAME}\_FULL_OBJ_LIST)"); + + $bin->{DEBUGDIR} = "bin"; + $bin->{RESULT_BINARY} = $bin->{OUTPUT_BINARY} = "$bin->{DEBUGDIR}/$bin->{NAME}"; + $bin->{TARGET_BINARY} = $bin->{RESULT_BINARY}; + $bin->{BINARY} = $bin->{NAME}; +} + +sub merge_array($$) +{ + # $dest is a reference to an array + # $src is an array + my ($dest, $src) = @_; + + return unless defined($src); + return unless ($#{$src} >= 0); + + foreach my $line (@{$src}) { + next if (grep /^$line$/, @{$$dest}); + push(@{$$dest}, $line); + } +} + +sub create_output($$) +{ + my ($depend, $config) = @_; + my $part; + + foreach $part (values %{$depend}) { + next unless(defined($part->{OUTPUT_TYPE})); + + generate_binary($part) if grep(/BINARY/, @{$part->{OUTPUT_TYPE}}); + generate_shared_library($part) if grep(/SHARED_LIBRARY/, @{$part->{OUTPUT_TYPE}}); + generate_static_library($part) if grep(/STATIC_LIBRARY/, @{$part->{OUTPUT_TYPE}}); + generate_merged_obj($part) if grep(/MERGED_OBJ/, @{$part->{OUTPUT_TYPE}}); + $part->{OUTPUT} = $part->{"OUTPUT_" . @{$part->{OUTPUT_TYPE}}[0]}; + $part->{TARGET} = $part->{"TARGET_" . @{$part->{OUTPUT_TYPE}}[0]}; + } + + foreach $part (values %{$depend}) { + next if not defined($part->{OUTPUT_TYPE}); + + merge_array(\$part->{FINAL_CFLAGS}, $part->{CPPFLAGS}); + merge_array(\$part->{FINAL_CFLAGS}, $part->{CFLAGS}); + + foreach (@{$part->{UNIQUE_DEPENDENCIES_ALL}}) { + my $elem = $depend->{$_}; + next if $elem == $part; + + merge_array(\$part->{FINAL_CFLAGS}, $elem->{CPPFLAGS}); + merge_array(\$part->{FINAL_CFLAGS}, $elem->{CFLAGS}); + } + + # Always import the link options of the unique dependencies + foreach (@{$part->{UNIQUE_DEPENDENCIES_LINK}}) { + my $elem = $depend->{$_}; + next if $elem == $part; + + push(@{$part->{LINK_FLAGS}}, @{$elem->{LIBS}}) if defined($elem->{LIBS}); + push(@{$part->{LINK_FLAGS}}, @{$elem->{LDFLAGS}}) if defined($elem->{LDFLAGS}); + if (defined($elem->{OUTPUT_TYPE}) and @{$elem->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ") { + push (@{$part->{FULL_OBJ_LIST}}, $elem->{TARGET}); + } else { + push(@{$part->{LINK_FLAGS}}, "\$($elem->{NAME}_OUTPUT)") if defined($elem->{OUTPUT}); + push(@{$part->{DEPEND_LIST}}, $elem->{TARGET}) if (defined($elem->{TARGET})); + } + } + } + + foreach $part (values %{$depend}) { + if (defined($part->{STANDARD_VISIBILITY}) and ($part->{STANDARD_VISIBILITY} ne "default") and + ($config->{visibility_attribute} eq "yes")) { + push(@{$part->{FINAL_CFLAGS}}, "-fvisibility=$part->{STANDARD_VISIBILITY}"); + } + } + + return $depend; +} + +1; diff --git a/source4/build/smb_build/summary.pm b/source4/build/smb_build/summary.pm new file mode 100644 index 0000000000..4ea1ad525e --- /dev/null +++ b/source4/build/smb_build/summary.pm @@ -0,0 +1,79 @@ +# Samba Build System +# - write out summary +# +# Copyright (C) Jelmer Vernooij 2006 +# Released under the GNU GPL + +package summary; +use smb_build::config; +use strict; + +sub enabled($) +{ + my ($val) = @_; + + return (defined($val) && $val =~ m/yes|true/i); +} + +sub showitem($$$) +{ + my ($output,$desc,$items) = @_; + + my @need = (); + + foreach (@$items) { + push (@need, $_) if (enabled($config::enable{$_})); + } + + print "Support for $desc: "; + if ($#need >= 0) { + print "no (install " . join(',',@need) . ")\n"; + } else { + print "yes\n"; + } +} + +sub showisexternal($$$) +{ + my ($output, $desc, $name) = @_; + print "Using external $desc: ". + (($output->{$name}->{TYPE} eq "EXT_LIB")?"yes":"no")."\n"; +} + +sub show($$) +{ + my ($output,$config) = @_; + + print "Summary:\n\n"; + showitem($output, "SSL in SWAT and LDAP", ["GNUTLS"]); + showitem($output, "threads in smbd (see --with-pthread)", ["PTHREAD"]); + showitem($output, "intelligent command line editing", ["READLINE"]); + showitem($output, "changing process titles (see --with-setproctitle)", ["SETPROCTITLE"]); + showitem($output, "using extended attributes", ["XATTR"]); + showitem($output, "using libblkid", ["BLKID"]); + showitem($output, "using iconv", ["ICONV"]); + showitem($output, "using pam", ["PAM"]); + showitem($output, "python bindings", ["LIBPYTHON"]); + showisexternal($output, "popt", "LIBPOPT"); + showisexternal($output, "talloc", "LIBTALLOC"); + showisexternal($output, "tdb", "LIBTDB"); + showisexternal($output, "ldb", "LIBLDB"); + print "Developer mode: ".(enabled($config->{developer})?"yes":"no")."\n"; + print "Automatic dependencies: ". + (enabled($config->{automatic_dependencies}) + ? "yes" : "no (install GNU make >= 3.81 and see --enable-automatic-dependencies)") . + "\n"; + + print "Building shared libraries: " . + (enabled($config->{BLDSHARED}) + ? "yes" : "no (not supported on this system)") . + "\n"; + print "Using shared libraries internally: " . + (enabled($config->{USESHARED}) + ? "yes" : "no (specify --enable-dso)") . + "\n"; + + print "\n"; +} + +1; |