快乐虾<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
http://blog.csdn.net/lights_joy/
lights@hb165.com
本文适用于
gcc-<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />4.3.1
Blackfin系列DSP
Visual Studio 2005
欢迎转载,但请保留作者信息
这是很多c文件中包含的第一个头文件,从Makefile的依赖关系可以也看出很多模块都要依赖于config.h的生成。
在Makefile.in中搜索,可以发现这样的语句:
config.h: cs-config.h ; @true
即config.h依赖于cs-config.h,再搜索cs-config.h:
cs-config.h: Makefile
TARGET_CPU_DEFAULT="" /
HEADERS="$(host_xm_include_list)" DEFINES="$(host_xm_defines)" /
$(SHELL) $(srcdir)/mkconfig.sh config.h
即config.h的生成是通过mkconfig.sh config.h这个命令来实现的。
下面对照mkconfig.sh的内容生成config.h文件。
1.1.1.1 调用参数判断
# Generate gcc's various configuration headers:
# config.h, tconfig.h, bconfig.h, tm.h, and tm_p.h.
# $1 is the file to generate. DEFINES, HEADERS, and possibly
# TARGET_CPU_DEFAULT are expected to be set in the environment.
if [ -z "$1" ]; then
echo "Usage: DEFINES='list' HEADERS='list' //" >&2
echo " [TARGET_CPU_DEFAULT='default'] mkconfig.sh FILE" >&2
exit 1
fi
判断是否带参数执行,从Makefile调用命令来看$1 = “config.h”。
1.1.1.2 删除临时文件
output=$1
rm -f ${output}T
删除输出的临时文件。
1.1.1.3 输出保护性语句
# This converts a file name into header guard macro format.
hg_sed_expr='y,abcdefghijklmnopqrstuvwxyz./,ABCDEFGHIJKLMNOPQRSTUVWXYZ__,'
header_guard=GCC_`echo ${output} | sed -e ${hg_sed_expr}`
# Add multiple inclusion protection guard, part one.
echo "#ifndef ${header_guard}" >> ${output}T
echo "#define ${header_guard}" >> ${output}T
这几句话其实就是在头文件中输出
#ifndef xxx
#define xxx
这样的保护性语句。
1.1.1.4 错误判断
# A special test to ensure that build-time files don't blindly use
# config.h.
if test x"$output" = x"config.h"; then
echo "#ifdef GENERATOR_FILE" >> ${output}T
echo "#error config.h is for the host, not build, machine." >> ${output}T
echo "#endif" >> ${output}T
fi
这段话将在config.h中输出:
#ifdef GENERATOR_FILE
#error config.h is for the host, not build, machine.
#endif
1.1.1.5 定义TARGET_CPU_DEFAULT
# Define TARGET_CPU_DEFAULT if the system wants one.
# This substitutes for lots of *.h files.
if [ "$TARGET_CPU_DEFAULT" != "" ]; then
echo "#define TARGET_CPU_DEFAULT ($TARGET_CPU_DEFAULT)" >> ${output}T
fi
对于config.h来讲,TARGET_CPU_DEFAULT为空字符串,这段将不执行。
1.1.1.6 输出宏定义
# Provide defines for other macros set in config.gcc for this file.
for def in $DEFINES; do
echo "#ifndef $def" | sed 's/=.*//' >> ${output}T
echo "# define $def" | sed 's/=/ /' >> ${output}T
echo "#endif" >> ${output}T
done
这段话的输出取决于调用时的DEFINES定义,而这一变量在Makefile中定义为host_xm_defines,在Makefile.in中查找这个变量的定义:
host_xm_defines=@host_xm_defines@
说明这个值的定义应该是从configure中来的,在configure中查找可以发现这个值的定义为空,所以config.sh中的这段话将不产生输出。
1.1.1.7 输出include
# The first entry in HEADERS may be auto-FOO.h ;
# it wants to be included even when not -DIN_GCC.
if [ -n "$HEADERS" ]; then
set $HEADERS
case "$1" in auto-* )
echo "#include /"$1/"" >> ${output}T
shift
;;
esac
if [ $# -ge 1 ]; then
echo '#ifdef IN_GCC' >> ${output}T
for file in "$@"; do
echo "# include /"$file/"" >> ${output}T
done
echo '#endif' >> ${output}T
fi
fi
这段话将根据HEADERS的定义生成一些include语句。查找host_xm_include_list,可以发现以下定义:
host_xm_include_list=
for f in $host_xm_file; do
case $f in
ansidecl.h )
host_xm_file_list="${host_xm_file_list} /$(srcdir)/../include/$f"
host_xm_include_list="${host_xm_include_list} $f"
;;
auto-host.h )
host_xm_file_list="${host_xm_file_list} $f"
host_xm_include_list="${host_xm_include_list} $f"
;;
* )
host_xm_file_list="${host_xm_file_list} /$(srcdir)/config/$f"
host_xm_include_list="${host_xm_include_list} config/$f"
;;
esac
done
再查一下host_xm_file的定义:
# Machine-specific settings.
case ${host} in
i[34567]86-*-pe | i[34567]86-*-cygwin*)
host_xm_file=i386/xm-cygwin.h
out_host_hook_obj=host-cygwin.o
host_xmake_file="${host_xmake_file} i386/x-cygwin"
host_exeext=.exe
;;
i[34567]86-*-mingw32* | x86_64-*-mingw*)
host_xm_file=i386/xm-mingw32.h
host_xmake_file="${host_xmake_file} i386/x-mingw32"
host_exeext=.exe
out_host_hook_obj=host-mingw32.o
;;
………………
esac
host_xm_file="auto-host.h ansidecl.h ${host_xm_file}"
因为我们选择vs2005做为host的编译器,因此在系统中并不直接支持,为此仿照configs/i386/xm-cygwin.h建立一个xm-vs2005.h文件,其内容与xm-cygwin.h相同。
所以最后host_xm_include_list就变成了
“auto-host.h ../include/ansidecl.h config/i386/xm-vs2005.h”
回到mkconfig.sh的代码中来,上述代码段将生成如下输出:
#include "auto-host.h"
#ifdef IN_GCC
# include "../include/ansidecl.h"
# include "config/i386/xm-vs2005.h"
#endif
1.1.1.8 对tm.h做特殊处理
# If this is tm.h, now include insn-constants.h and insn-flags.h only
# if IN_GCC is defined but neither GENERATOR_FILE nor USED_FOR_TARGET
# is defined. (Much of this is temporary.)
case $output in
tm.h )
cat >> ${output}T <<EOF
#if defined IN_GCC && !defined GENERATOR_FILE && !defined USED_FOR_TARGET
# include "insn-constants.h"
# include "insn-flags.h"
#endif
EOF
;;
esac
这几行代码将对tm.h输出一些特定的语句,但我们生成的是config.h,故略过。
1.1.1.9 #endif
# Add multiple inclusion protection guard, part two.
echo "#endif /* ${header_guard} */" >> ${output}T
输出头文件末尾的#endif,与文件开头中的#ifndef对应。
1.1.1.10 文件后继处理
# Avoid changing the actual file if possible.
if [ -f $output ] && cmp ${output}T $output >/dev/null 2>&1; then
echo $output is unchanged >&2
rm -f ${output}T
else
mv -f ${output}T $output
fi
# Touch a stamp file for Make's benefit.
rm -f cs-$output
echo timestamp > cs-$output
没什么,最后就是把临时文件复制为正式的config.h。
1.1.1.11 最终版本
最后生成的config.h如下:
#ifndef __GCC_CONFIG__H__
#define __GCC_CONFIG__H__
#ifdef GENERATOR_FILE
#error config.h is for the host, not build, machine.
#endif
#include "auto-host.h"
#ifdef IN_GCC
# include "../include/ansidecl.h"
# include "config/i386/xm-vs2005.h"
#endif
#endif // __GCC_CONFIG__H__