[PATCH] winebuild: Use Clang to assemble if found.

Charles Davis cdavis5x at gmail.com
Mon Jan 21 11:15:58 CST 2013


Try 3: Always invoke Clang if it is found.

The configure script invokes the system compiler to figure out if .cfi
pseudo-ops are supported, on the assumption that it will invoke the
system assembler. Winebuild, on the other hand, invokes the system
assembler directly. This caused a problem on Mac OS hosts when compiling
with Clang: configure would detect that .cfi ops were supported, because
Clang's integrated assembler supports them; however, when winebuild then
emitted assembly with .cfi ops in them, the system assembler would then
choke. This patch makes winebuild invoke Clang's assembler if it is
found in the path.

Note that if you have Clang installed, winebuild will now always invoke
it to assemble. Should we always make winebuild invoke the compiler like
this?
---
 tools/winebuild/utils.c | 84 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 65 insertions(+), 19 deletions(-)

diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c
index 559e476..31f6042 100644
--- a/tools/winebuild/utils.c
+++ b/tools/winebuild/utils.c
@@ -277,6 +277,31 @@ void spawn( struct strarray *args )
     }
 }
 
+/* test if a particular tool exists in the PATH and can be executed */
+char *test_tool( const char *name, char **dirs, unsigned int count, unsigned int maxlen )
+{
+    char *p, *file;
+    unsigned int i, len;
+    struct stat st;
+
+    len = strlen(name) + sizeof(EXEEXT) + 1;
+    file = xmalloc( maxlen + len );
+
+    for (i = 0; i < count; i++)
+    {
+        strcpy( file, dirs[i] );
+        p = file + strlen(file);
+        if (p == file) *p++ = '.';
+        if (p[-1] != '/') *p++ = '/';
+        strcpy( p, name );
+        strcat( p, EXEEXT );
+
+        if (!stat( file, &st ) && S_ISREG(st.st_mode) && (st.st_mode & 0111)) return file;
+    }
+    free( file );
+    return NULL;
+}
+
 /* find a build tool in the path, trying the various names */
 char *find_tool( const char *name, const char * const *names )
 {
@@ -285,10 +310,7 @@ char *find_tool( const char *name, const char * const *names )
 
     char *p, *file;
     const char *alt_names[2];
-    unsigned int i, len;
-    struct stat st;
-
-    if (target_alias) return strmake( "%s-%s", target_alias, name );
+    unsigned int i;
 
     if (!dirs)
     {
@@ -319,26 +341,27 @@ char *find_tool( const char *name, const char * const *names )
         names = alt_names;
     }
 
-    while (*names)
+    /* If we have a target triple, we really need to try the list of names
+     * twice: once with the triple, and once without.
+     */
+    if (target_alias)
     {
-        len = strlen(*names) + sizeof(EXEEXT) + 1;
-        file = xmalloc( maxlen + len );
-
-        for (i = 0; i < count; i++)
+        const char *const *n = names;
+        while (*n)
         {
-            strcpy( file, dirs[i] );
-            p = file + strlen(file);
-            if (p == file) *p++ = '.';
-            if (p[-1] != '/') *p++ = '/';
-            strcpy( p, *names );
-            strcat( p, EXEEXT );
-
-            if (!stat( file, &st ) && S_ISREG(st.st_mode) && (st.st_mode & 0111)) return file;
+            file = test_tool( *n, dirs, count, maxlen );
+            if (file) return file;
+            n++;
         }
-        free( file );
+    }
+
+    while (*names)
+    {
+        file = test_tool( *names, dirs, count, maxlen );
+        if (file) return file;
         names++;
     }
-    return xstrdup( name );
+    return NULL;
 }
 
 struct strarray *get_as_command(void)
@@ -346,12 +369,28 @@ struct strarray *get_as_command(void)
     struct strarray *args = strarray_init();
 
     if (!as_command)
+        as_command = find_tool( "clang", NULL );
+
+    if (!as_command)
     {
         static const char * const commands[] = { "gas", "as", NULL };
         as_command = find_tool( "as", commands );
     }
+
+    if (!as_command)
+        fatal_error( "cannot find suitable assembler\n" );
+
     strarray_add_one( args, as_command );
 
+    if (strstr( as_command, "clang" ))
+    {
+        strarray_add( args, as_command, "-xassembler", "-c", NULL );
+        if (force_pointer_size)
+            strarray_add_one( args, (force_pointer_size == 8) ? "-m64" : "-m32" );
+        if (cpu_option) strarray_add_one( args, strmake("-mcpu=%s", cpu_option) );
+        return args;
+    }
+
     if (force_pointer_size)
     {
         switch (target_platform)
@@ -386,6 +425,10 @@ struct strarray *get_ld_command(void)
         static const char * const commands[] = { "ld", "gld", NULL };
         ld_command = find_tool( "ld", commands );
     }
+
+    if (!ld_command)
+        fatal_error( "cannot find suitable linker\n" );
+
     strarray_add_one( args, ld_command );
 
     if (force_pointer_size)
@@ -421,6 +464,9 @@ const char *get_nm_command(void)
         static const char * const commands[] = { "nm", "gnm", NULL };
         nm_command = find_tool( "nm", commands );
     }
+
+    if (!nm_command)
+        fatal_error( "cannot find suitable name lister\n" );
     return nm_command;
 }
 
-- 
1.7.12.4




More information about the wine-patches mailing list