mirror of
https://github.com/python/cpython.git
synced 2026-10-28 10:25:05 +08:00
The build-helper programs (`Programs/_freeze_module` and `_bootstrap_python`) don't need to link extension modules that they don't need. This PR makes sure the helper programs get only the modules they need to do their job, regardless of what the build configuration sets for the final built runtime and interpreter. This follows the same pattern as what `PCbuild/_freeze_module.vcxproj` does with `PC/config_minimal.c`, and lets "extra" builtin modules (from `Setup.local` or `MODULE_BUILDTYPE=static`) depend on frozen modules or `getpath`.
405 lines
11 KiB
Bash
Executable File
405 lines
11 KiB
Bash
Executable File
#! /bin/sh
|
|
set -e
|
|
|
|
# Convert templates into Makefile and config.c, based on the module
|
|
# definitions found in the file Setup.
|
|
#
|
|
# Usage: makesetup [-s dir] [-c file] [-m file] [Setup] ... [-b Setup] ...
|
|
# [-n [Setup] ...]
|
|
#
|
|
# Options:
|
|
# -s directory: alternative source directory (default .)
|
|
# -l directory: library source directory (default derived from $0)
|
|
# -c file: alternative config.c template (default $libdir/config.c.in)
|
|
# -c -: don't write config.c (nor config_bootstrap.c)
|
|
# -m file: alternative Makefile template (default ./Makefile.pre)
|
|
# -m -: don't write Makefile
|
|
#
|
|
# Remaining arguments are one or more Setup files (default ./Setup).
|
|
# The Setup file following a -b option holds the *bootstrap* modules:
|
|
# the static modules that the build helper programs (_freeze_module,
|
|
# _bootstrap_python) are linked with. They are also regular modules of
|
|
# the final build.
|
|
# Setup files after a -n option are used for their variables, modules
|
|
# and libraries but not for their .o files.
|
|
#
|
|
# See Setup for a description of the format of the Setup file.
|
|
#
|
|
# The following edits are made:
|
|
#
|
|
# Copying config.c.in to config.c:
|
|
# - insert an identifying comment at the start
|
|
# - for each <module> mentioned in Setup before *noconfig*:
|
|
# + insert 'extern PyObject* PyInit_<module>(void);' before MARKER 1
|
|
# + insert '{"<module>", PyInit_<module>},' before MARKER 2
|
|
#
|
|
# Copying config.c.in to config_bootstrap.c (only with a -b Setup file):
|
|
# - same as config.c, but only for the modules of the -b Setup file
|
|
#
|
|
# Copying Makefile.pre to Makefile:
|
|
# - insert an identifying comment at the start
|
|
# - replace _MODBUILT_NAMES_ by the list of *static* and *shared* modules
|
|
# from Setup
|
|
# - replace _MODBSHARED_NAMES_ by the list of *shared* modules from Setup
|
|
# - replace _MODDISABLED_NAMES_ by the list of *disabled* modules from Setup
|
|
# - replace _MODOBJS_ by the list of objects from Setup (except for
|
|
# Setup files after a -n option)
|
|
# - replace _MODLIBS_ by the list of libraries from Setup
|
|
# - replace _BOOTSTRAP_MODOBJS_ and _BOOTSTRAP_MODLIBS_ by the objects and
|
|
# libraries of the -b Setup file
|
|
# - for each object file mentioned in Setup, append a rule
|
|
# '<file>.o: <file>.c; <build commands>' to the end of the Makefile
|
|
# - for each module mentioned in Setup, append a rule
|
|
# which creates a shared library version to the end of the Makefile
|
|
# - for each variable definition found in Setup, insert the definition
|
|
# before the comment 'Definitions added by makesetup'
|
|
|
|
# Loop over command line options
|
|
usage='
|
|
usage: makesetup [-s srcdir] [-l libdir] [-c config.c.in] [-m Makefile.pre]
|
|
[Setup] ... [-b Setup] ... [-n [Setup] ...]'
|
|
srcdir='.'
|
|
libdir=''
|
|
config=''
|
|
makepre=''
|
|
noobjects=''
|
|
doconfig=yes
|
|
bootstrap=
|
|
while :
|
|
do
|
|
case $1 in
|
|
-s) shift; srcdir=$1; shift;;
|
|
-l) shift; libdir=$1; shift;;
|
|
-c) shift; config=$1; shift;;
|
|
-m) shift; makepre=$1; shift;;
|
|
--) shift; break;;
|
|
-n) noobjects=yes;;
|
|
-*) echo "$usage" 1>&2; exit 2;;
|
|
*) break;;
|
|
esac
|
|
done
|
|
|
|
# Set default libdir and config if not set by command line
|
|
# (Not all systems have dirname)
|
|
case $libdir in
|
|
'') case $0 in
|
|
*/*) libdir=`echo $0 | sed 's,/[^/]*$,,'`;;
|
|
*) libdir=.;;
|
|
esac;;
|
|
esac
|
|
case $config in
|
|
'') config=$libdir/config.c.in;;
|
|
esac
|
|
case $makepre in
|
|
'') makepre=Makefile.pre;;
|
|
esac
|
|
|
|
# Newline for sed i and a commands
|
|
NL='\
|
|
'
|
|
|
|
# Main loop
|
|
for i in ${*-Setup}
|
|
do
|
|
echo '' # Add a linebreak so we don't choke on files missing EOL.
|
|
case $i in
|
|
-n) echo '*noobjects*';;
|
|
-b) echo '*bootstrap*';;
|
|
*) echo '*doconfig*'; cat "$i"; echo ''; echo '*nobootstrap*';;
|
|
esac
|
|
done |
|
|
sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' |
|
|
(
|
|
rulesf="@rules.$$"
|
|
trap 'rm -f $rulesf' 0 1 2 3
|
|
echo "
|
|
# Rules appended by makesetup
|
|
" >$rulesf
|
|
DEFS=
|
|
BUILT=
|
|
BUILT_SHARED=
|
|
DISABLED=
|
|
CONFIGURED=
|
|
MODS=
|
|
SHAREDMODS=
|
|
OBJS=
|
|
LIBS=
|
|
LOCALLIBS=
|
|
BASELIBS=
|
|
BOOTMODS=
|
|
BOOTOBJS=
|
|
BOOTLIBS=
|
|
havebootstrap=
|
|
while read line
|
|
do
|
|
# to handle backslashes for sh's that don't automatically
|
|
# continue a read when the last char is a backslash
|
|
while echo $line | grep '\\$' > /dev/null
|
|
do
|
|
read extraline
|
|
line=`echo $line| sed s/.$//`$extraline
|
|
done
|
|
|
|
# Output DEFS in reverse order so first definition overrides
|
|
case $line in
|
|
*=*) DEFS="$line$NL$DEFS"; continue;;
|
|
'include '*) DEFS="$line$NL$DEFS"; continue;;
|
|
'*noobjects*')
|
|
case $noobjects in
|
|
yes) ;;
|
|
*) LOCALLIBS=$LIBS; LIBS=;;
|
|
esac
|
|
noobjects=yes;
|
|
continue;;
|
|
'*doconfig*') doconfig=yes; continue;;
|
|
'*bootstrap*') bootstrap=yes; havebootstrap=yes; continue;;
|
|
'*nobootstrap*') bootstrap=; continue;;
|
|
'*static*') doconfig=yes; continue;;
|
|
'*noconfig*') doconfig=no; continue;;
|
|
'*shared*') doconfig=no; continue;;
|
|
'*disabled*') doconfig=disabled; continue;;
|
|
esac
|
|
srcs=
|
|
cpps=
|
|
libs=
|
|
mods=
|
|
mods_upper=
|
|
skip=
|
|
for arg in $line
|
|
do
|
|
case $skip in
|
|
libs) libs="$libs $arg"; skip=; continue;;
|
|
cpps) cpps="$cpps $arg"; skip=; continue;;
|
|
srcs) srcs="$srcs $arg"; skip=; continue;;
|
|
esac
|
|
case $arg in
|
|
-framework) libs="$libs $arg"; skip=libs;
|
|
# OSX/OSXS/Darwin framework link cmd
|
|
;;
|
|
-[IDUCfF]*) cpps="$cpps $arg";;
|
|
-Xcompiler) skip=cpps;;
|
|
-Xlinker) libs="$libs $arg"; skip=libs;;
|
|
-rpath) libs="$libs $arg"; skip=libs;;
|
|
--rpath) libs="$libs $arg"; skip=libs;;
|
|
-[A-Zl]*) libs="$libs $arg";;
|
|
*.a) libs="$libs $arg";;
|
|
*.so) libs="$libs $arg";;
|
|
*.sl) libs="$libs $arg";;
|
|
/*.o) libs="$libs $arg";;
|
|
*.def) libs="$libs $arg";;
|
|
*.o) srcs="$srcs `basename $arg .o`.c";;
|
|
*.[cC]) srcs="$srcs $arg";;
|
|
*.m) srcs="$srcs $arg";; # Objective-C src
|
|
*.cc) srcs="$srcs $arg";;
|
|
*.c++) srcs="$srcs $arg";;
|
|
*.cxx) srcs="$srcs $arg";;
|
|
*.cpp) srcs="$srcs $arg";;
|
|
\$\(*_CFLAGS\)) cpps="$cpps $arg";;
|
|
\$\(*_INCLUDES\)) cpps="$cpps $arg";;
|
|
\$\(*_LIBS\)) libs="$libs $arg";;
|
|
\$\(*_LDFLAGS\)) libs="$libs $arg";;
|
|
\$\(*_RPATH\)) libs="$libs $arg";;
|
|
\$*) libs="$libs $arg"
|
|
cpps="$cpps $arg";;
|
|
*.*) echo 1>&2 "bad word $arg in $line"
|
|
exit 1;;
|
|
-u) skip=libs; libs="$libs -u";;
|
|
[a-zA-Z_]*)
|
|
mods="$mods $arg"
|
|
mods_upper=$(echo $mods | tr '[a-z]' '[A-Z]');;
|
|
*) echo 1>&2 "bad word $arg in $line"
|
|
exit 1;;
|
|
esac
|
|
done
|
|
if test -z "$cpps" -a -z "$libs"; then
|
|
cpps="\$(MODULE_${mods_upper}_CFLAGS)"
|
|
libs="\$(MODULE_${mods_upper}_LDFLAGS)"
|
|
fi
|
|
for mod in $mods
|
|
do
|
|
case $CONFIGURED in
|
|
*,${mod},*)
|
|
# Detected multiple rules for a module, first rule wins. This
|
|
# allows users to disable modules in Setup.local.
|
|
echo 1>&2 "maksetup: '$mod' was handled by previous rule."
|
|
case $bootstrap in
|
|
yes)
|
|
# This module is in the bootstrap Setup file, but an
|
|
# earlier Setup file (e.g. Setup.local) already defined
|
|
# it, and that definition won. Give the build helpers
|
|
# that earlier definition, so they use the same module
|
|
# as the final interpreter.
|
|
eval "BOOTMODS=\"\$BOOTMODS \${STATICMOD_$mod}\""
|
|
eval "BOOTOBJS=\"\$BOOTOBJS \${STATICOBJS_$mod}\""
|
|
eval "BOOTLIBS=\"\$BOOTLIBS \${STATICLIBS_$mod}\""
|
|
;;
|
|
esac
|
|
continue 2;;
|
|
esac
|
|
CONFIGURED="$CONFIGURED,${mod},"
|
|
done
|
|
case $doconfig in
|
|
yes)
|
|
LIBS="$LIBS $libs"
|
|
MODS="$MODS $mods"
|
|
BUILT="$BUILT $mods"
|
|
case $bootstrap in
|
|
yes)
|
|
BOOTLIBS="$BOOTLIBS $libs"
|
|
BOOTMODS="$BOOTMODS $mods"
|
|
;;
|
|
esac
|
|
;;
|
|
no)
|
|
BUILT="$BUILT $mods"
|
|
;;
|
|
disabled)
|
|
DISABLED="$DISABLED $mods"
|
|
continue
|
|
;;
|
|
esac
|
|
case $noobjects in
|
|
yes) continue;;
|
|
esac
|
|
objs=''
|
|
for src in $srcs
|
|
do
|
|
case $src in
|
|
*.c) obj=`basename $src .c`.o; cc='$(CC)';;
|
|
*.cc) obj=`basename $src .cc`.o; cc='$(CXX)';;
|
|
*.c++) obj=`basename $src .c++`.o; cc='$(CXX)';;
|
|
*.C) obj=`basename $src .C`.o; cc='$(CXX)';;
|
|
*.cxx) obj=`basename $src .cxx`.o; cc='$(CXX)';;
|
|
*.cpp) obj=`basename $src .cpp`.o; cc='$(CXX)';;
|
|
*.m) obj=`basename $src .m`.o; cc='$(CC)';; # Obj-C
|
|
*) continue;;
|
|
esac
|
|
case $src in
|
|
*/*) obj="$srcdir/`dirname $src`/$obj";;
|
|
*) obj="$srcdir/$obj";;
|
|
esac
|
|
objs="$objs $obj"
|
|
case $src in
|
|
glmodule.c) ;;
|
|
/*) ;;
|
|
\$*) ;;
|
|
*) src='$(srcdir)/'"$srcdir/$src";;
|
|
esac
|
|
# custom flags first, PY_STDMODULE_CFLAGS may contain -I with system libmpdec
|
|
case $doconfig in
|
|
no)
|
|
cc="$cc $cpps \$(PY_STDMODULE_CFLAGS) \$(CCSHARED)"
|
|
rule="$obj: $src \$(MODULE_${mods_upper}_DEPS) \$(MODULE_DEPS_SHARED) \$(PYTHON_HEADERS)"
|
|
rule="$rule; $cc -c $src -o $obj"
|
|
;;
|
|
*)
|
|
cc="$cc $cpps \$(PY_BUILTIN_MODULE_CFLAGS)"
|
|
rule="$obj: $src \$(MODULE_${mods_upper}_DEPS) \$(MODULE_DEPS_STATIC) \$(PYTHON_HEADERS)"
|
|
rule="$rule; $cc -c $src -o $obj"
|
|
;;
|
|
esac
|
|
echo "$rule" >>$rulesf
|
|
done
|
|
case $doconfig in
|
|
yes)
|
|
OBJS="$OBJS $objs"
|
|
case $bootstrap in
|
|
yes) BOOTOBJS="$BOOTOBJS $objs";;
|
|
esac
|
|
# Record each static module's objects and libs by name, so
|
|
# the bootstrap handling above can find a definition that
|
|
# won over a later line in the bootstrap Setup file.
|
|
for mod in $mods
|
|
do
|
|
eval "STATICMOD_$mod='$mod'"
|
|
eval "STATICOBJS_$mod='$objs'"
|
|
eval "STATICLIBS_$mod='$libs'"
|
|
done
|
|
;;
|
|
esac
|
|
for mod in $mods
|
|
do
|
|
file="$srcdir/$mod\$(EXT_SUFFIX)"
|
|
case $doconfig in
|
|
no)
|
|
SHAREDMODS="$SHAREDMODS $file"
|
|
BUILT_SHARED="$BUILT_SHARED $mod"
|
|
;;
|
|
esac
|
|
rule="$file: $objs \$(MODULE_${mods_upper}_LDEPS)"
|
|
rule="$rule; \$(BLDSHARED) $objs $libs \$(MODULE_LDFLAGS_SHARED) -o $file"
|
|
echo "$rule" >>$rulesf
|
|
done
|
|
done
|
|
|
|
case $SHAREDMODS in
|
|
'') ;;
|
|
*) DEFS="SHAREDMODS=$SHAREDMODS$NL$DEFS";;
|
|
esac
|
|
|
|
case $noobjects in
|
|
yes) BASELIBS=$LIBS;;
|
|
*) LOCALLIBS=$LIBS;;
|
|
esac
|
|
LIBS='$(LOCALMODLIBS) $(BASEMODLIBS)'
|
|
DEFS="BASEMODLIBS=$BASELIBS$NL$DEFS"
|
|
DEFS="LOCALMODLIBS=$LOCALLIBS$NL$DEFS"
|
|
|
|
# Generate a config.c from the template for the given modules
|
|
genconfig() {
|
|
out=$1; shift
|
|
EXTDECLS=
|
|
INITBITS=
|
|
for mod
|
|
do
|
|
EXTDECLS="${EXTDECLS}extern PyObject* PyInit_$mod(void);$NL"
|
|
INITBITS="${INITBITS} {\"$mod\", PyInit_$mod},$NL"
|
|
done
|
|
sed -e "
|
|
1i$NL/* Generated automatically from $config by makesetup. */
|
|
/MARKER 1/i$NL$EXTDECLS
|
|
|
|
/MARKER 2/i$NL$INITBITS
|
|
|
|
" $config >$out
|
|
}
|
|
|
|
case $config in
|
|
-) ;;
|
|
*) genconfig config.c $MODS
|
|
case $havebootstrap in
|
|
yes) genconfig config_bootstrap.c $BOOTMODS;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
case $makepre in
|
|
-) ;;
|
|
*)
|
|
# macOS' sed has issues with 'a' command. Use 'r' command with an
|
|
# external replacement file instead.
|
|
sedf="@sed.in.$$"
|
|
sedr="@sed.replace.$$"
|
|
trap 'rm -f $sedf $sedr' 0 1 2 3
|
|
echo "$NL$NL$DEFS" | sed 's/\\$//' > $sedr
|
|
echo "1i\\" >$sedf
|
|
str="# Generated automatically from $makepre by makesetup."
|
|
echo "$str" >>$sedf
|
|
echo "s%_MODBUILT_NAMES_%$BUILT%" >>$sedf
|
|
echo "s%_MODSHARED_NAMES_%$BUILT_SHARED%" >>$sedf
|
|
echo "s%_MODDISABLED_NAMES_%$DISABLED%" >>$sedf
|
|
# _BOOTSTRAP_* first: _MODOBJS_ is a substring of _BOOTSTRAP_MODOBJS_
|
|
echo "s%_BOOTSTRAP_MODOBJS_%$BOOTOBJS%" >>$sedf
|
|
echo "s%_BOOTSTRAP_MODLIBS_%$BOOTLIBS%" >>$sedf
|
|
echo "s%_MODOBJS_%$OBJS%" >>$sedf
|
|
echo "s%_MODLIBS_%$LIBS%" >>$sedf
|
|
echo "/Definitions added by makesetup/r $sedr" >>$sedf
|
|
sed -f $sedf $makepre >Makefile
|
|
cat $rulesf >>Makefile
|
|
rm -f $sedf $sedr
|
|
;;
|
|
esac
|
|
|
|
rm -f $rulesf
|
|
)
|