public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC] Adding some rpath support.
@ 2001-09-20 11:56 Theodore Papadopoulo
  0 siblings, 0 replies; only message in thread
From: Theodore Papadopoulo @ 2001-09-20 11:56 UTC (permalink / raw)
  To: gcc

This message is essentially submitted for discussion and advices for 
improvements if the proposal meets some support.

Sometime ago, it has been discussed extensively whether or gcc should insert the -R (or equivalent)
directives for libgcc.so and others. There was not really a consensus as far as I can tell, but
some people seemed to be interested to have such a thing (mostly people installing and using
their own installed gcc and that do not have root priviledges to add in one way or the other
the gcc libs to the ld.so cache). Others considered that most people will install a distribution
consider that this is the distributor task, so that such a thing was 
unneeded...

There was also a comment (by Alexandre Oliva if I remember correctly), that it might be nice to provide
to gcc users a platform 
independent way of specifying the runpath at link time (as opposed to -R for Solaris,
-Wl,-rpath... for linux, etc). This is not the topic of this patch/proposal, but the 
problem of defining the proper falg to pass to the linker is related.

Since it is really painful and/or ugly to define the LD_LIBRARY_PATH each time I run a gcc-3.0
compiled program, and since there is no real consensus AFAICT, I have tried to provide the functionnality
directly in gcc for me (tweaking the spec file did not work very well in all the situations) but it 
have been careful to keep it just as a configuration option (--enable-runpath). This is currently done only
for linux (I'm not even very sure what is the proper place where to put the RUNPATH_FLAG definition, so that
I prefer to get some comments before eventually going further).

I have been bootstrapped and used this code several times now, without any problem (some errors might
be in the patch below since I had to solve some conflicts and have not re-bootstrapped since then, but I hope not).

I verified that if gcc is moved, then it is sufficient (for linux) to define a LD_LIBRARY_PATH so that
using programs compiled with gcc is no more complicated than it is now. Of course, I may have overlooked
some situations.

The patch is simpler than it looks.  Basically, it creates a new function do_lib_spec in gcc.c and uses
it. Even without the rpath extension it might still be useful as it makes IMHO the code more readable.
The rpath stuff is then just a matter of a few lines.

I also spotted several places where sequences of strcpy and strcat could be replaced by a single concat.
There were some more places, but those are using alloca, so I did not changed them.

I would be glad to hear any comment about this tiny proposal.
    
    Theo.

ChangeLog for gcc:

2000-08-13 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>

    * gcc.c (do_lib_spec): New function.
    (do_spec_1): Use it.
    (find_a_file): Use concat.

Index: gcc/config.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config.in,v
retrieving revision 1.117
diff -c -3 -p -r1.117 config.in
*** config.in	2001/09/11 16:49:53	1.117
--- config.in	2001/09/20 18:11:24
***************
*** 275,280 ****
--- 275,283 ----
     other memory allocation checks.  This is quite expensive. */
  #undef ENABLE_GC_CHECKING
  
+ /* Define if you want run path directives to be inserted in the spec file. */
+ #undef ENABLE_RUNPATH
+ 
  /* Define if you want the garbage collector to operate in maximally
     paranoid mode, validating the entire heap and collecting garbage at
     every opportunity.  This is extremely expensive. */
Index: gcc/configure.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/configure.in,v
retrieving revision 1.540
diff -c -3 -p -r1.540 configure.in
*** configure.in	2001/09/12 16:15:55	1.540
--- configure.in	2001/09/20 18:11:25
*************** changequote([, ])dnl
*** 176,181 ****
--- 176,186 ----
    fi
  fi
  
+ # Enable the insertion of runpath directives for GCC libraries.
+ AC_ARG_ENABLE(runpath,
+ [  --enable-runpath        enable to insert run path directives in the spec file],
+ [AC_DEFINE(ENABLE_RUNPATH, 1, [Define if you want run path directives to be inserted in the spec file.])], [])
+ 
  # Determine whether or not multilibs are enabled.
  AC_ARG_ENABLE(multilib,
  [  --enable-multilib       enable library support for multiple ABIs],
Index: gcc/gcc.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gcc.c,v
retrieving revision 1.252
diff -c -3 -p -r1.252 gcc.c
*** gcc.c	2001/09/17 22:15:10	1.252
--- gcc.c	2001/09/20 18:11:26
*************** static void clear_failure_queue PARAMS (
*** 289,294 ****
--- 289,295 ----
  static int check_live_switch	PARAMS ((int, int));
  static const char *handle_braces PARAMS ((const char *));
  static char *save_string	PARAMS ((const char *, int));
+ static void do_lib_spec         PARAMS ((char *));
  static int do_spec_1		PARAMS ((const char *, int, const char *));
  static const char *find_file	PARAMS ((const char *));
  static int is_directory		PARAMS ((const char *, const char *, int));
*************** find_a_file (pprefix, name, mode)
*** 2434,2444 ****
       const char *name;
       int mode;
  {
!   char *temp;
    const char *const file_suffix =
      ((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "");
    struct prefix_list *pl;
-   int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1;
  
  #ifdef DEFAULT_ASSEMBLER
    if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0)
--- 2435,2444 ----
       const char *name;
       int mode;
  {
!   char *temp = NULL;
    const char *const file_suffix =
      ((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "");
    struct prefix_list *pl;
  
  #ifdef DEFAULT_ASSEMBLER
    if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0)
*************** find_a_file (pprefix, name, mode)
*** 2450,2469 ****
      return xstrdup (DEFAULT_LINKER);
  #endif
  
-   if (machine_suffix)
-     len += strlen (machine_suffix);
- 
-   temp = xmalloc (len);
- 
    /* Determine the filename to execute (special case for absolute paths).  */
  
    if (IS_ABSOLUTE_PATHNAME (name))
      {
        if (access (name, mode) == 0)
! 	{
! 	  strcpy (temp, name);
! 	  return temp;
! 	}
      }
    else
      for (pl = pprefix->plist; pl; pl = pl->next)
--- 2450,2461 ----
      return xstrdup (DEFAULT_LINKER);
  #endif
  
    /* Determine the filename to execute (special case for absolute paths).  */
  
    if (IS_ABSOLUTE_PATHNAME (name))
      {
        if (access (name, mode) == 0)
! 	return concat (name, NULL);
      }
    else
      for (pl = pprefix->plist; pl; pl = pl->next)
*************** find_a_file (pprefix, name, mode)
*** 2474,2501 ****
  	       So try appending that first.  */
  	    if (file_suffix[0] != 0)
  	      {
! 		strcpy (temp, pl->prefix);
! 		strcat (temp, machine_suffix);
! 		strcat (temp, name);
! 		strcat (temp, file_suffix);
  		if (access_check (temp, mode) == 0)
  		  {
  		    if (pl->used_flag_ptr != 0)
  		      *pl->used_flag_ptr = 1;
  		    return temp;
  		  }
  	      }
  
  	    /* Now try just the name.  */
! 	    strcpy (temp, pl->prefix);
! 	    strcat (temp, machine_suffix);
! 	    strcat (temp, name);
  	    if (access_check (temp, mode) == 0)
  	      {
  		if (pl->used_flag_ptr != 0)
  		  *pl->used_flag_ptr = 1;
  		return temp;
  	      }
  	  }
  
  	/* Certain prefixes are tried with just the machine type,
--- 2466,2491 ----
  	       So try appending that first.  */
  	    if (file_suffix[0] != 0)
  	      {
!                 temp = concat (pl->prefix, machine_suffix, name, file_suffix,
!                                NULL);
  		if (access_check (temp, mode) == 0)
  		  {
  		    if (pl->used_flag_ptr != 0)
  		      *pl->used_flag_ptr = 1;
  		    return temp;
  		  }
+                 free (temp);
  	      }
  
  	    /* Now try just the name.  */
!             temp = concat (pl->prefix, machine_suffix, name, NULL);
  	    if (access_check (temp, mode) == 0)
  	      {
  		if (pl->used_flag_ptr != 0)
  		  *pl->used_flag_ptr = 1;
  		return temp;
  	      }
+             free (temp);
  	  }
  
  	/* Certain prefixes are tried with just the machine type,
*************** find_a_file (pprefix, name, mode)
*** 2506,2532 ****
  	       So try appending that first.  */
  	    if (file_suffix[0] != 0)
  	      {
! 		strcpy (temp, pl->prefix);
! 		strcat (temp, just_machine_suffix);
! 		strcat (temp, name);
! 		strcat (temp, file_suffix);
  		if (access_check (temp, mode) == 0)
  		  {
  		    if (pl->used_flag_ptr != 0)
  		      *pl->used_flag_ptr = 1;
  		    return temp;
  		  }
  	      }
  
! 	    strcpy (temp, pl->prefix);
! 	    strcat (temp, just_machine_suffix);
! 	    strcat (temp, name);
  	    if (access_check (temp, mode) == 0)
  	      {
  		if (pl->used_flag_ptr != 0)
  		  *pl->used_flag_ptr = 1;
  		return temp;
  	      }
  	  }
  
  	/* Certain prefixes can't be used without the machine suffix
--- 2496,2520 ----
  	       So try appending that first.  */
  	    if (file_suffix[0] != 0)
  	      {
!                 temp = concat (pl->prefix, just_machine_suffix, name,
!                                file_suffix, NULL);
  		if (access_check (temp, mode) == 0)
  		  {
  		    if (pl->used_flag_ptr != 0)
  		      *pl->used_flag_ptr = 1;
  		    return temp;
  		  }
+                 free (temp);
  	      }
  
!             temp = concat (pl->prefix, just_machine_suffix, name, NULL);
  	    if (access_check (temp, mode) == 0)
  	      {
  		if (pl->used_flag_ptr != 0)
  		  *pl->used_flag_ptr = 1;
  		return temp;
  	      }
+             free (temp);
  	  }
  
  	/* Certain prefixes can't be used without the machine suffix
*************** find_a_file (pprefix, name, mode)
*** 2537,2565 ****
  	       So try appending that first.  */
  	    if (file_suffix[0] != 0)
  	      {
! 		strcpy (temp, pl->prefix);
! 		strcat (temp, name);
! 		strcat (temp, file_suffix);
  		if (access_check (temp, mode) == 0)
  		  {
  		    if (pl->used_flag_ptr != 0)
  		      *pl->used_flag_ptr = 1;
  		    return temp;
  		  }
  	      }
  
! 	    strcpy (temp, pl->prefix);
! 	    strcat (temp, name);
  	    if (access_check (temp, mode) == 0)
  	      {
  		if (pl->used_flag_ptr != 0)
  		  *pl->used_flag_ptr = 1;
  		return temp;
  	      }
  	  }
        }
  
-   free (temp);
    return 0;
  }
  
--- 2525,2551 ----
  	       So try appending that first.  */
  	    if (file_suffix[0] != 0)
  	      {
!                 temp = concat (pl->prefix, name, file_suffix, NULL);
  		if (access_check (temp, mode) == 0)
  		  {
  		    if (pl->used_flag_ptr != 0)
  		      *pl->used_flag_ptr = 1;
  		    return temp;
  		  }
+                 free (temp);
  	      }
  
!             temp = concat (pl->prefix, name, NULL);
  	    if (access_check (temp, mode) == 0)
  	      {
  		if (pl->used_flag_ptr != 0)
  		  *pl->used_flag_ptr = 1;
  		return temp;
  	      }
+             free (temp);
  	  }
        }
  
    return 0;
  }
  
*************** static int input_from_pipe;
*** 4009,4014 ****
--- 3995,4038 ----
     arguments.  */
  static const char *suffix_subst;
  
+ /* Output the library directory flags corresponding to PATH.  
+    PATH is supposed to be a writable string.  */
+ 
+ static void
+ do_lib_spec (path)
+      char *path;
+ {
+   if (is_directory (path, "", 1))
+     {
+       /* Remove slash from path.  */
+       const int idx = strlen (path);
+       if (IS_DIR_SEPARATOR (path[idx - 1]))
+         path[idx - 1] = 0;
+ 
+       do_spec_1 ("-L", 0, NULL);
+ #ifndef SPACE_AFTER_L_OPTION
+ #define SPACE_AFTER_L_OPTION 0
+ #else
+ #define SPACE_AFTER_L_OPTION 1
+ #endif
+       if (SPACE_AFTER_L_OPTION)
+         do_spec_1 (" ", 0, NULL);
+       do_spec_1 (path, 1, NULL);
+       /* Make this a separate argument.  */
+       do_spec_1 (" ", 0, NULL);
+ #ifndef RUNPATH_FLAG
+ #define RUNPATH_FLAG 0
+ #endif
+       if (ENABLE_RUNPATH && RUNPATH_FLAG)
+         {
+           do_spec_1 (RUNPATH_FLAG, 0, NULL);
+           do_spec_1 (path, 1, NULL);
+           /* Make this a separate argument.  */
+           do_spec_1 (" ", 0, NULL);
+         }
+     }
+ }
+ 
  /* Process the spec SPEC and run the commands specified therein.
     Returns 0 if the spec is successfully processed; -1 if failed.  */
  
*************** do_spec_1 (spec, inswitch, soft_matched_
*** 4184,4192 ****
  	  case 'D':
  	    {
  	      struct prefix_list *pl = startfile_prefixes.plist;
! 	      size_t bufsize = 100;
! 	      char *buffer = (char *) xmalloc (bufsize);
! 	      int idx;
  
  	      for (; pl; pl = pl->next)
  		{
--- 4208,4214 ----
  	  case 'D':
  	    {
  	      struct prefix_list *pl = startfile_prefixes.plist;
! 	      char *buffer;
  
  	      for (; pl; pl = pl->next)
  		{
*************** do_spec_1 (spec, inswitch, soft_matched_
*** 4204,4288 ****
  		    {
  		      if (machine_suffix)
  			{
! 			  if (strlen (pl->prefix) + strlen (machine_suffix)
! 			      >= bufsize)
! 			    bufsize = (strlen (pl->prefix)
! 				       + strlen (machine_suffix)) * 2 + 1;
! 			  buffer = (char *) xrealloc (buffer, bufsize);
! 			  strcpy (buffer, pl->prefix);
! 			  strcat (buffer, machine_suffix);
! 			  if (is_directory (buffer, multilib_dir, 1))
! 			    {
! 			      do_spec_1 ("-L", 0, NULL);
! #ifdef SPACE_AFTER_L_OPTION
! 			      do_spec_1 (" ", 0, NULL);
! #endif
! 			      do_spec_1 (buffer, 1, NULL);
! 			      do_spec_1 (multilib_dir, 1, NULL);
! 			      /* Make this a separate argument.  */
! 			      do_spec_1 (" ", 0, NULL);
! 			    }
  			}
  		      if (!pl->require_machine_suffix)
  			{
! 			  if (is_directory (pl->prefix, multilib_dir, 1))
! 			    {
! 			      do_spec_1 ("-L", 0, NULL);
! #ifdef SPACE_AFTER_L_OPTION
! 			      do_spec_1 (" ", 0, NULL);
! #endif
! 			      do_spec_1 (pl->prefix, 1, NULL);
! 			      do_spec_1 (multilib_dir, 1, NULL);
! 			      /* Make this a separate argument.  */
! 			      do_spec_1 (" ", 0, NULL);
! 			    }
  			}
  		    }
  		  if (machine_suffix)
  		    {
! 		      if (is_directory (pl->prefix, machine_suffix, 1))
! 			{
! 			  do_spec_1 ("-L", 0, NULL);
! #ifdef SPACE_AFTER_L_OPTION
! 			  do_spec_1 (" ", 0, NULL);
! #endif
! 			  do_spec_1 (pl->prefix, 1, NULL);
! 			  /* Remove slash from machine_suffix.  */
! 			  if (strlen (machine_suffix) >= bufsize)
! 			    bufsize = strlen (machine_suffix) * 2 + 1;
! 			  buffer = (char *) xrealloc (buffer, bufsize);
! 			  strcpy (buffer, machine_suffix);
! 			  idx = strlen (buffer);
! 			  if (IS_DIR_SEPARATOR (buffer[idx - 1]))
! 			    buffer[idx - 1] = 0;
! 			  do_spec_1 (buffer, 1, NULL);
! 			  /* Make this a separate argument.  */
! 			  do_spec_1 (" ", 0, NULL);
! 			}
  		    }
  		  if (!pl->require_machine_suffix)
  		    {
! 		      if (is_directory (pl->prefix, "", 1))
! 			{
! 			  do_spec_1 ("-L", 0, NULL);
! #ifdef SPACE_AFTER_L_OPTION
! 			  do_spec_1 (" ", 0, NULL);
! #endif
! 			  /* Remove slash from pl->prefix.  */
! 			  if (strlen (pl->prefix) >= bufsize)
! 			    bufsize = strlen (pl->prefix) * 2 + 1;
! 			  buffer = (char *) xrealloc (buffer, bufsize);
! 			  strcpy (buffer, pl->prefix);
! 			  idx = strlen (buffer);
! 			  if (IS_DIR_SEPARATOR (buffer[idx - 1]))
! 			    buffer[idx - 1] = 0;
! 			  do_spec_1 (buffer, 1, NULL);
! 			  /* Make this a separate argument.  */
! 			  do_spec_1 (" ", 0, NULL);
! 			}
  		    }
  		}
- 	      free (buffer);
  	    }
  	    break;
  
--- 4226,4256 ----
  		    {
  		      if (machine_suffix)
  			{
!                           buffer = concat (pl->prefix, machine_suffix,
!                                            multilib_dir, NULL);
!                           do_lib_spec (buffer);
!                           free (buffer);
  			}
  		      if (!pl->require_machine_suffix)
  			{
!                           buffer = concat (pl->prefix, multilib_dir, NULL);
!                           do_lib_spec (buffer);
!                           free (buffer);
  			}
  		    }
  		  if (machine_suffix)
  		    {
!                       buffer = concat (pl->prefix, machine_suffix, NULL);
!                       do_lib_spec (buffer);
!                       free (buffer);
  		    }
  		  if (!pl->require_machine_suffix)
  		    {
!                       buffer = concat (pl->prefix, NULL);
!                       do_lib_spec (buffer);
!                       free (buffer);
  		    }
  		}
  	    }
  	    break;
  
Index: gcc/config/i386/linux.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/linux.h,v
retrieving revision 1.29
diff -c -3 -p -r1.29 linux.h
*** linux.h	2001/05/22 16:57:40	1.29
--- linux.h	2001/09/20 18:11:26
*************** the Free Software Foundation, 59 Temple 
*** 21,26 ****
--- 21,27 ----
  Boston, MA 02111-1307, USA.  */
  
  #define LINUX_DEFAULT_ELF
+ #define RUNPATH_FLAG "-rpath "
  
  /* Output at beginning of assembler file.  */
  /* The .file command should always begin the output.  */

 --------------------------------------------------------------------
 Theodore Papadopoulo
 Email: Theodore.Papadopoulo@sophia.inria.fr Tel: (33) 04 92 38 76 01
 --------------------------------------------------------------------



-- 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: Exmh version 2.2 06/23/2000

iD8DBQE7qjvIIzTj8qrxOU4RAgZSAJ0aPl9J44CBF2HGe/GfmAoKLOhHpACcDccv
VVlblA0Zn9YpFidbq7Tfias=
=TFeY
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2001-09-20 11:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-20 11:56 [RFC] Adding some rpath support Theodore Papadopoulo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).