View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0010342CMakeCMakepublic2010-02-26 10:472016-06-10 14:31
ReporterManuel Massing 
Assigned ToKitware Robot 
PrioritynormalSeveritymajorReproducibilityalways
StatusclosedResolutionmoved 
PlatformOSOS Version
Product VersionCMake-2-8 
Target VersionFixed in Version 
Summary0010342: Mac OsX: Common symbols of c static librarties are not exported
DescriptionOn MacOSX, ranlib does not export common symbols, in contrast to the behaviour on other platforms.

This leads to link errors when linking against a static C library with common symbols (e.g. variables declared via the extern keyword will result in unresolved symbols). Attached is a minimal testcase to illustrate this.

This bug was already reported by Bob Tanner
(see http://www.cmake.org/pipermail/cmake/2009-June/029943.html [^]). The workaround,
also reported by Bob Tanner, is to invoke ranlib with a "-c" flag when building the library.
Additional InformationMacOS 10.6.2, ranlib version: "Apple Computer, Inc. version cctools-750"
Affects all tested cmake versions (2.8.0, 2.6.4 and cmake 2.9.0)
TagsNo tags attached.
Attached Filesgz file icon testcase.tar.gz [^] (635 bytes) 2010-02-26 10:47

 Relationships

  Notes
(0019653)
Brad King (manager)
2010-02-26 16:57

I've seen at least one project use "-fno-common" to avoid this problem.

From "man ranlib":

       -c Include common symbols as definitions with respect to the table
              of contents. This is seldom the intended behavior for linking
              from a library, as it forces the linking of a library member
              just because it uses an uninitialized global that is undefined
              at that point in the linking. This option is included only
              because this was the original behavior of ranlib. This option
              is not the default.

This seems to say it is not the preferred behavior on Mac. Any idea why? I'm not against adding the flag but I wonder why it is not default.
(0019683)
Manuel Massing (reporter)
2010-03-02 08:30

Hi Brad, thanks for looking into this.
I do not have much experience on the platform, so unfortunately I am unsure why
this is not the default option. The man-page to ranlib seems to indicate
that libtool ( http://developer.apple.com/mac/library/documentation/Darwin [^]
/Reference/ManPages/man1/libtool.1.html ) is preferred over ranlib altogether, so
maybe this is the reason for the depreciation note?
(0020975)
Brad King (manager)
2010-06-10 14:01

You can probably work around this problem by adding

  SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -c <TARGET>")

after your project() command.
(0020976)
Brad King (manager)
2010-06-10 14:28

Building your test case in Xcode also fails. It creates the archive using libtool:

/Developer/usr/bin/libtool -static -arch_only x86_64 -syslibroot /Developer/SDKs/MacOSX10.6.sdk "-L/.../Debug" -filelist "/.../Project.build/Debug/staticlib.build/Objects-normal/x86_64/staticlib.LinkFileList" -o "/.../Debug/libstaticlib.a"

Adding "-c" to the OTHER_LDFLAGS option in the Xcode IDE solves the problem.
(0023756)
K. Noel Belcourt (reporter)
2010-12-07 11:52

Hi,

I gave your work around mentioned above a try, it doesn't seem to work. Note that I'm on OSX 10.5.8 and not using Xcode and am using Intel compilers. Is there any other way to pass -c to ranlib?

Here's what gcc has to say about -fno-common.

-fno-common
    In C, allocate even uninitialized global variables in the data section of the object file, rather than generating them as common blocks. This has the effect that if the same variable is declared (without "extern") in two different compilations, you will get an error when you link them. The only reason this might be useful is if you wish to verify that the program will work on other systems which always work this way.

So given that -fno-common isn't an option and your workaround doesn't seem to work, is there any CMAKE_RANLIB_FLAGS option we can use or add so I can pass -c to ranlib? I'm more or less dead unless I start making code changes (which I can't do to QA'd code).

Is there a way to create static libraries on the Mac using libtool rather than usnig the ar / ranlib shuffle? Perhaps an option to select which approach to use?

-- Noel
(0023757)
Brad King (manager)
2010-12-07 12:17

I disagree with gcc's case against -fno-common. I've never seen a C compiler other than on Mac that uses the common block for this case. It's bad behavior IMO, and -fno-common disables it. Does it avoid your problem or not?

> is there any CMAKE_RANLIB_FLAGS option
[snip]
> create static libraries on the Mac using libtool

No to both. That's why a workaround is needed.

The CMAKE_C_ARCHIVE_FINISH workaround may need to be set for CMAKE_CXX_ARCHIVE_FINISH and CMAKE_Fortran_ARCHIVE_FINISH too.

Is CMAKE_C_CREATE_STATIC_LIBRARY set to anything? If so that will be used instead of the ARCHIVE rules and the workaround will do nothing.


Anyway, the full fix here is to teach the CMake platform information files to add -c to ranlib calls, and to fix the Xcode generator too.
(0023758)
K. Noel Belcourt (reporter)
2010-12-07 12:32

Hi Brad,

It'll take a while for a clean rebuild so I'll let you know if -fno-common passed to ifort fixes it. I didn't realize Intel supported gcc's -fno-common since they don't document it. I do notice the symbol type changed from C to S which is a step in the right direction.

"C" The symbol is common. Common symbols are uninitialized data. When linking, multiple common symbols may appear with the same name. If the symbol is defined anywhere, the common symbols are treated as undefined references.

"S" The symbol is in an uninitialized data section for small objects.

Also, if I have C, CXX and Fortran all setting the CMAKE_<LANG>_ARCHIVE_FINISH rule, then -c is passed to ranlib. Not sure why it isn't if I only set CMAKE_Fortran_ARCHIVE_FINISH.

Thanks for the help Brad, I'm running so consider this issue closed for me.

-- Noel
(0023759)
K. Noel Belcourt (reporter)
2010-12-07 12:46

Yes, passing -fno-common to ifort works.

Thanks again Brad!

-- Noel
(0028791)
Nick Brown (reporter)
2012-03-02 10:40

Has this been taken any further?
I don't think OSX will change it's behaviour, and and it's still necessary to add -c to ranlib or use -fno-common.
It would be nice if cmake was smart enough to do this by default on OSX and not require adding manually to project files.
(0028794)
Brad King (manager)
2012-03-02 11:47

Moving to backlog as I have no time to investigate this further.

How does one decide if "ranlib -c" or "--no-common" is the desired solution for a particular project? Adding either by default could pollute existing projects that do not need them.

If someone wants to work on this the patch will need to address both Makefile and Xcode generators.
(0041658)
Kitware Robot (administrator)
2016-06-10 14:27

Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.

 Issue History
Date Modified Username Field Change
2010-02-26 10:47 Manuel Massing New Issue
2010-02-26 10:47 Manuel Massing File Added: testcase.tar.gz
2010-02-26 10:58 Bill Hoffman Status new => assigned
2010-02-26 10:58 Bill Hoffman Assigned To => Brad King
2010-02-26 16:57 Brad King Note Added: 0019653
2010-03-02 08:30 Manuel Massing Note Added: 0019683
2010-06-10 14:01 Brad King Note Added: 0020975
2010-06-10 14:28 Brad King Note Added: 0020976
2010-12-07 11:52 K. Noel Belcourt Note Added: 0023756
2010-12-07 12:17 Brad King Note Added: 0023757
2010-12-07 12:32 K. Noel Belcourt Note Added: 0023758
2010-12-07 12:46 K. Noel Belcourt Note Added: 0023759
2012-03-02 10:40 Nick Brown Note Added: 0028791
2012-03-02 11:47 Brad King Note Added: 0028794
2012-03-02 11:47 Brad King Assigned To Brad King =>
2012-03-02 11:47 Brad King Status assigned => backlog
2016-06-10 14:27 Kitware Robot Note Added: 0041658
2016-06-10 14:27 Kitware Robot Status backlog => resolved
2016-06-10 14:27 Kitware Robot Resolution open => moved
2016-06-10 14:27 Kitware Robot Assigned To => Kitware Robot
2016-06-10 14:31 Kitware Robot Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team