On Jun 7, 2012, at 05:22, Josh Triplett <j...@joshtriplett.org> wrote:

> On Thu, Jun 07, 2012 at 01:22:47AM -0700, Jeremy Huddleston wrote:
>> On Jun 6, 2012, at 15:13, Josh Triplett <j...@joshtriplett.org> wrote:
>>> On Wed, Jun 06, 2012 at 02:10:47PM -0700, Jeremy Huddleston wrote:
>>>> On Jun 6, 2012, at 4:04 AM, Josh Triplett <j...@joshtriplett.org> wrote:
>>>>> On Tue, Jun 05, 2012 at 10:03:44PM -0700, Jeremy Huddleston wrote:
>>>>>> On Jun 5, 2012, at 6:35 PM, Josh Triplett <j...@joshtriplett.org> wrote:
>>>>>>> I agree with your statement that from a functional standpoint this holds
>>>>>>> true: the linker doesn't seem to enforce the minor version rule, so you
>>>>>>> can build against a newer library and run with an older one, or vice
>>>>>>> versa, as long as the major version matches.  The linker will complain
>>>>>>> if you use a symbol that it can't resolve, though.
>>>>>> 
>>>>>> As it should (well unless the symbol is weak and can be checked for at
>>>>>> runtime).
>>>>> 
>>>>> True, though for most symbols that doesn't make sense, since you'd have
>>>>> to write things like "if (!xcb_useful_function) aieee();". :)
>>>> 
>>>> Well, if aieee() is really needed, then you wouldn't check for it, you'd
>>>> just use it and bail out with the dynamic linker complaining that it
>>>> couldn't resolve.
>>> 
>>> You don't necessarily have that option with a weak symbol.  Unless you
>>> mean that the program can, on a symbol-by-symbol basis, choose whether
>>> to use the symbol as weak or non-weak?  That seems feasible, but not
>>> compatible with how most library header files normally define function
>>> prototypes.
>> 
>> Well, it's how we do it on OS X.  For example:
>> 
>> ssize_t getdelim(char ** __restrict, size_t * __restrict, int, FILE * 
>> __restrict)
>> __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
>> 
>> getdelim will be weak if the developer sets OS X 10.6 as a deployment target.
>> If 10.7 or later is used as a deployment target, the symbol will not be weak.
>> __OSX_AVAILABLE_STARTING is essentially a macro that evaluates to nothing or
>> __attribute__((weak_import)).
> 
> I see.  So if you build with the headers and libraries of 10.7, and you
> want to require 10.7, then you get a non-weak symbol and can use it
> unconditionally, while if you build with 10.7 but say you want
> compatibility with 10.6 then you get a weak symbol?

Yep.

> That seems like an eminently sensible approach.  The alternative, which
> I've seen in the occasional Linux interface header that implements such
> versioning, amounts to not defining the symbol at all if you say you
> want compatibility with versions that don't have it.

Yeah, I guess that's probably just the easier way to do it.  It makes it harder 
for someone to do the wrong thing, but I'd rather make it easier for someone to 
do the right thing. ;)

> Several of my responses below will amount to "this makes much more sense
> now that I understand the standard idiom you had in mind". :)

=)

>>>> Why?  If you can do something in the case that it doesn't exist, that
>>>> should be an option.
>>> 
>>> That falls under the case I mentioned below ("Or, if you really have
>>> written your program so that you can cope with the absence of some
>>> functionality,").  That doesn't represent the common case, though.
>> 
>> It's a very common case for OS X developers that want to support new
>> technologies on newer OS versions but still want to run on older OS
>> versions.  For example, when Snow Leopard first came out, developers
>> were able to use this functionality to use their new dispatch codepath
>> if GCD was available and pthreads if it was not.
> 
> Sorry, I should have said that it doesn't represent the common case *on
> Linux*.  I do agree that it potentially represents the common case on
> platforms with predominantly binary-only software.  I'd also say,
> though, that the solution you described above with conditionally-weak
> symbols makes much more sense than the notion of always-weak symbols
> that I thought you had suggested.

Yes, but the fact that this doesn't represent the common case on Linux is
perhaps one of the hurdles in 3rd party developers supporting Linux as
a platform for their binaries.  I know there are plenty of people who could
care less about commercial binaries running on Linux (I was certainly on
that boat when I was focused on Linux, but I'm sure this is an issue that
Valve is having to deal with for Steam.  Other major commercial products
distributed as binary (Maya, Shake, ...) have typically targeted very
specific versions of specific distributions.  Of course this is all
editorial commentary from someone who has been drinking OS X Kool Aide for
the past few years, but I really do think this particular model for SDKs is
quite nice.

>> Well you should be checking the return value and acting appropriately.  In
>> your case, you still need to do:
>> 
>> if (syscall(...) == ENOSYS) {
>>    do_fallback();
>> }
> 
> Except that I can fold that in with all the other errno handling, which
> will tend to make it a bit more natural.  I frequently won't need to
> distinguish between ENOSYS and any other error.

Yeah, true.

>  (Also, presumably you
> meant if (syscall(...) < 0 && errno == ENOSYS) { ... }.)

Yeah, you got me ;)  Sometimes I like to go live in a land of beauty where
errno does not exist and UNIX was originally designed with functions that
returned negative error codes on failure and >= 0 status on success.

Ah, if we could only throw out *everything* and start again...


_______________________________________________
xorg@lists.x.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.x.org/mailman/listinfo/xorg
Your subscription address: arch...@mail-archive.com

Reply via email to