Patchwork [c++,driver] Add -lrt on Solaris

login
register
mail settings
Submitter Rainer Orth
Date June 7, 2013, 3:45 p.m.
Message ID <yddk3m5diwb.fsf@lokon.CeBiTec.Uni-Bielefeld.DE>
Download mbox | patch
Permalink /patch/249746/
State New
Headers show

Comments

Rainer Orth - June 7, 2013, 3:45 p.m.
This is a resubmission of a patch originally posted here

	http://gcc.gnu.org/ml/gcc-patches/2013-05/msg01488.html

It was only intended as a stop-gap measure to avoid a couple of
libstdc++ testsuite failures on Solaris 9 and 10 where nanosleep only
lives in librt, which is now required since --enable-libstdcxx-time=auto
became the default.  On Solaris 11, librt has been folded into libc and
librt only remains as a filter on libc, so linking with unnecessary,
though not really harmful.

As I mentioned in the thread above, I don't really like this solution
for two reasons:

* It splits the knowledge about libstdc++'s need for librt between
  libstdc++ and gcc configury.

* It unconditionally links librt into every C++ program instead of doing
  this only when necessary.

Therefore I'd suggested an alternative approach, which unfortunately is
far more intrusive:

Follow libgfortran's lead and introduce libstdc++.spec.  Here,
target-specific linker switches can be determined by the libstdc++
configury, with configuration well localized, and one can easily handle
stuff like linking -lrt with -z ignore/-z record
resp. --as-needed/--no-as-needed.  This provides us with a general
extension mechanism for linking C++ programs, which can be used for
other purposes if the need arises.

The downside of course is that the testsuite needs to be taught about
that file by passing the appropriate -B switches to find it at compile
time.

One way or another, this needs to be adressed to fix the libstdc++
testsuite failures on Solaris.

Thoughts?

	Rainer


2013-05-24  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gcc/cp:
	* g++spec.c (TIMELIB): Define.
	(WITHLIBC, SKIPOPT): Adjust values.
	(lang_specific_driver): Add TIME_LIBRARY if not passed explicitly.

	gcc:
	* config/sol2.h (TIME_LIBRARY): Define.
Jonathan Wakely - June 7, 2013, 3:54 p.m.
I haven't looked at the patch yet and my knowledge of spec files is
pretty weak, so sorry if these are stupid questions ...


On 7 June 2013 16:45, Rainer Orth wrote:
>
> Follow libgfortran's lead and introduce libstdc++.spec.  Here,
> target-specific linker switches can be determined by the libstdc++
> configury, with configuration well localized, and one can easily handle
> stuff like linking -lrt with -z ignore/-z record
> resp. --as-needed/--no-as-needed.  This provides us with a general
> extension mechanism for linking C++ programs, which can be used for
> other purposes if the need arises.

Could this later be extended to serve as the basis for a -cxxthread
switch that does platform-specific things to allow the C++11 thread
library to be used?  I don't like that users must use -pthread for
std::thread and std::mutex to work, because they shouldn't need to
know or care whether it uses Pthreads internally, or some other thread
model.


> The downside of course is that the testsuite needs to be taught about
> that file by passing the appropriate -B switches to find it at compile
> time.

Is that only necessary for testing an uninstalled libstdc++?  In other
words, would the spec file be installed and used automatically for an
installed libstdc++?

> One way or another, this needs to be adressed to fix the libstdc++
> testsuite failures on Solaris.

The other option is to make --enable-libstdcxx-time=auto only
effective for Solaris 11, but I think you said you'd prefer to keep it
for 9 and 10.
Rainer Orth - June 7, 2013, 4:03 p.m.
Jonathan Wakely <jwakely.gcc@gmail.com> writes:

> On 7 June 2013 16:45, Rainer Orth wrote:
>>
>> Follow libgfortran's lead and introduce libstdc++.spec.  Here,
>> target-specific linker switches can be determined by the libstdc++
>> configury, with configuration well localized, and one can easily handle
>> stuff like linking -lrt with -z ignore/-z record
>> resp. --as-needed/--no-as-needed.  This provides us with a general
>> extension mechanism for linking C++ programs, which can be used for
>> other purposes if the need arises.
>
> Could this later be extended to serve as the basis for a -cxxthread
> switch that does platform-specific things to allow the C++11 thread
> library to be used?  I don't like that users must use -pthread for

Sure.

> std::thread and std::mutex to work, because they shouldn't need to
> know or care whether it uses Pthreads internally, or some other thread
> model.

Exactly: that's the sort of implementation detail users shouldn't need
to know or care about.

>> The downside of course is that the testsuite needs to be taught about
>> that file by passing the appropriate -B switches to find it at compile
>> time.
>
> Is that only necessary for testing an uninstalled libstdc++?  In other
> words, would the spec file be installed and used automatically for an
> installed libstdc++?

Of course: that's what gfortran does with libgfortran.spec: it gets
installed into $libdir and is searched there automatically.

>> One way or another, this needs to be adressed to fix the libstdc++
>> testsuite failures on Solaris.
>
> The other option is to make --enable-libstdcxx-time=auto only
> effective for Solaris 11, but I think you said you'd prefer to keep it
> for 9 and 10.

Right: if the target (independent of Solaris) has the necessary support
for some feature, libstdc++ should be able to use it.  You wouldn't
think about disabling thread support before Solaris 11 to avoid linking
libstdc++.so with -lpthread?

	Rainer

Patch

# HG changeset patch
# Parent d6881ec042d3a6328b763cbf0f38e61bdbb64d79
Add -lrt on Solaris

diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -194,6 +194,9 @@  along with GCC; see the file COPYING3.  
 #endif /* HAVE_LD_EH_FRAME && TARGET_DL_ITERATE_PHDR */
 #endif
 
+/* C++11 programs need -lrt for nanosleep.  */
+#define TIME_LIBRARY "rt"
+
 #ifndef USE_GLD
 /* The default MFLIB_SPEC is GNU ld specific.  */
 #define MFLIB_SPEC ""
diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
--- a/gcc/cp/g++spec.c
+++ b/gcc/cp/g++spec.c
@@ -28,10 +28,12 @@  along with GCC; see the file COPYING3.  
 #define LANGSPEC	(1<<1)
 /* This bit is set if they did `-lm' or `-lmath'.  */
 #define MATHLIB		(1<<2)
+/* This bit is set if they did `-lrt' or equivalent.  */
+#define TIMELIB		(1<<3)
 /* This bit is set if they did `-lc'.  */
-#define WITHLIBC	(1<<3)
+#define WITHLIBC	(1<<4)
 /* Skip this option.  */
-#define SKIPOPT		(1<<4)
+#define SKIPOPT		(1<<5)
 
 #ifndef MATH_LIBRARY
 #define MATH_LIBRARY "m"
@@ -40,6 +42,10 @@  along with GCC; see the file COPYING3.  
 #define MATH_LIBRARY_PROFILE MATH_LIBRARY
 #endif
 
+#ifndef TIME_LIBRARY
+#define TIME_LIBRARY ""
+#endif
+
 #ifndef LIBSTDCXX
 #define LIBSTDCXX "stdc++"
 #endif
@@ -83,16 +89,22 @@  lang_specific_driver (struct cl_decoded_
   /* "-lm" or "-lmath" if it appears on the command line.  */
   const struct cl_decoded_option *saw_math = NULL;
 
+  /* "-lrt" or eqivalent if it appears on the command line.  */
+  const struct cl_decoded_option *saw_time = NULL;
+
   /* "-lc" if it appears on the command line.  */
   const struct cl_decoded_option *saw_libc = NULL;
 
   /* An array used to flag each argument that needs a bit set for
-     LANGSPEC, MATHLIB, or WITHLIBC.  */
+     LANGSPEC, MATHLIB, TIMELIB, or WITHLIBC.  */
   int *args;
 
   /* By default, we throw on the math library if we have one.  */
   int need_math = (MATH_LIBRARY[0] != '\0');
 
+  /* By default, we throw on the time library if we have one.  */
+  int need_time = (TIME_LIBRARY[0] != '\0');
+
   /* True if we saw -static.  */
   int static_link = 0;
 
@@ -136,6 +148,11 @@  lang_specific_driver (struct cl_decoded_
 	      args[i] |= MATHLIB;
 	      need_math = 0;
 	    }
+	  else if (strcmp (arg, TIME_LIBRARY) == 0)
+	    {
+	      args[i] |= TIMELIB;
+	      need_time = 0;
+	    }
 	  else if (strcmp (arg, "c") == 0)
 	    args[i] |= WITHLIBC;
 	  else
@@ -268,6 +285,12 @@  lang_specific_driver (struct cl_decoded_
 	  saw_math = &decoded_options[i];
 	}
 
+      if (!saw_time && (args[i] & TIMELIB) && library > 0)
+	{
+	  --j;
+	  saw_time = &decoded_options[i];
+	}
+
       if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
 	{
 	  --j;
@@ -352,6 +375,15 @@  lang_specific_driver (struct cl_decoded_
       added_libraries++;
       j++;
     }
+  if (saw_time)
+    new_decoded_options[j++] = *saw_time;
+  else if (library > 0 && need_time)
+    {
+      generate_option (OPT_l, TIME_LIBRARY, 1, CL_DRIVER,
+		       &new_decoded_options[j]);
+      added_libraries++;
+      j++;
+    }
   if (saw_libc)
     new_decoded_options[j++] = *saw_libc;
   if (shared_libgcc && !static_link)