freetype-devel
[Top][All Lists]
Advanced

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

Re: [ft-devel] No support for side-by-side installation of x86-64and i38


From: mpsuzuki
Subject: Re: [ft-devel] No support for side-by-side installation of x86-64and i386
Date: Sat, 31 Dec 2005 22:00:29 +0900

On Tue, 27 Dec 2005 09:15:46 +0100 (CET)
Werner LEMBERG <address@hidden> wrote:

>> Just I've searched documents in libtool-1.5.22 & 2.1a, and libtool
>> mail list archive. In the latest CVS snapshot (2.1a), still multilib
>> support is written as future issue.
>
>OK.

Here I attach revised patch. It includes:
* ft-uniconf.m4
  utility macros to generate unified ftconfig.h
* configure.ac
  hook is added to generate ftconfig.h
* ftconfig.in
  add keyphrase to quote ABI-dependent part

I changed the feature name to uniconf, because
it does not built multi libraries, it just generates
unified ftconfig.h which is capable to use for both of
32 & 64bit ABIs on amd64, ppc64, sparc64 and s390x.

While I search "multilib" in libtool mail list archive,
I remember that "multilib" is also supported in recent
gcc, by config-ml.in. Taking a look on that, I think,
gcc config-ml.in is designed to work as meta-configure
level: it executes configure in separated directories
for each configurations (usually, gcc multilib is used
to support the CPUs whose FPU is optional (e.g. m68k
& ARM), CPUs whoese family is big and instruction sets
are defined (e.g. MIPS & ARM), and, finally, CPUs supports
both of 64- and 32bit ABI. I think gcc config-ml.in is
designed to build libraries for various configuration
at once, but it's not designed to generate unified config.h.

The goal of gcc config-ml.in is more generic than
RedHat's 64bit-32bit issue, but more specified than
that of libtool future plan. The goal of libtool multilib
is, I guess, to build libraries at once, for more
various configurations: archive/shared/debug/profiled
(as X11), untuned/tuned (as GNU libc), and 32/64bit ABI.
However, I don't think libtool is designed to distribute
the header files to suitable directories (e.g. Linux's
/usr/lib/freetype/include and /usr/lib64/freetype/include),
nor designed to unify the header files (as my patch does).
I think, such header file management is not libtool's
business.

Attached patch has ugly hook to flush informations
(sizeof(int) and sizeof(long)) for the default configuration
and reconfigure them for non-default target. I think
it's not easy to maintain. Because, when a developer
modifies configure.ac, he must care if it's reconfigured
in multilib case and he must know how to reset cached
informations (as I reset unset ac_cv_type_int etc).
He have to keep the integrity among ft-uniconf.m4,
configure.ac and ftconfig.in. This is troublesome work.

Now I think, the next step to improve multilib support
would be modification of freetype2/configure, instead
of freetype2/builds/unix/configure. It's like gcc config-ml.in.
By executing configure in separated directories, we can
collect ftconfig.h files for each configuration easily,
and exactly. I've already wrote several useful macros
for multilib support (they are in ft-uniconf.h):
* check how many object formats are available
* check required CFLAG for specified object format
* check CPP macro to specify the object format
The left task is gathering ftconfig.h from each
configured directories and merge them into single
unified ftconfig.h. I will propose a patch for
freetype2/configure to support. But, freetype2/configure
has not been autoconfized, so I'm afraid I should
not use macros in ft-uniconf.m4...?

Werner, could you tell me about the restriction to
modify that?

Regards,
mpsuzuki

--

diff -NBurb -x {arch} -x '.*' 
freetype2--mps-multilib--0.1--base-0/builds/unix/configure.ac 
freetype2--mps-multilib--0.1--patch-11/builds/unix/configure.ac
--- freetype2--mps-multilib--0.1--base-0/builds/unix/configure.ac       
2005-12-31 19:19:10.000000000 +0900
+++ freetype2--mps-multilib--0.1--patch-11/builds/unix/configure.ac     
2005-12-31 19:19:26.000000000 +0900
@@ -88,6 +89,23 @@
 AC_CHECK_SIZEOF([long])
 
 
+# generate unified header file, if requested
+
+FT_UNICONF_ENABLE([uniconf_type])
+FT_UNICONF_CFLAGS_GETLIST([uniconf_type],[cflags_to_check])
+if test x"${uniconf_type}" != xno; then
+  FT_UNICONF_PROG_OBJDUMP([OBJDUMP],[objdump_filter])
+fi
+if test x"${uniconf_type}" != xno && test x"${OBJDUMP}" != x; then
+  FT_UNICONF_MAKE_OBJFMT_LIST([${cflags_to_check}],[obj_fmt0 
obj_fmt1],[objdump_filter])
+  
FT_UNICONF_GET_CFLAG_FOR_OBJFMT([${cflags_to_check}],[obj_fmt0],[cflag_fmt0],[objdump_filter])
+  
FT_UNICONF_GET_CFLAG_FOR_OBJFMT([${cflags_to_check}],[obj_fmt1],[cflag_fmt1],[objdump_filter])
+fi
+if test x"${cflag_fmt0}" != x"${cflag_fmt1}"; then
+  FT_UNICONF_MAKE_ARCHDEP([arch_dep.tmp],[cflag_fmt0],[cflag_fmt1])
+fi
+
+
 # checks for library functions
 
 # Here we check whether we can use our mmap file component.
@@ -168,8 +186,10 @@
 AC_CONFIG_HEADERS([ftconfig.h:ftconfig.in],
   [mv ftconfig.h ftconfig.tmp
    sed 's|/undef|#undef|' < ftconfig.tmp > ftconfig.h
+   FT_UNICONF_FTCONFIG_H_CONVERT( [ftconfig.h], [ftconfig.tmp], [arch_dep.tmp] 
)
    rm ftconfig.tmp])
 
+
 # create the Unix-specific sub-Makefiles `builds/unix/unix-def.mk'
 # and 'builds/unix/unix-cc.mk' that will be used by the build system
 #
diff -NBurb -x {arch} -x '.*' 
freetype2--mps-multilib--0.1--base-0/builds/unix/ftconfig.in 
freetype2--mps-multilib--0.1--patch-11/builds/unix/ftconfig.in
--- freetype2--mps-multilib--0.1--base-0/builds/unix/ftconfig.in        
2005-12-31 19:19:10.000000000 +0900
+++ freetype2--mps-multilib--0.1--patch-11/builds/unix/ftconfig.in      
2005-12-31 19:29:45.000000000 +0900
@@ -60,8 +60,14 @@
 #undef HAVE_UNISTD_H
 #undef HAVE_FCNTL_H
 
+
+  /* ABI-dependent macros should be quoted by comments including keywords: */
+  /* ARCH_DEP_BEGIN and ARCH_DEP_END. The macros are defined conditionally */
+  /* by FT_UNICONF_MAKE_ARCHDEP. See ft-uniconf.m4 for detail.             */
+  /* ARCH_DEP_BEGIN */
 #undef SIZEOF_INT
 #undef SIZEOF_LONG
+  /* ARCH_DEP_END */
 
 
 #define FT_SIZEOF_INT   SIZEOF_INT
diff -NBurb -x {arch} -x '.*' 
freetype2--mps-multilib--0.1--base-0/builds/unix/ft-uniconf.m4 
freetype2--mps-multilib--0.1--patch-11/builds/unix/ft-uniconf.m4
--- freetype2--mps-multilib--0.1--base-0/builds/unix/ft-uniconf.m4      
1970-01-01 09:00:00.000000000 +0900
+++ freetype2--mps-multilib--0.1--patch-11/builds/unix/ft-uniconf.m4    
2005-12-31 21:52:08.000000000 +0900
@@ -0,0 +1,377 @@
+# Copyright 2002, 2003, 2004, 2005 by
+# suzuki toshiya and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+
+
+dnl
+dnl FT_UNICONF_ENABLE([enable_uniconf])
+dnl                          $1
+dnl
+dnl  add uniconf option to configure.
+dnl  passed value is stored in the first argument.
+dnl
+
+AC_DEFUN([FT_UNICONF_ENABLE],
+  [
+    ${RMF} ARCHDEP_TMP
+    AC_ARG_WITH([uniconf],
+                [  --enable-uniconf        make unified ftconfig.h for 
32/64bit ABI],
+                [], [])
+    case x"${enable_uniconf}" in
+    x )
+      $1="no"
+      ;;
+    xyes | x64_32 | xamd64 | xppc64 | xsparc64 | xs390x | xx86_64 )
+      $1="64_32"
+      ;;
+    esac
+  ])
+
+
+dnl
+dnl FT_UNICONF_LOOKUP_CFLAGS([enable_uniconf], [cflags_to_check])
+dnl                                 $1                $2
+dnl
+dnl   according to the first argument and ${host},
+dnl   fill the second argument by CFLAGs (separated by space).
+dnl   if uniconf is requested but unavailable, abort as error.
+dnl
+
+AC_DEFUN([FT_UNICONF_CFLAGS_GETLIST],
+  [
+    # prepare known CFLAGS for uniconf
+    case "${$1}":"${host}" in
+      64_32:amd64-*linux* | 64_32:x86_64-*linux* | \
+      64_32:ppc64-*linux* | 64_32:s390x-*linux*  | 64_32:sparc64-*linux* )
+        $2="-m64 -m32"
+        ;;
+
+      64_32:sparc*-*sunos[1-4].*   | 64_32:sparc*-*solaris1.* )
+        AC_MSG_ERROR([this platform is unsupported for uniconf configuration: 
${$1} ])
+        ;;
+      64_32:*-*sunos* | 64_32:x86_64-*sunos* )
+        case x"${CC}" in
+        *gcc* )
+          $2="-m64 -m32"
+          ;;
+        * ) # assume Sun Forte Studio
+          $2="-xtarget=generic64 -xtarget=generic32 -m64 -m32 -xarch=generic64 
-xarch=generic32"
+          ;;
+        esac
+        ;;
+      64_32:ia64-*aix* )
+        case x"${CC}" in
+        *gcc* )
+          $2="-m64 -m32"
+          ;;
+        * ) # assume IBM compiler
+          $2="-q64 -q32 -m64 -m32"
+          ;;
+        esac
+        ;;
+      64_32:ppc*-*aix* | 64_32:power*-aix* )
+        $2="-maix64 -m64 -m32"
+        ;;
+      no:* | NO:* )
+        ;;
+      *)
+        AC_MSG_ERROR([this platform is unsupported for uniconf configuration: 
${$1} ])
+        ;;
+    esac
+  ])
+
+dnl
+dnl FT_UNICONF_PROG_OBJDUMP([OBJDUMP], [objfmt_sed])
+dnl                             $1          $2
+dnl
+dnl  lookup a command to detect object file format
+dnl  the command is stored in the first argument
+dnl  and sed script (to remove unrequired info) is
+dnl  stored in the second argument.
+dnl
+
+AC_DEFUN([FT_UNICONF_PROG_OBJDUMP],
+  [
+    if test x"${OBJDUMP}" != x; then
+      $1="${OBJDUMP}"
+    else
+      if test x"${host}" != x"${build}"; then
+        AC_PATH_PROG($1, ${host}"-objdump", ${PATH})
+      fi
+      if test x"${$1}" = x ; then
+        AC_PATH_PROG($1, objdump, ${PATH})
+      fi
+      if test x"${$1}" != x ; then
+        $1="${$1} -p"
+        $2='/^ *$/d;s/^.* //'
+      else
+        AC_PATH_PROG($1, file, ${PATH})
+        $2='s/^[^:]*: //;s/, /,/g;y/ /_/'
+      fi
+      if test x"${$1}" = x ; then
+        AC_MSG_ERROR([no program to detect binary format])
+      fi
+    fi
+  ])
+
+
+dnl
+dnl FT_UNICONF_MAKE_OBJFMT_LIST( [cflag_0 cflag_1 ...],    $1
+dnl                              [obj_fmt0 obj_fmt1 ...],  $2
+dnl                              [objfmt_sed] )            $3
+dnl
+dnl   try each CFLAGs in the first argument (array of variable
+dnl   names) and count unique object format. the names of
+dnl   unique object format are stored in the second argument
+dnl   (array of variable names). don't expect obj_fmt0 is
+dnl   defined by cflag_0. obj_fmt1 is by cflag_1, etc.
+
+AC_DEFUN([FT_UNICONF_MAKE_OBJFMT_LIST],
+  [
+    for v in $2 NONE
+    do
+      if test $v != NONE; then
+        eval ${v}=""
+      fi
+    done
+    obj_fmt_max=`echo $2 | wc -w`
+    obj_fmt_num=0
+    CC_obj_default="${CC}"
+    echo "${$3}" > conftest.sed
+
+cat > conftest.c << EOF
+int test_func()
+{
+  return 0;
+}
+EOF
+    #
+    # 1st member of obj_fmt array is filled by default fmt
+    #
+    AC_MSG_CHECKING([default object format])
+    ${CC} ${XX_CFLAGS} ${CPPFLAGS} ${CFLAGS} -I. -c conftest.c
+    if test 0 != $?; then
+      AC_MSG_ERROR([compiler does not work])
+    fi
+    ${OBJDUMP} conftest.${OBJEXT} 2>/dev/null 1>/dev/null
+    if test 0 != $? ; then
+      AC_MSG_ERROR([cannot detect default object format])
+    fi
+
+    v=`echo $2 | awk '{print $[1]}'`
+    o=`${OBJDUMP} conftest.${OBJEXT} | tr '\t' ' ' | sed -f conftest.sed`
+    eval $"${v}"="${o}"
+    AC_MSG_RESULT([${o}])
+    obj_fmt_num=`echo ${obj_fmt_num} + 1 | bc`
+
+    #
+    # lookup non-default object formats
+    #
+    for cflag_test in $1 NONE
+    do
+      ${RMF} conftest.${OBJEXT}
+      if test ${obj_fmt_num} -lt ${obj_fmt_max} && test ${cflag_test} != NONE; 
then 
+        AC_MSG_CHECKING([${cflag_test} and its output])
+        CC=`echo "${CC_obj_default} x" | sed "s/ / ${cflag_test} /" | sed 
's,x$,,'`
+        ${CC} ${XX_CFLAGS} ${CPPFLAGS} ${CFLAGS} -I. -c conftest.c
+        if test 0 != $?; then
+          AC_MSG_RESULT([bad flag])
+       else
+          ${OBJDUMP} conftest.${OBJEXT} 2>/dev/null 1>/dev/null
+          if test 0 != $?; then
+            AC_MSG_RESULT([cannot detect format])
+         else
+            obj_fmt_test=`${OBJDUMP} conftest.${OBJEXT} | tr '\t' ' ' | sed -f 
conftest.sed`
+            for v in $2
+           do
+             eval o=$"$"${v}""
+             if test x"${o}" != x && test "${o}" = "${obj_fmt_test}"; then
+                AC_MSG_RESULT([${obj_fmt_test}, known])
+               obj_fmt_test=""
+             elif test x"${o}" = x && test x"${obj_fmt_test}" != x; then
+                AC_MSG_RESULT([${obj_fmt_test}, add as format${obj_fmt_num}])
+                obj_fmt_num=`echo ${obj_fmt_num} + 1 | bc`
+                eval ${v}="${obj_fmt_test}"
+               obj_fmt_test=""
+             fi
+           done
+         fi
+       fi
+      fi
+    done
+    ${RMF} conftest.c conftest.${OBJEXT} conftest.sed
+    CC="${CC_obj_default}"
+  ])
+
+
+dnl
+dnl FT_UNICONF_GET_CFLAG_FOR_OBJFMT([cflag_0  cflag_1...],  $1
+dnl                                 [obj_fmt],              $2
+dnl                                 [cflag_fmt],            $3
+dnl                                 [objfmt_sed])           $4
+dnl
+dnl   pick up the first cflag from the first argument (array
+dnl   of variable names) that can generate object file that
+dnl   is in format specified by the second argument. the matched
+dnl   cflag is stored in the third argument.
+dnl
+
+AC_DEFUN([FT_UNICONF_GET_CFLAG_FOR_OBJFMT],
+  [
+    AC_MSG_CHECKING([CFLAG to generate ${$2}])
+    CC_obj_default="${CC}"
+    echo "${$4}" > conftest.sed
+    $3=""
+cat > conftest.c << EOF
+int test_func()
+{
+  return 0;
+}
+EOF
+    for cflag_test in $1 NONE
+    do
+      ${RMF} conftest.${OBJEXT}
+      if test ${cflag_test} != NONE && test x"${$3}" = x; then 
+        CC=`echo "${CC_obj_default} x" | sed "s/ / ${cflag_test} /" | sed 
's,x$,,'`
+        ${CC} ${XX_CFLAGS} ${CPPFLAGS} ${CFLAGS} -I. -c conftest.c
+        if test 0 = $?; then
+         ${OBJDUMP} conftest.${OBJEXT} 2>/dev/null 1>/dev/null
+          if test 0 = $?; then
+            obj_fmt_test=`${OBJDUMP} conftest.${OBJEXT} | tr '\t' ' ' | sed -f 
conftest.sed`
+            eval o=$"$"$2""
+            if test "${o}" = "${obj_fmt_test}"; then
+             $3="${cflag_test}"
+           fi
+         fi
+       fi
+      fi
+    done
+    AC_MSG_RESULT([${$3}])
+    ${RMF} conftest.c conftest.${OBJEXT} conftest.sed
+    CC="${CC_obj_default}"
+  ])
+
+
+dnl
+dnl FT_UNICONF_MAKE_ARCHDEP([arch_dep.tmp],  $1
+dnl                         [cflag_fmt0],    $2
+dnl                         [cflag_fmt1] )   $3
+dnl                            
+dnl
+dnl  according to the CFLAGs given by the second and third
+dnl  arguments, generate (a part of) unified config.h.
+dnl  the name of unified config file is specified by
+dnl  the first argument.
+dnl  at present, sizeof(int) and sizeof(long) are only dealt.
+dnl
+dnl  for first, flush the cache of preconfigured values,
+dnl  and recheck with CFLAG to generate non-default object.
+dnl  if the results are same with default object file,
+dnl  (a part of) unified config file is not generated.
+dnl
+dnl  in second, test builtin CPP macros which may differ
+dnl  between default and non-default object file, and
+dnl  pickup the first suitable macro for conditional
+dnl  definitions of sizeof(int) and sizeof(long).
+dnl  if no suitable macro is found, abort as error.
+dnl
+dnl  in third, the unified configuration file is generated.
+dnl
+
+AC_DEFUN([FT_UNICONF_MAKE_ARCHDEP],
+  [
+    orig_CC="${CC}"
+    unset ac_cv_type_int
+    unset ac_cv_type_long
+
+    SIZEOF_INT_$2=${ac_cv_sizeof_int}
+    SIZEOF_LONG_$2=${ac_cv_sizeof_long}
+    CC=`echo "${CC} x" | sed "s/ / ${$3} /" | sed 's,x$,,'`
+    unset ac_cv_sizeof_int
+    unset ac_cv_sizeof_long
+    AC_CHECK_SIZEOF([int])
+    AC_CHECK_SIZEOF([long])
+    SIZEOF_INT_$3=${ac_cv_sizeof_int}
+    SIZEOF_LONG_$3=${ac_cv_sizeof_long}
+
+    CC="${orig_CC}"
+
+    if test x"${SIZEOF_INT_$2}"  = x"${SIZEOF_INT_$3}"   && \
+       test x"${SIZEOF_LONG_$2}" = x"${SIZEOF_LONG_$3}"; then
+      if test x"${$2}" != x"${$3}"; then
+        AC_MSG_WARN([sizeof(int), sizeof(long) are same in both platform])
+      fi
+    else
+      macro_fmt=""
+      AC_MSG_CHECKING([predefined cpp macro to identify platform])
+      for m in \
+        __LP64__ _LP64 __64BIT__ \
+        __arch64__ \
+        __x86_64__ __x86_64 __amd64__ __amd64 __i386__ __i386 i386 \
+        __ppc64__ __powerpc64__ __ppc64 \
+        __s390x__ __s390x \
+        __sparc64__ __sparc64 __sparcv9
+      do
+        echo ${m} | sed 's|.*|\"&\" &|' > conftest.c 
+        ${CPP} ${CPPFLAGS} ${$2} conftest.c | grep ${m} > conftest_$2.i
+        ${CPP} ${CPPFLAGS} ${$3} conftest.c | grep ${m} > conftest_$3.i
+        cmp conftest_$2.i conftest_$3.i 2>/dev/null 1>/dev/null
+        if test 0 != $?; then
+          if test x"${macro_fmt}" = x; then
+            AC_MSG_RESULT(${m})
+            macro_fmt=${m}
+            value_$2=`awk '{print $[2]}' < conftest_$2.i`
+            value_$3=`awk '{print $[2]}' < conftest_$3.i`
+          fi
+        fi
+      done
+      if test x"${macro_fmt}" = x; then
+        AC_MSG_ERROR([nothing found])
+      elif test x"${macro_fmt}" = x"${value_$2}"; then
+        ARCH_CONDITIONAL_$2='#if defined( '${macro_fmt}' )'
+        ARCH_CONDITIONAL_$3='#if !defined( '${macro_fmt}' )'
+      elif test x"${macro_fmt}" = x"${value_$3}"; then
+        ARCH_CONDITIONAL_$2='#if !defined( '${macro_fmt}' )'
+        ARCH_CONDITIONAL_$3='#if defined( '${macro_fmt}' )'
+      else
+        ARCH_CONDITIONAL_$2='#if '${macro_fmt}' == '${value_$2}
+        ARCH_CONDITIONAL_$3='#if '${macro_fmt}' == '${value_$3}
+      fi
+
+      echo >  $1 "${ARCH_CONDITIONAL_$2} /* default */"
+      echo >> $1 '#define  SIZEOF_INT   '${SIZEOF_INT_$2}
+      echo >> $1 '#define  SIZEOF_LONG  '${SIZEOF_LONG_$2}
+      echo >> $1 '#else /* non-default */'
+      echo >> $1 '#define  SIZEOF_INT   '${SIZEOF_INT_$3}
+      echo >> $1 '#define  SIZEOF_LONG  '${SIZEOF_LONG_$3}
+      echo >> $1 '#endif'
+    fi
+  ])
+
+
+dnl
+dnl FT_UNICONF_FTCONFIG_H_CONVERT([ftconfig.h],    $1
+dnl                               [ftconfig.tmp],  $2
+dnl                               [arch_dep.tmp] ) $3
+dnl
+dnl   replace the part in ftconfig.h (the file name is specified
+dnl   by the first argument) which is quoted by ARCH_DEP_BEGIN
+dnl   and ARCH_DEP_END, by (a part of) unified config.h (the file
+dnl   name is specified by the third argument). the file name for
+dnl   scratching use.
+
+AC_DEFUN([FT_UNICONF_FTCONFIG_H_CONVERT],
+  [
+    if test -r $1 && test -r $3 ; then
+      mv $1 $2
+      sed >  $1 < $2 -n '1,/ARCH_DEP_BEGIN/p'
+      cat >> $1 < $3
+      sed >> $1 < $2 -n '/ARCH_DEP_END/,$p'
+      ${RMF} $3
+    fi
+  ])




reply via email to

[Prev in Thread] Current Thread [Next in Thread]