how to support making a config.h for multiple architechtures?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear Autoconf developers,

Does Autoconf have any support to generate a config.h which
can support multiple architectures, or multiple ABI, or
multiple data-model?

Recently I was asked to generate a config.h which can
support multiple architechtures of Mac OS X.  Apple
extended gcc to execute multiple compilation by single
command. Aslike, if I execute:

	gcc -arch ppc -arch i386 -arch ppc64 -arch x86_64 -c xxx.c

Apple's modified gcc executes 4 compilation in backgrounds:

	gcc -arch ppc    -c xxx.c -o /path_for_ppc/xxx.o
	gcc -arch i386   -c xxx.c -o /path_for_i386/xxx.o
	gcc -arch ppc64  -c xxx.c -o /path_for_ppc64/xxx.o
	gcc -arch x86_64 -c xxx.c -o /path_for_x86_64/xxx.o

Then, 4 objects files are packed in single object file
(so-called "universal binary" format).

If I execute configure with such options (one of the
architechture is native), aslike:

	env CC="gcc -arch ppc -arch ppc64" ./configure

on PPC machine, configure script works as usual if it's
executed for single architecture on native system, and
generates config.h successfully.

Nothing to say, some of the checked values are dependent
with architecture (ppc|ppc64), or data model (LP32|LP64),
or ABI (QuickDraw framework for ppc64 is unavailable).
So, some people tell such values should not be checked
by configure, and should not be written in config.h.
I think it's simple and reasonable solution.

# Mac OS X is the only system I know that executes multiple
# compilation by single command, but similar request
# (single config.h should support multiple architechtures)
# are raised by AMD64-system users, because their system
# can execute i386 code & amd64 code.

However, still I want configure to check such values and
write them in config.h, with appropriate conditionals.
Because,

* sometimes, cpp technique to check such values in
  compilation time is not easy. when I write a pre-C99
  cpp conditional to check the data model LP32 or LP64,
  it bloats 100 line:
  http://lists.gnu.org/archive/html/freetype-devel/2008-07/msg00010.html

* sometimes, it is impossible to guess the availability
  of a feature by the combination of standard macros.
  for example, the availability of PTHREAD cannot be
  written by the combination of standard macros in C89.

So, now I'm thinking of writing a configure that can
execute some checking for each architechtures and merge
them with appropriate conditionals. The outline I'm
thinking of is following:

# --------------------------------------------------------
	dnl
	dnl arch-free checking
	dnl

	...

	orig_CC=${CC}


	dnl 
	dnl make a list of symbolic name of architectures
	dnl 	because arch-speficying CFLAGS may includes a delimiter
	dnl and, make variables to get CFLAGS from symbolic names.
	dnl

	list_of_arch_names=""
	for cflags_for_an_arch in ${list_of_cflags_for_arch}
	do
		arch_name=`cflags-to-arch-name ${cflags_for_an_arch}`
		cpp_cond=`arch-to-cpp-cond ${cflags_for_an_arch}`
		list_of_arch_names="${list_of_arch_names} ${arch_name}"
		eval cflags_for_arch_${arch_name}=${cflags_for_an_arch}
		eval cond_for_arch_${arch_name}=${cpp_cond}
	done


	for an_arch in ${list_of_arch_names}
	do
		CC="${orig_CC} ${cflags_for_an_arch}" 

		dnl
		dnl arch-dependent checking
		dnl
		AC_CHECK_SIZEOF([...])
		...

		dnl
		dnl move values obtained by arch-dependent checking
		dnl

		cond='echo $cond_for_arch_'${arch_name}
		cond=`echo ${cond}`
		echo >> sample.h '#ifdef '${cond}
		echo >> sample.h '# define SIZEOF_XXX '${ac_cv_sizeof_xxx}
		...
		echo >> sample.h '#endif'

		unset ac_cv_...
		...
	done

	CC=${orig_CC}
# --------------------------------------------------------

A few small tools are needed.

1. A tool used in configure.ac, to maintain the arch-dependent
   values checked by configure. They should be flushed when
   a serie of arch-dependent checks is finished.

	KSH and BASH have a feature ${!prefix*} to obtain a list
	of shell variables with prefix, so it is possible to
	get a list of arch-dependent values by the comparison of
	the list of variable before arch-dependent checking and
	after arch-dependent checking. But I don't have good idea
	applicable to real Bourne shell.

2. A tool to obtain to find cpp conditional to specify an arch.
   In the outline in above, I called "arch-to-cpp-cond":
		cpp_cond=`arch-to-cpp-cond ${cflags_for_an_arch}`

	If we restrict the scope to GCC, "-dD" option is very
	useful to get a list of predefined cpp macros. I attached
	a sample sh script "cpp-cond.sh" to choose a cpp macro
	which can specify an architecture. It works aslike:

	$ env CC=gcc ./cpp-cond.sh "-march=i386" "-march=i486"
	checking cpp macro specific to -march=i386... __tune_i386__
	checking cpp macro specific to -march=i486... __tune_i486__

	At present, I don't have good idea to work with non-GNU
	C compilers without "-dD" option.

3. A tool to convert CFLAGS (multi-word must be accepted) to
   appropriate arch name. In the outline in above, I called 
   "cflags-to-arch-name",

		arch_name=`cflags-to-arch-name ${cflags_for_an_arch}`

4. A tool to merge multiple config.h with appropriate
   cpp conditionals.

	In the outline in above, the expected building procedure
	is Mac OS X, single command line causes multi-arch
	compilation.
	Of course, most Unix systems require separated compilation
	for each architectures. In such case, the arch-dependent
	part in config.h should be marked in each complation,
	and multiple config.h should be merged into single file.
	I'm trying to write an utility to do that, but I think
	such requirement may be popular and there might be existing
	tool.

Anyway, if I write everything out of Autoconf, the utilization
of them makes configure.ac difficult to maintain by other people.
I wish some of them are adoped in future Autoconf. So I want to
hear the comments from Autoconf maintainers about a generation
of config.h which supports multiple architechtures.

Regards,
mpsuzuki
#!/bin/sh

trap 'rm -f confdefs.opt_*.h confdefs.*_macros.h confdefs.*.keyword' 1 2 3 9 19



num_of_opt=$#
while [ $# -gt 0 ]
do
  cc_opt_name=`echo $1 | sed 's/[^0-9A-Za-z_]/_/g'`
  if test x = x"${cc_opt_name}"
  then
    cc_opt_name="NONE"
  fi
  eval ${cc_opt_name}=\"$1\"
  cc_opt_list="${cc_opt_list} ${cc_opt_name}"  
  shift
done




for cc_opt_name in ${cc_opt_list}
do
  get_opt_command="echo $"${cc_opt_name}
  eval cc_opt=`$get_opt_command`

  eval $get_opt_command | tr ' -+=.,' '\n\n\n\n\n\n' | sort -f | uniq > confdefs.opt_${cc_opt_name}.keyword
  echo | ${CC} ${CPPFLAGS} ${CFLAGS} ${cc_opt} -E -dD - | fgrep '#define' | sort -f | uniq > confdefs.opt_${cc_opt_name}.h
done





cat confdefs.opt_*.keyword | sort -f | uniq -c \
	| sed -n "/^ *1 */s/^ *1 *//p" > confdefs.unique.keyword

cat confdefs.opt_*.h | awk '{printf("#define %s \n", $2)}' | sort -f | uniq -c \
	| sed -n "/^ *${num_of_opt} *#/s/^ *${num_of_opt} *#/#/p" > confdefs.common_macros.h
cat confdefs.opt_*.h | sort -f | uniq -c \
	| sed -n "/^ *${num_of_opt} *#/s/^ *${num_of_opt} *#/#/p" > confdefs.same_macros.h
cat confdefs.opt_*.h | awk '{printf("#define %s \n", $2)}' \
	| fgrep -vf confdefs.common_macros.h | sort -f | uniq -c \
	| sed -n "/^ *1 *#/s/^ *1 *#/#/p" > confdefs.uniqbool_macros.h
cat confdefs.opt_*.h | fgrep -vf confdefs.uniqbool_macros.h | sort -f | uniq -c \
	| sed -n "/^ *1 *#/s/^ *1 *#/#/p" > confdefs.uniqvalue_macros.h





for cc_opt_name in ${cc_opt_list}
do
  get_opt_command="echo $"${cc_opt_name}
  eval cc_opt=`$get_opt_command`
  echo "checking cpp macro specific to ${cc_opt}..." | tr '\n' ' '

  opt_bool_macros=`fgrep -f confdefs.uniqbool_macros.h < confdefs.opt_${cc_opt_name}.h | awk '{printf(" %s", $2)}'`
  opt_value_macros=`fgrep -f confdefs.uniqvalue_macros.h < confdefs.opt_${cc_opt_name}.h | sed 's/#define \([^ ]*\) /\1=/g' | tr '\n' ' '`

  if test `echo ${opt_bool_macros} | wc -w` -gt 0
  then
    if test `echo ${opt_bool_macros} | tr ' ' '\n' | fgrep -f confdefs.unique.keyword | fgrep -f confdefs.opt_${cc_opt_name}.keyword | wc -l` -gt 0
    then
      opt_bool_macros=`echo ${opt_bool_macros} | tr ' ' '\n' | fgrep -f confdefs.unique.keyword | fgrep -f confdefs.opt_${cc_opt_name}.keyword | tail -1`
    elif test `echo ${opt_bool_macros} | tr ' ' '\n' | fgrep -vf confdefs.unique.keyword | fgrep -if confdefs.opt_${cc_opt_name}.keyword | wc -l` -gt 0
    then
      opt_bool_macros=`echo ${opt_bool_macros} | tr ' ' '\n' | fgrep -f confdefs.unique.keyword | fgrep -if confdefs.opt_${cc_opt_name}.keyword | tail -1`
    fi
    opt_bool_macros=`echo ${opt_bool_macros} | tr ' ' '\n' | tail -1`
    echo ${opt_bool_macros}
  elif test `echo ${opt_value_macros} | wc -w` -gt 0
  then
    if test `echo ${opt_value_macros} | tr ' ' '\n' | fgrep -vf confdefs.unique.keyword | fgrep -f confdefs.opt_${cc_opt_name}.keyword | wc -l` -gt 0
    then
      opt_value_macros=`echo ${opt_value_macros} | tr ' ' '\n' | fgrep -f confdefs.unique.keyword | fgrep -f confdefs.opt_${cc_opt_name}.keyword | tail -1`
    elif test `echo ${opt_value_macros} | tr ' ' '\n' | fgrep -vf confdefs.unique.keyword | fgrep -if confdefs.opt_${cc_opt_name}.keyword | wc -l` -gt 0
    then
      opt_value_macros=`echo ${opt_value_macros} | tr ' ' '\n' | fgrep -f confdefs.unique.keyword | fgrep -if confdefs.opt_${cc_opt_name}.keyword | tail -1`
    fi
    opt_value_macros=`echo ${opt_value_macros} | tr ' ' '\n' | tail -1`
    echo ${opt_value_macros}
  else
    echo "not found"
  fi
done

rm -f confdefs.opt_*.h confdefs.*_macros.h confdefs.*.keyword
_______________________________________________
Autoconf mailing list
Autoconf@xxxxxxx
http://lists.gnu.org/mailman/listinfo/autoconf

[Index of Archives]     [GCC Help]     [Kernel Discussion]     [RPM Discussion]     [Red Hat Development]     [Yosemite News]     [Linux USB]     [Samba]

  Powered by Linux