Commits

Adam Butcher committed e484dc0

Support .SYSLIBDIRS and CROSS_SYSROOT. See make.texi for details.

Comments (0)

Files changed (5)

 You can turn off link library expansion completely by setting this
 variable to an empty value.
 
+The default paths to be searched for libraries can be overridden via
+the @code{.SYSLIBDIRS} variable.  Each word in the value of this
+variable is a path to be searched.  Setting the variable to empty
+removes all default search locations.
+
+The default search path for libraries is also influenced by the
+@code{CROSS_SYSROOT} environment variable.  This is useful for
+cross-compilation where searching for dependent libraries in the build
+system's paths is almost never useful.  @code{CROSS_SYSROOT} is
+expected to be an absolute path.  It will be used as a prefix for the
+/lib and /usr/lib search paths.  If @code{CROSS_SYSROOT} is set, the
+directory @var{prefix}/lib is not considered.
+
 @node Phony Targets, Force Targets, Directory Search, Rules
 @section Phony Targets
 @cindex phony targets
   /* define_variable_cname (".TARGETS", "", o_default, 0)->special = 1; */
   define_variable_cname (".RECIPEPREFIX", "", o_default, 0)->special = 1;
   define_variable_cname (".SHELLFLAGS", "-c", o_default, 0);
+  define_variable_cname (SYSLIBDIRS_NAME, "", o_default, 0)->special = 1;
 
   /* Set up .FEATURES
      Use a separate variable because define_variable_cname() is a macro and
   {
     const char *features = "target-specific order-only second-expansion"
                            " else-if shortest-stem undefine oneshell"
+                           " syslibdirs"
 #ifndef NO_ARCHIVES
                            " archives"
 #endif
                              o_env, 1);
     }
 
+  /* If CROSS_SYSROOT set in calling environment, then provide default
+     .SYSLIBDIRS relative to it. */
+  {
+    struct variable *v = lookup_variable (STRING_SIZE_TUPLE ("CROSS_SYSROOT"));
+    if (v != 0 && v->value[0] != '\0')
+      {
+	/* CROSS_SYSROOT/lib CROSS_SYSROOT/usr/lib */
+	int prefix_len = strlen (v->value) * 2
+	  + 1 /* space */ + 4 /* /lib */ + 8 /* /usr/lib */ + 1 /* NUL */;
+	char *syslibdirs = xmalloc (prefix_len);
+	sprintf (syslibdirs, "%s/lib %s/usr/lib", v->value, v->value);
+	define_variable_cname (SYSLIBDIRS_NAME, syslibdirs, o_default, 0);
+	set_default_library_search_path (syslibdirs);
+	free (syslibdirs);
+      }
+  }
+
   /* If there were -C flags, move ourselves about.  */
   if (directories != 0)
     {
 #define RECIPEPREFIX_DEFAULT       '\t'
 extern char cmd_prefix;
 
+/* Support for setting custom default system library search path. */
+#define SYSLIBDIRS_NAME            ".SYSLIBDIRS"
+void set_default_library_search_path(const char *dirlist);
+
 extern unsigned int job_slots;
 extern int job_fds[2];
 extern int job_rfd;
 /* Current value for pruning the scan of the goal chain (toggle 0/1).  */
 static unsigned int considered;
 
+/* Support for .SYSLIBDIRS and CROSS_SYSROOT.  See library_search(). */
+static char **syslibdirs = 0;
+
 static int update_file (struct file *file, unsigned int depth);
 static int update_file_1 (struct file *file, unsigned int depth);
 static int check_dep (struct file *file, unsigned int depth,
 }
 
 
+void set_default_library_search_path(const char *dirlist)
+{
+  static const char spaces[] = " \t";
+  size_t wc = 0;
+
+  /* Passing null dirlist or empty string frees the custom list */
+  if (dirlist == 0 || *dirlist == '\0')
+    {
+      if (syslibdirs)
+	{
+	  char **it = syslibdirs;
+	  while (*it)
+	    free (*it++);
+	  free (syslibdirs);
+	}
+      syslibdirs = 0;
+      return;
+    }
+
+  /* Count words */
+  {
+    const char *w = dirlist;
+    for (; *(w += strspn (w, spaces)); w += strcspn (w, spaces))
+      ++wc;
+  }
+
+  /* Build path list */
+  {
+    char **dir = syslibdirs = calloc (wc + 1, sizeof (char*));
+    while (*(dirlist += strspn (dirlist, spaces)))
+      {
+	size_t span = strcspn (dirlist, spaces);
+	*dir = malloc (span + 1);
+	(*dir)[span] = 0;
+	memcpy (*dir, dirlist, span);
+	dirlist += span;
+	++dir;
+      }
+  }
+}
+
+
 /* Search for a library file specified as -lLIBNAME, searching for a
    suitable library file in the system library directories and the VPATH
    directories.  */
 static const char *
 library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
 {
-  static char *dirs[] =
+  static char *builtin_dirs[] =
     {
 #ifndef _AMIGA
       "/lib",
   /* Information about the earliest (in the vpath sequence) match.  */
   unsigned int best_vpath = 0, best_path = 0;
 
+  char **dirs = syslibdirs? syslibdirs : builtin_dirs;
   char **dp;
 
   libpatterns = xstrdup (variable_expand ("$(.LIBPATTERNS)"));
          properly.  */
       cmd_prefix = var->value[0]=='\0' ? RECIPEPREFIX_DEFAULT : var->value[0];
     }
+  else if (streq (var->name, SYSLIBDIRS_NAME))
+    {
+      set_default_library_search_path (var->value);
+    }
 
   return var;
 }