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