[cmake-developers] portable way for linking (single) libraries statically or dynamically
Christoph Anton Mitterer
calestyo at scientia.net
Mon Apr 9 19:39:55 EDT 2012
On Mon, 2012-04-09 at 13:41 -0400, Brad King wrote:
> I'm not commenting either way. I'm just saying that is what may
> need to be done to address your concerns.
Well I mean it's rather obvious that I personally miss far to much
insight in the inner workings of CMake to push/implement such big
> How it is linked depends on the file type at the given full path.
> If it is an archive it will be linked statically and if it is a
> shared library it will be linked dynamically. Options like -Bstatic
> only tell the linker to prefer "libX.a" when searching for "-lX".
> If the full path is already known it is meaningless.
I've also understood that in the meantime :) My bad!
> > So basically link_directories() == deprecated...
> I wouldn't say "deprecated" because it is still useful to some people.
Ok what I rather meant was:
It's recommended to use full pathnames and _then_ link_directories() is
not needed obviously.
> There are just better ways to do things most of the time.
See, this is one of the examples on "how to do things right" I've missed
somewhere in the CMake documentation.
Till know I basically always used -lXXX and no full paths. ;-)
> On Windows there is no way to tell if a library is static or shared
> from just the file name. Linkers do not use "foo.dll". They use a
> corresponding "import library" called "foo.lib". It is possible for
> "foo.lib" to be either an import library for foo.dll *or* its own
> static library. There is no way to tell without parsing the binary
> format. Also Windows toolchains have no equivalent to -Bstatic so
> it does not make sense to "request" static or dynamic linking. One
> must always specify the full path to a given library file to get it.
I see,... fuck Wind***
> Use find_library to locate a library file. Then pass the result to
> target_link_libraries. Since find_library stores the result in a
> user-editable persistent cache users can always specify an exact
> library file to use as the result of find_library. The user can
> choose a .a or .so to get the linking type desired.
Phew,... well of course this is possible, but also means that one is
already back to quite a lot of manual work.
It could be that changing the .so to .a isn't enough, maybe the
libraries are in different directories or not installed at all...
> > Also, I'm not sure whether I fully understand the ideas here...
> > for me a target is something that I build in my project...
> > but I never build the external libarary...
> That's why they're called "imported" targets. They are imported
> from an outside source so they can be referenced as if they had
> been built inside (from say target_link_libraries).
Yeah,... I mean don't feel offended or so,... this just looks a bit
messy to me.
"target" is something that is build... pretending imported or virtual
targets sounds a bit strange...
> Imported targets are not themselves linked to form new files. Their
> existing files loaded from outside the project can be linked into other
> targets that are built inside the project. Transitive dependencies and
> such are specified in target IMPORTED_* properties.
So basically the export functions is just something that automatically
generates the .cmake file and even sets the necessary paths in there
where the libs were installed, as known via the install command.
The XXXConfig.cmake files then have all the necessary information to
find the paths of all the (e.g.) libs?
Getting the paths in a auto-created file should have been possible
without introducing the concept of imported targets,.. right?
I assume you did it because you wanted all the transitive dependencies
How's the following handled:
when libraries need you to add special defines or other compiler flags
(of course the later would make it non-portable).
pkg-config at least provides such files (though I've never seen them
I'm still not sure whether the concept of imported/virtual targets seems
"clean" to me,... but the main problem is anyway that till now they're
now very wide spread, right?
> > Well I still don't see how I can do this fully portable
> As explained above Windows (MS-style tools) do not distinguish static
> v. shared using the library file name in any way. One *must* choose
> the desired library file and specify it by full path. IOW the entire
> concept of asking a tool to "search for a shared lib" or "search for
> a static lib" is not portable. Instead CMake projects should just use
> find_library so that a user can specify the desired library file if
> the one found automatically is not preferred.
Whew,.. wait... disagree...
a) In all *NIX (as far as I can see) it's just perfectly possible to
decide wheter a lib is sharable (dynamically linkable) or not (i.e. an
archive .a file), right?
Just because windows is stupid we shouldn't restrict our self that much,
especially as *NIX is probably the main platform for CMake anyway.
b) There must be some other way (if not by name) how in Windows it's
decided whether linking statically or dynamically?
At some point their linkers must decide somehow what to do.
Unfortunately, I had posted another reply under the wrong topic,
especially this one:
so perhaps you can visit the open mails in that thread when you have
occasionally time :)
I still think most of this could work as I describe, at least for *NIX.
As you enlightened me above, it's probably not that easy for windows.
But perhaps some things can be done for Windows:
a) Can't we parse that binary information somehow?
b) We could give responsibility to find-package, i.e. that one is
responsible to return the right paths for the right variables (and lib
-------------- next part --------------
A non-text attachment was scrubbed...
Size: 5677 bytes
Desc: not available
More information about the cmake-developers