View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0003832CMakeCMakepublic2006-10-02 05:372008-01-23 16:38
ReporterPierre Chifflier 
Assigned ToBrad King 
PrioritynormalSeveritymajorReproducibilityalways
StatusclosedResolutionfixed 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0003832: add support for static libraries in TARGET_LINK_LIBRARIES
DescriptionWhen adding a static library name like
/usr/lib/perl/5.8/auto/DynaLoader/DynaLoader.a (needed to create perl modules)
in TARGET_LINK_LIBRARIES, the name is splitted into
-L/usr/lib/perl/5.8/auto/DynaLoader -lDynaLoader

However, this won't work because of the name (which does not begin by lib, so ld won't find -lDynaLoader)

I can see two solutions:
* modify TARGET_LINK_LIBRARIES so it supports different filenames (for ex, by *not* splitting path/filename in such case); or
* add some additional flags (like LINK_FLAGS) which would appear *after* <OBJECTS> in the link command (the build order _is_ important).
TagsNo tags attached.
Attached Files

 Relationships

  Notes
(0005076)
Brad King (manager)
2006-10-02 10:27

I'm closing this as a duplicate of bug 0001644. Note it has been fixed and the fix will be in CMake 2.4.4.
(0005078)
Brad King (manager)
2006-10-02 10:32

Oops, this is not the same problem. I've re-opened this report.
(0005093)
Brad King (manager)
2006-10-03 11:09

Is DynaLoader.a a convenience library?
(0005095)
Pierre Chifflier (reporter)
2006-10-03 11:29

Here's the complete story:
DynaLoader.a is not really a convenience library, it's an archive (set of .o files, exactly like a static library) provided by Perl, to allow creating new modules.
When creating a Perl extension, you must change your CFLAGS and LDFLAGS to use a valid provided by the 2 commands:
perl -MExtUtils::Embed -e ccopts (which expands to: -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/lib/perl/5.8/CORE)
and
perl -MExtUtils::Embed -e ldopts
-Wl,-E -L/usr/local/lib /usr/lib/perl/5.8/auto/DynaLoader/DynaLoader.a -L/usr/lib/perl/5.8/CORE -lperl -ldl -lm -lpthread -lc -lcrypt

DynaLoader is a perl module that allows loading dynamically C libraries into Perl code. To do this, you must link your program with DynaLoader.a

Technically, it may act exactly the same way as a convenience library. However, the solution is rather easy: you just use the .a file as if it was a .o, and the linker will do the job.

That's why I proposed the two possible solutions (reformulated here):
* provide a cmake command to allow adding an object file name directly, for ex:
TARGET_LINK_OBJECT(foo.a)
This command would add this object *after* the list of objects generated by sources. This is the solution I prefer
* modify TARGET_LINK_LIBRARY to check if the name begins with "lib" (for gcc), and in this case do *not* modify the name (even if an absolute path).

BTW, a side effect is that would indeed allow convenience libraries.

Other solutions implies asking the perl folks to name their libraries correctly (since naming it libDynaLoader.a would have solved the problem, as ld expands -lDynaLoader to either libDynaLoader.so OR libDynaLoader.a) ..

HTH
(0005096)
Brad King (manager)
2006-10-03 11:38

That sounds like a convenience library to me. Aren't they just archives of object files meant for inclusion in another target?

I bet the perl folks left off the lib prefix on purpose to force people to list the .a file like a .o file. This is how convenience libraries are "linked", right?
(0005123)
Pierre Chifflier (reporter)
2006-10-04 03:47

Honestly, I don't what the problem with external libraries is. Technically, there is *zero* difference between a static library and an object file.

The manual for ld says that ld is used to link _both_ object and archive files (archive files can be ended by .a or .so). What I consider as a bug/missing feature in cmake is the lack of ability to specify directly the name of an object or archive directly for the linker.

You will tell me that it is possible by changing the LINK_FLAGS property of the target. Indeed, it's true, but it won't work because <LINK_FLAGS> appears _before_ <OBJECTS> (and the order is important .. it should appear after) in file CMakeCInformation.cmake.

A simple patch is to put <LINK_FLAGS> _after_ <OBJECTS> in CMAKE_C_CREATE_SHARED_LIBRARY, in file CMakeCInformation.cmake.

Quote from this file (CMakeCInformation.cmake line 95):
  SET(CMAKE_C_CREATE_SHARED_LIBRARY
      "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")

Regards,
Pierre
(0005262)
Brad King (manager)
2006-10-05 14:31

I'm not saying there is a problem, I'm just trying to confirm that implementing convenience library support will fix this problem too.
(0005263)
Brad King (manager)
2006-10-05 14:32

FYI, you can specify object files directly for the linker. Just add them as source files to the target.

I don't know if .a files will be recognized as "external object" files though.
(0005287)
Pierre Chifflier (reporter)
2006-10-06 03:51

Sorry, I didn't meant to be aggressive.
Yes, adding convenience libs support could be a solution if an external lib (i.e not built by cmake) can be integrated.
I already tried adding DynaLoader.a to the sources of the target, but it didn't work. It seems the extension .a is not recognized as an external object, that may also be a solution to do that.
(0010002)
Steven Van Ingelgem (reporter)
2007-12-19 12:56

Hi Brad/Chifflier,


I ran in exactly the same problem trying to compile in a static version of wxWidgets. Somehow CMake thinks it knows better and changes my absolute paths to relative ones.

More information can be found in this thread:
http://public.kitware.com/pipermail/cmake/2007-December/018418.html [^]

Especially this remark is of importance here:
-------------------------
For example if I would have a static library in /home/steven/test/libtest.a, and one in /usr/lib/libtest.a with BOTH the same name, and BOTH static, but I add the /home/steven/test/libtest.a, then CMake will end up using the /usr/lib/libtest.a... Even though I said to use the one in "home".
-------------------------

Hopefully this could be resolved soon as it seems to be an issue for a very long time already :).

Adding the static library as a source would be perfect imho.
(0010003)
Brad King (manager)
2007-12-19 14:42

I doubt CMake is choosing the /usr/lib/libtest.a library over /home/steven/test/libtest.a in the way you think. The cmOrderLinkDirectories class is meant specifically to compute a safe link directory order. If you can reproduce this in a small example please attach a tarball to this issue.

The problem here is the confusion between linking to a static library and linking with a "convenience" library.

From a simple command line perspecitve:

  ... foo.o -L/bar/directory -lbar ...

will only copy in the object files from /bar/directory/libbar.a that are needed by foo.o. This is linking to the static library. On the other hand

  ... foo.o /bar/directory/libbar.a

will copy the *entire* libbar.a with *all* of its object files into the final executable whether foo.o needs the symbols or not. This means libbar.a is a convenience library...a package of object files meant for inclusion in the executable (one of which could have "main" for example).

In other words, splitting a full path into -L/dir and -lfile options is absolutely necessary and unavoidable when the library has been specified for linking (like TARGET_LINK_LIBRARIES). The issue here is that CMake does not have direct support for convenience libraries. I think we're in agreement that the solution is to treat a library as a convenience library if and only if it is listed as a *source* file for a given target.
(0010020)
Brad King (manager)
2007-12-24 12:17

I've investigated this issue further. The linker behavior I documented in the previous note does not apply to all linkers. Here are some updates:

On OS X, passing "/usr/lib/libfoo.a" to the linker will in fact simply link the archive (search it for symbols) and not copy everything in. There is a specific -all_load option to ld to copy all members.

On GNU/Linux (with GNU ld), passing "/usr/lib/libfoo.a" and "-L/usr/lib" "-lfoo" are basically the same assuming they find the same file. There are options "--whole-archive" and "--no-whole-archive" that enable/disable copying of the entire archive.

On HP-UX, the behavior is the same as the GNU linker, except that the options are "+forceload" and "+noforceload".

On IRIX, the flags are "-all" and "-notall".

On Sun, the flags are "-z allextract" and "-z defaultextract".
(0010021)
Brad King (manager)
2007-12-24 17:00

On FreeBSD, the GNU linker's whole-archive/no-whole-archive flags are available.

On AIX, there is no such flag and normal linking is the default, except for this note:

  Note: If you specify a shared object, or an archive file containing a
  shared object, with an absolute or relative path name, instead of with
  the -lName flag, the path name is included in the import file ID string
  in the loader section of the output file. You can override this
  behavior with the -bnoipath option.


On Windows with VS tools .lib files are specified by name anyway.

I cannot find any platform whose documentation indicates the behavior I mention above. Clearly wherever I "learned" that was either mistaken or based on some ancient platform.

So the summary is that normal linking can be accomplished on every platform by just passing full paths to the linker. Convenience library "linking" (copying at link time) can be accomplished on Linux, FreeBSD, HP-UX, IRIX, and Sun with flags. On Windows, OS X, and AIX some kind of manipulation of object file lists will be needed to support libtool convenience libraries.
(0010208)
Brad King (manager)
2008-01-22 09:29

I've implemented a new link line computation approach. Libraries are now linked using paths to their files instead of the -L -l split. More details were included in the commit log.

/cvsroot/CMake/CMake/bootstrap,v <-- bootstrap
new revision: 1.102; previous revision: 1.101
/cvsroot/CMake/CMake/Modules/CMakeCInformation.cmake,v <-- CMakeCInformation.cmake
new revision: 1.19; previous revision: 1.18
/cvsroot/CMake/CMake/Modules/CMakeCXXInformation.cmake,v <-- CMakeCXXInformation.cmake
new revision: 1.22; previous revision: 1.21
/cvsroot/CMake/CMake/Modules/CMakeFortranInformation.cmake,v <-- CMakeFortranInformation.cmake
new revision: 1.17; previous revision: 1.16
/cvsroot/CMake/CMake/Modules/Platform/AIX.cmake,v <-- AIX.cmake
new revision: 1.20; previous revision: 1.19
/cvsroot/CMake/CMake/Modules/Platform/HP-UX.cmake,v <-- HP-UX.cmake
new revision: 1.25; previous revision: 1.24
/cvsroot/CMake/CMake/Source/CMakeLists.txt,v <-- CMakeLists.txt
new revision: 1.387; previous revision: 1.386
/cvsroot/CMake/CMake/Source/cmComputeLinkInformation.cxx,v <-- cmComputeLinkInformation.cxx
initial revision: 1.1
/cvsroot/CMake/CMake/Source/cmComputeLinkInformation.h,v <-- cmComputeLinkInformation.h
initial revision: 1.1
/cvsroot/CMake/CMake/Source/cmDocumentVariables.cxx,v <-- cmDocumentVariables.cxx
new revision: 1.10; previous revision: 1.9
/cvsroot/CMake/CMake/Source/cmGlobalGenerator.cxx,v <-- cmGlobalGenerator.cxx
new revision: 1.218; previous revision: 1.217
/cvsroot/CMake/CMake/Source/cmGlobalGenerator.h,v <-- cmGlobalGenerator.h
new revision: 1.102; previous revision: 1.101
/cvsroot/CMake/CMake/Source/cmGlobalXCodeGenerator.cxx,v <-- cmGlobalXCodeGenerator.cxx
new revision: 1.180; previous revision: 1.179
/cvsroot/CMake/CMake/Source/cmLocalGenerator.cxx,v <-- cmLocalGenerator.cxx
new revision: 1.258; previous revision: 1.257
/cvsroot/CMake/CMake/Source/cmLocalGenerator.h,v <-- cmLocalGenerator.h
new revision: 1.99; previous revision: 1.98
/cvsroot/CMake/CMake/Source/cmLocalVisualStudio6Generator.cxx,v <-- cmLocalVisualStudio6Generator.cxx
new revision: 1.138; previous revision: 1.137
/cvsroot/CMake/CMake/Source/cmLocalVisualStudio7Generator.cxx,v <-- cmLocalVisualStudio7Generator.cxx
new revision: 1.214; previous revision: 1.213
/cvsroot/CMake/CMake/Source/cmLocalVisualStudio7Generator.h,v <-- cmLocalVisualStudio7Generator.h
new revision: 1.48; previous revision: 1.47
/cvsroot/CMake/CMake/Source/cmOrderLinkDirectories.cxx,v <-- cmOrderLinkDirectories.cxx
new revision: delete; previous revision: 1.38
/cvsroot/CMake/CMake/Source/cmOrderLinkDirectories.h,v <-- cmOrderLinkDirectories.h
new revision: delete; previous revision: 1.20
/cvsroot/CMake/CMake/Source/cmTarget.cxx,v <-- cmTarget.cxx
new revision: 1.178; previous revision: 1.177
/cvsroot/CMake/CMake/Source/cmTarget.h,v <-- cmTarget.h
new revision: 1.96; previous revision: 1.95
/cvsroot/CMake/CMake/Tests/Complex/Executable/complex.cxx,v <-- complex.cxx
new revision: 1.96; previous revision: 1.95
/cvsroot/CMake/CMake/Tests/ComplexOneConfig/Executable/complex.cxx,v <-- complex.cxx
new revision: 1.97; previous revision: 1.96
/cvsroot/CMake/CMake/Tests/ComplexRelativePaths/Executable/complex.cxx,v <-- complex.cxx
new revision: 1.98; previous revision: 1.97
(0010267)
Brad King (manager)
2008-01-23 16:38

I've committed a few more changes to fix some backwards compatibility issues. This bug fix is now complete.

 Issue History
Date Modified Username Field Change
2007-08-28 15:56 Zack Galbreath Project KWStyle => CMake
2007-08-28 15:57 Zack Galbreath Assigned To Clinton Stimpson => Brad King
2007-08-28 15:57 Zack Galbreath Resolution suspended => reopened
2007-08-28 15:57 Zack Galbreath Category => CMake
2007-08-28 15:57 Zack Galbreath Summary Goodsite => add support for static libraries in TARGET_LINK_LIBRARIES
2007-08-28 15:57 Zack Galbreath Note Deleted: 0007374
2007-08-28 15:57 Zack Galbreath Note Deleted: 0008149
2007-12-19 12:56 Steven Van Ingelgem Note Added: 0010002
2007-12-19 14:42 Brad King Note Added: 0010003
2007-12-24 12:17 Brad King Note Added: 0010020
2007-12-24 17:00 Brad King Note Added: 0010021
2008-01-22 09:29 Brad King Note Added: 0010208
2008-01-23 16:38 Brad King Status assigned => closed
2008-01-23 16:38 Brad King Note Added: 0010267
2008-01-23 16:38 Brad King Resolution reopened => fixed


Copyright © 2000 - 2018 MantisBT Team