Le samedi 9 juillet 2011 20:44:47, grischka a écrit :
> Thomas Preud'homme wrote:
> > First let's focus on multilib as you said.
> 
> Actually I said "multilib" because you said "multilib".  Which
> means that I've no idea really what it means.
Ah? Ok nevermind. Usually I talk about multiarch but that's not important. 
Let's continue on multilib then.
> 
> > The requirement for multilib is suffix all path from search paths
> > (whatever are these search paths: include search path, library search
> > paths, etc…) by the multilib subdirectory,
> 
> Okay, but then I think that tcc doesn't really have to know all
> that either.  It is just a matter that you can configure as many
> paths as you want in one CONFIG_option.
> 
> Which you have now with the colon separated strings.
True. That's why the first patch tried to do it that way. But it's a bit more 
annoying than the current approach since you have to change all the search 
paths by duplicating them (A:B:C would become 
A/<triplet>:A:B/<triplet>:B:C/<triplet>:C) just to say you want for each 
directory to also try first with <triplet> subdirectory.
> 
> There is also the addition of certain prefixes in tcc_split_path,
> which you don't really need, I assume (and as such would conflict
> with the spirit of tinyness ;).
I agree, it's ugly. I wanted to keep the / and /usr/local prefix in the tcc and 
only specify the subdirectories. But I think this logic should still be needed 
somewhere else anyway — most likely in configure — to make things less painful 
with regards of sysroot. The user should only need to specify something like:
/lib/<triplet>:/lib:/usr/local/lib/<triplet>:/usr/local/lib and configure would 
prepend $sysroot if needed.
> 
> So then it is just a matter of integrating the new feature into
> existing code.
> 
> For example instead of
> 
>      tcc_add_library_path(s, CONFIG_TCC_CRT_PREFIX);
>      tcc_add_library_path(s, CONFIG_SYSROOT CONFIG_TCC_LDDIR);
>      tcc_add_library_path(s, CONFIG_SYSROOT "/usr/local"CONFIG_TCC_LDDIR);
> 
> I'd suggest:
> 
>      tcc_add_library_paths(s, CONFIG_TCC_LIBPATH);
> 
> with in tcc.h:
> 
>      #ifndef CONFIG_TCC_LIBPATH
>      # define CONFIG_TCC_LIBPATH \
>         CONFIG_TCC_CRT_PREFIX ":" \
>         CONFIG_SYSROOT CONFIG_TCC_LDDIR ":" \
>         CONFIG_SYSROOT "/usr/local"CONFIG_TCC_LDDIR);
>      #endif
> 
> which brings us further to have all data in one place (and closer
> to Rob Landley's approach from several years ago which is maybe or
> maybe not a coincidence :).
>      http://lists.gnu.org/archive/html/tinycc-devel/2011-07/msg00013.html
Agreed.
> 
> Plus you don't need CONFIG_TCC_EXTRA_LDDIR because you can simply
> override CONFIG_TCC_LIBPATH.
Agreed again.

But I'd still appreciate a --multilib=<triplet> switch in *complement*. This 
way if you want to add multilib but don't change the default paths, you just 
have to add one switch instead of a long --libpath=<colon_separated_path>.

I wrote the code yesterday. Please take a look. Still missing is the handling 
of elf_interp but this must be added anyway without this option.

By the way, is this normal that only X86_64 ld.so uses CONFIG_TCC_LDDIR or 
does the other ld.so also lack the use of this macro?
> 
> --- grischka
Best regards.

Thomas Preud'homme
From 96770d89d7857088d41d388113cb7f9b59093aec Mon Sep 17 00:00:00 2001
From: Thomas Preud'homme <[email protected]>
Date: Sat, 9 Jul 2011 12:04:15 +0200
Subject: [PATCH] Add multilib

---
 configure |   38 ++++++++++++++++----------
 libtcc.c  |   89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 libtcc.h  |    8 +++++
 tcc.h     |    3 ++
 tccelf.c  |    4 +-
 5 files changed, 117 insertions(+), 25 deletions(-)

diff --git a/configure b/configure
index d2049af..ea410e4 100755
--- a/configure
+++ b/configure
@@ -26,6 +26,7 @@ prefix=""
 execprefix=""
 bindir=""
 libdir=""
+multilib_subdir=""
 tccdir=""
 includedir=""
 mandir=""
@@ -108,6 +109,8 @@ for opt do
   ;;
   --libdir=*) libdir=`echo $opt | cut -d '=' -f 2`
   ;;
+  --multilib-subdir=*) multilib_subdir=`echo $opt | cut -d '=' -f 2`
+  ;;
   --includedir=*) includedir=`echo $opt | cut -d '=' -f 2`
   ;;
   --sharedir=*) sharedir=`echo $opt | cut -d '=' -f 2`
@@ -252,6 +255,7 @@ echo "Advanced options (experts only):"
 echo "  --source-path=PATH       path of source code [$source_path]"
 echo "  --cross-prefix=PREFIX    use PREFIX for compile tools [$cross_prefix]"
 echo "  --sysroot=PREFIX         prepend PREFIX to library/include paths []"
+echo "  --multilib_subdir=DIR    multilib subdirectory in DIR []"
 echo "  --cc=CC                  use C compiler CC [$cc]"
 echo "  --disable-static         make libtcc.so instead of libtcc.a"
 echo "  --disable-rpath          disable use of -rpath with the above"
@@ -322,21 +326,22 @@ if test x"$includedir" = x""; then
 includedir="${prefix}/include"
 fi
 
-echo "Binary  directory   $bindir"
-echo "TinyCC directory    $tccdir"
-echo "Library directory   $libdir"
-echo "Include directory   $includedir"
-echo "Manual directory    $mandir"
-echo "Info directory      $infodir"
-echo "Doc directory       $docdir"
-echo "Target root prefix  $sysroot"
-echo "Source path      $source_path"
-echo "C compiler       $cc"
-echo "CPU              $cpu"
-echo "Big Endian       $bigendian"
-echo "gprof enabled    $gprof"
-echo "cross compilers  $build_cross"
-echo "use libgcc       $use_libgcc"
+echo "Binary  directory      $bindir"
+echo "TinyCC directory       $tccdir"
+echo "Library directory      $libdir"
+echo "Multilib subdirectory  $multilib_subdir"
+echo "Include directory      $includedir"
+echo "Manual directory       $mandir"
+echo "Info directory         $infodir"
+echo "Doc directory          $docdir"
+echo "Target root prefix     $sysroot"
+echo "Source path            $source_path"
+echo "C compiler             $cc"
+echo "CPU                    $cpu"
+echo "Big Endian             $bigendian"
+echo "gprof enabled          $gprof"
+echo "cross compilers        $build_cross"
+echo "use libgcc             $use_libgcc"
 
 echo "Creating config.mak and config.h"
 
@@ -357,6 +362,9 @@ echo "#define CONFIG_SYSROOT \"$sysroot\"" >> $TMPH
 echo "#ifndef CONFIG_TCCDIR" >> $TMPH
 echo "#define CONFIG_TCCDIR \"$tccdir\"" >> $TMPH
 echo "#endif" >> $TMPH
+if test -n "$multilib_subdir" ; then
+  echo "#define CONFIG_TCC_MULTILIB_SUBDIR \"$multilib_subdir\"" >> $TMPH
+fi
 echo "CC=$cc" >> config.mak
 echo "GCC_MAJOR=$gcc_major" >> config.mak
 echo "#define GCC_MAJOR $gcc_major" >> $TMPH
diff --git a/libtcc.c b/libtcc.c
index f97336e..0699911 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -968,9 +968,9 @@ LIBTCCAPI TCCState *tcc_new(void)
     
 #ifndef TCC_TARGET_PE
     /* default library paths */
-    tcc_add_library_path(s, CONFIG_TCC_CRT_PREFIX);
-    tcc_add_library_path(s, CONFIG_SYSROOT CONFIG_TCC_LDDIR);
-    tcc_add_library_path(s, CONFIG_SYSROOT "/usr/local"CONFIG_TCC_LDDIR);
+    tcc_add_syslibrary_path(s, CONFIG_TCC_CRT_PREFIX);
+    tcc_add_syslibrary_path(s, CONFIG_SYSROOT CONFIG_TCC_LDDIR);
+    tcc_add_syslibrary_path(s, CONFIG_SYSROOT "/usr/local"CONFIG_TCC_LDDIR);
 #endif
 
     /* no section zero */
@@ -1036,6 +1036,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1)
 
     /* free library paths */
     dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
+    dynarray_reset(&s1->syslibrary_paths, &s1->nb_syslibrary_paths);
 
     /* free include paths */
     dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
@@ -1070,6 +1071,17 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
 {
     char *pathname1;
     
+#ifdef CONFIG_TCC_MULTILIB_SUBDIR
+    {
+        int len;
+        char *pathname2;
+
+        len = strlen(pathname) + strlen(CONFIG_TCC_MULTILIB_SUBDIR) + 2;
+        pathname2 = tcc_malloc(len);
+        snprintf(pathname2, len, "%s/%s", pathname, CONFIG_TCC_MULTILIB_SUBDIR);
+        dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname2);
+    }
+#endif
     pathname1 = tcc_strdup(pathname);
     dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
     return 0;
@@ -1093,6 +1105,18 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
 #endif
 
     /* open the file */
+#ifdef CONFIG_TCC_MULTILIB_SUBDIR
+    if (flags & AFF_MULTILIB) {
+        char *base, buf[1024];
+
+        base = tcc_basename(filename);
+        snprintf(buf, sizeof(buf), "%.*s/%s/%s", (int) (base - filename - 1),
+                 filename, CONFIG_TCC_MULTILIB_SUBDIR, base);
+        ret = tcc_open(s1, buf);
+        if (ret >= 0)
+            goto file_opened;
+    }
+#endif
     ret = tcc_open(s1, filename);
     if (ret < 0) {
         if (flags & AFF_PRINT_ERROR)
@@ -1100,6 +1124,9 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
         return ret;
     }
 
+#ifdef CONFIG_TCC_MULTILIB_SUBDIR
+file_opened:
+#endif
     /* update target deps */
     dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
             tcc_strdup(filename));
@@ -1196,14 +1223,24 @@ the_end:
     return ret;
 }
 
-LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
+ST_FUNC int tcc_add_file2(TCCState *s, const char *filename, int flags)
 {
     dynarray_add((void ***)&s->input_files, &s->nb_input_files, tcc_strdup(filename));
 
     if (s->output_type == TCC_OUTPUT_PREPROCESS)
-        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS);
+        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS | flags);
     else
-        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
+        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | flags);
+}
+
+LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
+{
+    return tcc_add_file2(s, filename, 0);
+}
+
+LIBTCCAPI int tcc_add_sysfile(TCCState *s, const char *filename)
+{
+    return tcc_add_file2(s, filename, AFF_MULTILIB);
 }
 
 LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
@@ -1215,6 +1252,26 @@ LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
     return 0;
 }
 
+LIBTCCAPI int tcc_add_syslibrary_path(TCCState *s, const char *pathname)
+{
+    char *pathname1;
+
+#ifdef CONFIG_TCC_MULTILIB_SUBDIR
+    {
+        int len;
+        char *pathname2;
+
+        len = strlen(pathname) + strlen(CONFIG_TCC_MULTILIB_SUBDIR) + 2;
+        pathname2 = tcc_malloc(len);
+        snprintf(pathname2, len, "%s/%s", pathname, CONFIG_TCC_MULTILIB_SUBDIR);
+        dynarray_add((void ***)&s->syslibrary_paths, &s->nb_syslibrary_paths, pathname2);
+    }
+#endif
+    pathname1 = tcc_strdup(pathname);
+    dynarray_add((void ***)&s->syslibrary_paths, &s->nb_syslibrary_paths, pathname1);
+    return 0;
+}
+
 /* find and load a dll. Return non zero if not found */
 /* XXX: add '-rpath' option support ? */
 ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
@@ -1228,6 +1285,14 @@ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
         if (tcc_add_file_internal(s, buf, flags) == 0)
             return 0;
     }
+#ifdef CONFIG_TCC_MULTILIB_SUBDIR
+    for(i = 0; i < s->nb_syslibrary_paths; i++) {
+        snprintf(buf, sizeof(buf), "%s/%s",
+                 s->syslibrary_paths[i], filename);
+        if (tcc_add_file_internal(s, buf, flags) == 0)
+            return 0;
+    }
+#endif
     return -1;
 }
 
@@ -1257,6 +1322,14 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
         if (tcc_add_file_internal(s, buf, 0) == 0)
             return 0;
     }
+#ifdef CONFIG_TCC_MULTILIB_SUBDIR
+    for (i = 0; i < s->nb_syslibrary_paths; i++) {
+        snprintf(buf, sizeof(buf), "%s/lib%s.a",
+                 s->syslibrary_paths[i], libraryname);
+        if (tcc_add_file_internal(s, buf, 0) == 0)
+            return 0;
+    }
+#endif
     return -1;
 }
 
@@ -1327,8 +1400,8 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
     if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
         !s->nostdlib) {
         if (output_type != TCC_OUTPUT_DLL)
-            tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
-        tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
+            tcc_add_sysfile(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
+        tcc_add_sysfile(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
     }
 #endif
 
diff --git a/libtcc.h b/libtcc.h
index bf328d3..90735f8 100644
--- a/libtcc.h
+++ b/libtcc.h
@@ -56,6 +56,11 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);
    script). Return -1 if error. */
 LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);
 
+/* add a system file (either a C file, dll, an object, a library or an
+   ld script). This file will also be searched in multilib subdir.
+   Return -1 if error. */
+LIBTCCAPI int tcc_add_sysfile(TCCState *s, const char *filename);
+
 /* compile a string containing a C source. Return non zero if
    error. */
 LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
@@ -79,6 +84,9 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
 /* equivalent to -Lpath option */
 LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);
 
+/* Each system library path is searched with and without multilib subdir */
+LIBTCCAPI int tcc_add_syslibrary_path(TCCState *s, const char *pathname);
+
 /* the library name is the same as the argument of the '-l' option */
 LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);
 
diff --git a/tcc.h b/tcc.h
index fcbfadc..b66e486 100644
--- a/tcc.h
+++ b/tcc.h
@@ -423,6 +423,8 @@ struct TCCState {
 
     char **library_paths;
     int nb_library_paths;
+    char **syslibrary_paths;
+    int nb_syslibrary_paths;
 
     /* array of all loaded dlls (including those referenced by loaded
        dlls) */
@@ -900,6 +902,7 @@ ST_DATA void *rt_prog_main;
 #define AFF_PRINT_ERROR     0x0001 /* print error if file not found */
 #define AFF_REFERENCED_DLL  0x0002 /* load a referenced dll from another dll */
 #define AFF_PREPROCESS      0x0004 /* preprocess file */
+#define AFF_MULTILIB        0x0008 /* also search multilib subdir */
 
 /* public functions currently used by the tcc main function */
 PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s);
diff --git a/tccelf.c b/tccelf.c
index 8d91daa..e1fedea 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -1253,7 +1253,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
     if (!s1->nostdlib) {
 #ifdef CONFIG_USE_LIBGCC
         tcc_add_library(s1, "c");
-        tcc_add_file(s1, CONFIG_SYSROOT CONFIG_TCC_LDDIR"/libgcc_s.so.1");
+        tcc_add_sysfile(s1, CONFIG_SYSROOT CONFIG_TCC_LDDIR"/libgcc_s.so.1");
 #else
         tcc_add_library(s1, "c");
 #ifndef WITHOUT_LIBTCC
@@ -1267,7 +1267,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
     }
     /* add crt end if not memory output */
     if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
-        tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
+        tcc_add_sysfile(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
     }
 }
 
-- 
1.7.5.4

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to