[CMake] target_link_libraries: prefer static to dynamic

Pau Garcia i Quiles pgquiles at elpauer.org
Sun Dec 27 17:30:57 EST 2009


On Sun, Dec 27, 2009 at 10:16 PM, Michael Wild <themiwi at gmail.com> wrote:
>
> On 27. Dec, 2009, at 20:41 , Pau Garcia i Quiles wrote:
>
>> On Sun, Dec 27, 2009 at 10:59 AM, Michael Wild <themiwi at gmail.com> wrote:
>>>
>>> On 26. Dec, 2009, at 17:53 , Pau Garcia i Quiles wrote:
>>>
>>>> Hello,
>>>>
>>>> I think this has already been discussed and the answer is negative but
>>>> still: when I do target_link_libraries to an external library (for
>>>> instance, my application needs to link to sqlite), is it possible to
>>>> tell CMake to link to the static version of sqlite instead of the
>>>> dynamic version?
>>>>
>>>> For instance, in Debian the libsqlite3-dev package contains both the
>>>> static and the dynamic versions of the library and they have the very
>>>> same name:
>>>>
>>>> /usr/lib/libsqlite3.a
>>>> /usr/lib/libsqlite3.so
>>>>
>>>> ( http://packages.debian.org/sid/i386/libsqlite3-dev/filelist )
>>>>
>>>> Is this feature going to be implemented any time soon? I have not
>>>> looked at the sources for target_link_libraries but at first sight it
>>>> doesn't look difficult to add  something like
>>>> "static;optimized;libsqlite3.a;dynamic;optimized;libsqlite3.so".
>>>> There's the problem of find_library on Windows confusing the .lib as
>>>> the import for a .dll with a static .lib library but IIRC it's
>>>> possible to detect that.
>>>
>>> Perhaps a variable CMAKE_FIND_STATIC with the possible values "FIRST" "LAST", "ONLY" and "NEVER, similar to CMAKE_FIND_FRAMEWORK, would fit the bill?
>>
>> No, it won't. If my application links to two libraries, I may want to
>> link statically to libA but dynamically to libB.
>
> But then, on Debian a static version of sqlite3 is available, but not on Mac OS X (that is, without compiling it yourself). What should be the behavior there? Perhaps this could be expanded to optional options FIND_STATIC of find_library and find_package? Besides, the variable IS enough:
>
> set(CMAKE_FIND_STATIC FIRST)
> find_library(SQLITE_LIBRARY sqlite3)
>
> set(CMAKE_FIND_STATIC LAST)
> find_library(OTHER_LIBRARY other)

Instead of having CMAKE_FIND_STATIC, CMAKE_FIND_FRAMEWORK,
CMAKE_FIND_APPBUNDLE, etc, those could be replaced with something like
this in find_library:

find_library(
          <VAR>
          name | NAMES name1 [name2 ...]
          [...]
          VARIANT variant1 [variant2 ...]
          )

Where "variant1", "variant2", etc would be "shared static framework
bundle" by default. That'd mean find_libraries searches for shared,
static, framework and bundle in that order.

With my proposal for find_library, and the one I made in the first
e-mail of this thread, if I do:

find_library( SQLITE3_LIBRARY_RELEASE sqlite3 VARIANT static shared )

I'd have:
SQLITE3_LIBRARY_RELEASE=static;release;/usr/lib/libsqlite3.a

But if I do:

find_library( SQLITE3_LIBRARY_RELEASE sqlite3 VARIANT shared static )

I'd have:
SQLITE3_LIBRARY_RELEASE=share;release;/usr/lib/libsqlite3.so

I. e. I'm expressing preference: in the first case I'm saying "I'd
like to find a static version of sqlite3 but if it's not available,
give me the shared version". I could also look for the static version
only:

find_library( SQLITE3_LIBRARY_RELEASE sqlite3 VARIANT static )

or the shared one:

find_library( SQLITE3_LIBRARY_RELEASE sqlite3 VARIANT shared )

Meaning: in the first case "I want to find a static version of sqlite3
and fail if it's not available".

Neither of those should not be the default, though.

So for instance if I do:

find_library( SQLITE3_LIBRARY_RELEASE sqlite3 )

That'd would be equivalent to:

find_library( SQLITE3_LIBRARY_RELEASE sqlite3 VARIANT shared static
framework bundle )


-- 
Pau Garcia i Quiles
http://www.elpauer.org
(Due to my workload, I may need 10 days to answer)


More information about the CMake mailing list