Opened 7 years ago

Last modified 6 years ago

#41918 new defect

R @3.0.2_1: +atlas variant fails to build

Reported by: josephsacco Owned by: kjellpk (Kjell Konis)
Priority: Normal Milestone:
Component: ports Version: 2.2.1
Keywords: haspatch Cc: petrrr
Port: R

Description

The +atlas variant of R-3.0.2_1 fails to build because of a library search path issue. A patch is attached to this ticket.

-Joseph

Discussion


So... You have been passing flags to linkers for years. Altering the linker search path using the -L option has been a favorite:

Search paths

ld maintains a list of directories to search for a library or framework to use. The default library search path is /usr/lib then /usr/local/lib. The -L option will add a new library search path. The default framework search path is /Library/Frameworks then /System/Library/Frameworks. (Note: previously, /Network/Library/Frame-works was at the end of the default path. If you need that functionality, you need to explicitly add -F/Net-work/Library/Frameworks). The -F option will add a new framework search path. The -Z option will remove the standard search paths. The -syslibroot option will prepend a prefix to all search paths.

Use the -L option and the linker will do your bidding. Add some -Lpath statements to the compile line and the linker will search for libraries in the order of your choosing. Right?

Well... Not quite. The linker prefers shared libraries over static libraries. If you ask it to find

-lMyLib

the linker will first search the *entire* search path for a shared library version of MyLib. If none is found, it will then search through the entire search path for the static version of MyLib.

Why is this a bad thing and what can you do about it?

Suppose you create a static version of libatlas and install it in

/opt/local/lib/libatlas.a

When you want to link against this library, you would might use something like

-L/opt/local/lib -latlas

This works provided libatlas.dylib does not exist elsewhere in the ld search path. Suppose libatlas.dylib exists in /usr/lib. Even though you have altered the ld search path with a -Lpath statement, the linker will choose the shared version in /usr/lib over the static version in /opt/local/lib

What to do?

The linker has yet another flag that will alter the search procedure to do what you really had in mind:

-search_paths_first

By default the -lx and -weak-lx options first search for a file of the form 'libx.dylib' in each directory in the library search path, then a file of the form 'libx.a' is searched for in the library search paths. This option changes it so that in each path `libx.dylib' is searched for then'libx.a' before the next path in the library search path is searched.

Attachments (1)

Portfile.diff (535 bytes) - added by josephsacco 7 years ago.
Portfile patch

Download all attachments as: .zip

Change History (5)

Changed 7 years ago by josephsacco

Attachment: Portfile.diff added

Portfile patch

comment:1 Changed 7 years ago by larryv (Lawrence Velázquez)

What version of OS X and Xcode are you using? The ld(1) man page claims that -search_paths_first is the default behavior with Xcode 4 and later.

comment:2 Changed 7 years ago by josephsacco

Good catch... G4 PowerMac running OS X 10.5.8 and Xcode 3.1.4.

-Joseph

comment:3 Changed 7 years ago by ryandesign (Ryan Schmidt)

Cc: kjell.konis@… removed
Keywords: haspatch added
Owner: changed from macports-tickets@… to kjell.konis@…
Port: R added; R-3.0.2_1 removed
Summary: R-3.0.2_1: +atlas variant fails to buildR @3.0.2_1: +atlas variant fails to build

comment:4 Changed 6 years ago by petrrr

Cc: petr@… added

Cc Me!

Note: See TracTickets for help on using tickets.