[CMake] Single library with both shared and static binaries

J Decker d3ck0r at gmail.com
Thu Sep 26 22:02:21 EDT 2019


I ended up using external_project() because unless you also copy the source
files, each source file each only gets one set of flags... so if you have
different compile options (the config file I suppose) the sources will only
build with one or the other.

If you copy all of the sources to the CMAKE_BiNARY_DIR (which can be done
passing a list of sources to a macro, which can then extract the path part
and append it) then use copy_file_if_different()  (And I additionally touch
that file to make sure the copy definitely gets built when it dos get
copied)  then you can build two targets with different options for the
sources.

Otherwise, an internal external project works pretty well.
https://github.com/d3x0r/SACK/blob/master/binary/CMakeLists.txt#L61

I kinda moved away from building both dynamic static libaries,and the
static binaries are just external projects that reference the original
sources.


On Thu, Sep 26, 2019 at 1:06 PM Avraham Shukron <avraham.shukron at gmail.com>
wrote:

> There is no hard requirement for shipping both static and shared. With the
> back against the wall I could get away with SHARED only, since it is the
> most common way the library will be consumed. I wanted to also distribute a
> static version just for those who want a single, self-contained executable.
>
> I understand that static and shared libraries ARE in fact two different
> target, but for the most part they are configured the same way and have the
> same properties.
>
> The fact that the recommended practice is to NOT specify SHARED / STATIC
> in add_library and let the user decide which one to compile using
> BUILD_SHARED_LIBS, proves that a library target is expected to be
> independent on whether it is compiled as a shared object or static library.
>
> I agree that it would be great to have the ability to produce both shared
> and static binaries from a single library target, although we need to think
> of how users importing such target, will be able to specify if they want to
> link against the static or the shared binary.
>
>
> On Thu, Sep 26, 2019 at 5:38 PM Juan Sanchez <juan.e.sanchez at gmail.com>
> wrote:
>
>> Here is an example where two libraries are created from object files that
>> have only been compiled once:
>>
>> ADD_LIBRARY(symdiff_objects OBJECT ${CXX_SRCS} ${MC_SRCS})
>> set_property(TARGET symdiff_objects PROPERTY POSITION_INDEPENDENT_CODE ON)
>> ADD_LIBRARY(symdiff_dynamic STATIC $<TARGET_OBJECTS:symdiff_objects>)
>> ADD_LIBRARY(symdiff SHARED $<TARGET_OBJECTS:symdiff_objects>)
>>
>> The "symdiff_dynamic" library is a static archive that can then be linked
>> into another shared library or an executable. The "symdiff" library is a
>> standalone object.  The POSITION_INDEPENDENT_CODE property is required for
>> the linux platform, but not for macOS or Windows.  If the original poster
>> is comfortable with having a PIC static library, this is an approach they
>> can take.
>>
>> Regards,
>>
>> Juan
>>
>> On Wed, Sep 25, 2019 at 8:43 AM Kyle Edwards via CMake <cmake at cmake.org>
>> wrote:
>>
>>> On Tue, 2019-09-24 at 23:41 +0300, Avraham Shukron wrote:
>>> > Hi!
>>> >
>>> > I have a library which I want to distribute in both shared object and
>>> > static library forms.
>>> > Is there a modern way to do it without creating two completely
>>> > separate library targets?
>>> > Since I want to be a good CMake citizen I use `target_*` and
>>> > `set_target_properties` as much as possible, and creating two
>>> > different libraries will force me to duplicate that information about
>>> > each one of them.
>>> >
>>> > I also tries not specifying STATIC/SHARED, and then running cmake
>>> > twice - once with BUILD_SHARED_LIBS=ON and once OFF and then
>>> > installing to the same directory. I got my both .a and .so libraries
>>> > installed, but I couldn't get the Config file correctly for this
>>> > arrangement.
>>> >
>>> > So - what is the community-recommended pattern to do this?
>>>
>>> Unfortunately, the recommendation is to do exactly what you don't want
>>> to do: create a shared target and a static target.
>>>
>>> To make this slightly simpler, you can use functions to de-duplicate
>>> the target_* and set_target_properties calls:
>>>
>>> function(create_foo_target name type)
>>>   add_library(${name} ${type} foo.c foo.h)
>>>   set_target_properties(${name} OUTPUT_NAME foo)
>>> endfunction()
>>>
>>> create_foo_target(foo_shared SHARED)
>>> create_foo_target(foo_static STATIC)
>>>
>>> Kyle
>>> --
>>>
>>> Powered by www.kitware.com
>>>
>>> Please keep messages on-topic and check the CMake FAQ at:
>>> http://www.cmake.org/Wiki/CMake_FAQ
>>>
>>> Kitware offers various services to support the CMake community. For more
>>> information on each offering, please visit:
>>>
>>> CMake Support: http://cmake.org/cmake/help/support.html
>>> CMake Consulting: http://cmake.org/cmake/help/consulting.html
>>> CMake Training Courses: http://cmake.org/cmake/help/training.html
>>>
>>> Visit other Kitware open-source projects at
>>> http://www.kitware.com/opensource/opensource.html
>>>
>>> Follow this link to subscribe/unsubscribe:
>>> https://cmake.org/mailman/listinfo/cmake
>>>
>> --
>
> Powered by www.kitware.com
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Kitware offers various services to support the CMake community. For more
> information on each offering, please visit:
>
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/training.html
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> https://cmake.org/mailman/listinfo/cmake
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20190926/7d5093a1/attachment-0001.html>


More information about the CMake mailing list