打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Open Source Tools Blog | HelloGcc Work Group | Page 3

Copyright (c) 2012 邢明杰(xmj@hellogcc)

GCC使用configure.ac(通过autoconf)来生成configure文件。顶层目录下的configure.ac有三千多行,用来在配置阶段做各种测试检测,并将结果替换到Makefile.in中,生成最终的Makefile。本文简单介绍了configure.ac中所要做的事请,并没有覆盖所有的细节问题。

1、导出原始的configure参数

progname=$0# if PWD already has a value, it is probably wrong.if test -n "$PWD" ; then PWD=`${PWDCMD-pwd}`; fi# Export original configure arguments for use by sub-configures.# Quote arguments with shell meta charatcers.TOPLEVEL_CONFIGURE_ARGUMENTS=set -- "$progname" "$@"for ac_argdo  case "$ac_arg" in  *" "*|*"      "*|*[[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\']]*)    ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"`    # if the argument is of the form -foo=baz, quote the baz part only    ac_arg=`echo "'$ac_arg'" | sed "s/^'\([[-a-zA-Z0-9]]*=\)/\\1'/"` ;;  *) ;;  esac  # Add the quoted argument to the list.  TOPLEVEL_CONFIGURE_ARGUMENTS="$TOPLEVEL_CONFIGURE_ARGUMENTS $ac_arg"doneif test "$silent" = yes; then  TOPLEVEL_CONFIGURE_ARGUMENTS="$TOPLEVEL_CONFIGURE_ARGUMENTS --silent"fi# Remove the initial space we just introduced and, as these will be# expanded by make, quote '$'.TOPLEVEL_CONFIGURE_ARGUMENTS=`echo "x$TOPLEVEL_CONFIGURE_ARGUMENTS" | sed -e 's/^x *//' -e 's,\\$,$$,g'`AC_SUBST(TOPLEVEL_CONFIGURE_ARGUMENTS)

这部分代码位于38-64行,用来将configure的参数保存到变量TOPLEVEL_CONFIGURE_ARGUMENTS中,以供子目录的configure使用。

2、一些基本的测试

# Find the build, host, and target systems.ACX_NONCANONICAL_BUILDACX_NONCANONICAL_HOSTACX_NONCANONICAL_TARGET... ...AC_CANONICAL_SYSTEMAC_ARG_PROGRAMm4_pattern_allow([^AS_FOR_TARGET$])dnlm4_pattern_allow([^AS_FOR_BUILD$])dnl# Get 'install' or 'install-sh' and its variants.AC_PROG_INSTALLACX_PROG_LNAC_PROG_LN_SAC_PROG_SEDAC_PROG_AWK...

从66到108行,测试build,host,target系统(这些命令在acx.m4中定义),测试install,ln,sed,awk。

3、确定哪些库和工具将被配置

# these library is used by various programs built for the build# environment#build_libs="build-libiberty"# these tools are built for the build environmentbuild_tools="build-texinfo build-flex build-bison build-m4 build-fixincludes"# these libraries are used by various programs built for the host environment#host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber gmp mpfr mpc isl cloog libelf libiconv"# these tools are built for the host environment# Note, the powerpc-eabi build depends on sim occurring before gdb in order to# know that we are building the simulator.# binutils, gas and ld appear in that order because it makes sense to run# "make check" in that particular order.# If --enable-gold is used, "gold" may replace "ld".host_tools="texinfo flex bison binutils gas ld fixincludes gcc cgen sid sim gdb gprof etc expect dejagnu m4 utils guile fastjar gnattools"# libgcj represents the runtime libraries only used by gcj.libgcj="target-libffi         target-zlib         target-libjava"# these libraries are built for the target environment, and are built after# the host libraries and the host tools (which may be a cross compiler)# Note that libiberty is not a target library.target_libraries="target-libgcc                 target-libgloss                 target-newlib                 target-libgomp                 target-libatomic                 target-libitm                 target-libstdc++-v3                 target-libmudflap                 target-libssp                 target-libquadmath                 target-libgfortran                 target-boehm-gc                 ${libgcj}                 target-libobjc                 target-libada                 target-libgo"# these tools are built using the target libraries, and are intended to# run only in the target environment## note: any program that *uses* libraries that are in the "target_libraries"# list belongs in this list.#target_tools="target-rda"

这部分代码位于112-2036行,这部分代码主要是为了确定哪些库和工具将被配置。首先,定义变量build_libs, build_tools, host_libs, host_tools, target_libraries(这里没有使用target_libs,是因为target_libs变量在config-lang.in中已经被定义使用了,参见http://gcc.gnu.org/ml/gcc-patches/2003-06/msg02977.html), target_tools,用来列出所有可能需要的库和工具。

## All tools belong in one of the four categories, and are assigned above## We assign ${configdirs} this way to remove all embedded newlines.  This## is important because configure will choke if they ever get through.## ${configdirs} is directories we build using the host tools.## ${target_configdirs} is directories we build using the target tools.configdirs=`echo ${host_libs} ${host_tools}`target_configdirs=`echo ${target_libraries} ${target_tools}`build_configdirs=`echo ${build_libs} ${build_tools}`

然后,定义变量configdirs, target_configdirs, build_configdirs,用来列出这些库和工具所对应的将要进行配置的源码目录。

# Skipdirs are removed silently.skipdirs=# Noconfigdirs are removed loudly.noconfigdirs=""

然后,定义变量skipdirs和noconfigdirs,用来列出哪些目录将被跳过,或者不进行配置。其中skipdirs中的目录将被隐式的跳过,而noconfigdirs中的目录将会在终端显式的打印出消息,告知这些目录将不被配置。

use_gnu_ld=# Make sure we don't let GNU ld be added if we didn't want it.if test x$with_gnu_ld = xno ; then  use_gnu_ld=no  noconfigdirs="$noconfigdirs ld gold"fiuse_gnu_as=# Make sure we don't let GNU as be added if we didn't want it.if test x$with_gnu_as = xno ; then  use_gnu_as=no  noconfigdirs="$noconfigdirs gas"fi... ...

接下来,就是根据configure的各种选项,来设置skipdirs和noconfigdirs的值。

# Remove the entries in $skipdirs and $noconfigdirs from $configdirs,# $build_configdirs and $target_configdirs.# If we have the source for $noconfigdirs entries, add them to $notsupp.notsupp=""for dir in . $skipdirs $noconfigdirs ; do  dirname=`echo $dir | sed -e s/target-//g -e s/build-//g`  if test $dir != .  && echo " ${configdirs} " | grep " ${dir} " >/dev/null 2>&1; then    configdirs=`echo " ${configdirs} " | sed -e "s/ ${dir} / /"`    if test -r $srcdir/$dirname/configure ; then      if echo " ${skipdirs} " | grep " ${dir} " >/dev/null 2>&1; then        true      else        notsupp="$notsupp $dir"      fi    fi  fi  if test $dir != .  && echo " ${build_configdirs} " | grep " ${dir} " >/dev/null 2>&1; then    build_configdirs=`echo " ${build_configdirs} " | sed -e "s/ ${dir} / /"`    if test -r $srcdir/$dirname/configure ; then      if echo " ${skipdirs} " | grep " ${dir} " >/dev/null 2>&1; then        true      else        notsupp="$notsupp $dir"      fi    fi  fi  if test $dir != . && echo " ${target_configdirs} " | grep " ${dir} " >/dev/null 2>&1; then    target_configdirs=`echo " ${target_configdirs} " | sed -e "s/ ${dir} / /"`    if test -r $srcdir/$dirname/configure ; then      if echo " ${skipdirs} " | grep " ${dir} " >/dev/null 2>&1; then        true      else        notsupp="$notsupp $dir"      fi    fi  fidone... ...

最后,从configdirs, target_configdirs, build_configdirs中,移除在skipdirs和noconfigdirs中存在的目录项。并且,移除那些无法进行配置(没有configure文件)的目录。

4、测试flags,复制目录

AC_ARG_WITH([build-sysroot],  [AS_HELP_STRING([--with-build-sysroot=SYSROOT],                  [use sysroot as the system root during the build])],  [if test x"$withval" != x ; then     SYSROOT_CFLAGS_FOR_TARGET="--sysroot=$withval"   fi],  [SYSROOT_CFLAGS_FOR_TARGET=])AC_SUBST(SYSROOT_CFLAGS_FOR_TARGET)... ...

从2046到2206行,这部分代码设定了CFLAGS_FOR_TARGET,CXXFLAGS_FOR_TARGET,LDFLAGS_FOR_TARGET;并且对选项–with-headers=XXX,–with-libs=XXX做了处理,分别将目录下的内容复制到$(tooldir)/sys-include和$(tooldir)/lib下。

5、设定Makefile片段(frag)

# Work in distributions that contain no compiler tools, like Autoconf.host_makefile_frag=/dev/nullif test -d ${srcdir}/config ; thencase "${host}" in  i[[3456789]]86-*-msdosdjgpp*)    host_makefile_frag="config/mh-djgpp"    ;;  *-cygwin*)    ACX_CHECK_CYGWIN_CAT_WORKS    host_makefile_frag="config/mh-cygwin"    ;;... ...# Makefile fragments.for frag in host_makefile_frag target_makefile_frag alphaieee_frag ospace_frag;do  eval fragval=\$$frag  if test $fragval != /dev/null; then    eval $frag=${srcdir}/$fragval  fidoneAC_SUBST_FILE(host_makefile_frag)AC_SUBST_FILE(target_makefile_frag)AC_SUBST_FILE(alphaieee_frag)AC_SUBST_FILE(ospace_frag)

这部分代码位于1074-1107,2226-2280,2871-2882行,用来设定host_makefile_frag,target_makefile_frag,alphaieee_frag,ospace_frag这些makefile片段的值。

6、gdb相关

# Create a .gdbinit file which runs the one in srcdir# and tells GDB to look there for source files.if test -r ${srcdir}/.gdbinit ; then  case ${srcdir} in    .) ;;    *) cat > ./.gdbinit <<="" pre="">

代码2287-2301行,用来创建.gdbinit文件,方便调试gcc。

# Determine whether gdb needs tk/tcl or not.# Use 'maybe' since enable_gdbtk might be true even if tk isn't available# and in that case we want gdb to be built without tk.  Ugh!# In fact I believe gdb is the *only* package directly dependent on tk,# so we should be able to put the 'maybe's in unconditionally and# leave out the maybe dependencies when enable_gdbtk is false.  I'm not# 100% sure that that's safe though.gdb_tk="maybe-all-tcl maybe-all-tk maybe-all-itcl maybe-all-libgui"case "$enable_gdbtk" in  no)    GDB_TK="" ;;  yes)    GDB_TK="${gdb_tk}" ;;  *)    # Only add the dependency on gdbtk when GDBtk is part of the gdb    # distro.  Eventually someone will fix this and move Insight, nee    # gdbtk to a separate directory.    if test -d ${srcdir}/gdb/gdbtk ; then      GDB_TK="${gdb_tk}"    else      GDB_TK=""    fi    ;;esacCONFIGURE_GDB_TK=`echo ${GDB_TK} | sed s/-all-/-configure-/g`INSTALL_GDB_TK=`echo ${GDB_TK} | sed s/-all-/-install-/g`

代码2352-2378行,用来确定gdb是否需要tk/tcl。这里作者提到一个他认为可以进行改进,但又不太确定的地方。

7、去掉Makefile中不需要的目标(target)

extrasub_build=for module in ${build_configdirs} ; do  if test -z "${no_recursion}"      && test -f ${build_subdir}/${module}/Makefile; then    echo 1>&2 "*** removing ${build_subdir}/${module}/Makefile to force reconfigure"    rm -f ${build_subdir}/${module}/Makefile  fi  extrasub_build="$extrasub_build/^@if build-$module\$/d/^@endif build-$module\$/d/^@if build-$module-$bootstrap_suffix\$/d/^@endif build-$module-$bootstrap_suffix\$/d"done... ...AC_CONFIG_FILES([Makefile],  [sed "$extrasub_build" Makefile |   sed "$extrasub_host" |   sed "$extrasub_target" > mf$$   mv -f mf$$ Makefile],  [extrasub_build="$extrasub_build"   extrasub_host="$extrasub_host"   extrasub_target="$extrasub_target"])AC_OUTPUT

这部分代码位于2382-2392,2445-2497,3199-3207行,用来删除掉Makefile(或者Makefile.in)中不需要的目标。
Makefile.in文件中有许多@if和@endif包裹的模块。configure.ac中定义了变量extrasub_build,extrasub_host,
extrasub_target,它们是根据build_configdirs,configdirs,target_configdirs的内容而定义的sed语句。

在最后的AC_CONFIG_FILES命令中,将会调用这些sed语句,修改Makefile,对@if语句块进行选择性的删除。

8、设定BUILD_CONFIG变量,以调整顶层makefile

# Adjust the toplevel makefile according to whether bootstrap was selected.case $enable_bootstrap in  yes)    bootstrap_suffix=bootstrap    BUILD_CONFIG=bootstrap-debug    ;;  no)    bootstrap_suffix=no-bootstrap    BUILD_CONFIG=    ;;esac... ...AC_MSG_RESULT($BUILD_CONFIG)

这部分代码位于2401-2443行,根据是否选择了bootstrap,来设定BUILD_CONFIG变量的值。
Makefile中会根据该变量的值将config子目录下相应的mk文件包含进来。

9、串行化configure

# Create the serialization dependencies.  This uses a temporary file.AC_ARG_ENABLE([serial-configure],[AS_HELP_STRING([[--enable-serial-[{host,target,build}-]configure]],                [force sequential configuration of                 sub-packages for the host, target or build                 machine, or all sub-packages])])... ...serialization_dependencies=serdep.tmpAC_SUBST_FILE(serialization_dependencies)

这部分代码位于2499-2547行,用来实现对串行化configure的支持。

10、对自举(bootstrap)的支持

# ---------------------# GCC bootstrap support# ---------------------# Stage specific cflags for build.stage1_cflags="-g"case $build in  vax-*-*)    case ${GCC} in      yes) stage1_cflags="-g -Wa,-J" ;;      *) stage1_cflags="-g -J" ;;    esac ;;esac... ...

这部分代码位于3118-3197行,用来设定不同阶段的命令行选项(比如stage1_cflags),
指定哪些文件在自举过程中不需要进行比较操作。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
安装gdb7.4时出现错误
Makefile.am、Makefile.in和Makefile的关系
运用autoconf和automake自动生成Makefile实例讲解
交叉编译GDB工具, 使GDB运行在嵌入式板子上
在Linux中使用VS Code编译调试C++项目
交叉编译 dhcp-4.2.5-P1
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服