Re: [CMake] Single library with both shared and static binaries
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 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 > 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 $) >> ADD_LIBRARY(symdiff SHARED $) >> >> 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 >> 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: >>>
Re: [CMake] Single library with both shared and static binaries
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 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 $) > ADD_LIBRARY(symdiff SHARED $) > > 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 > 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
Re: [CMake] Single library with both shared and static binaries
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 $) ADD_LIBRARY(symdiff SHARED $) 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 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
Re: [CMake] Single library with both shared and static binaries
Hi, On Tue, Sep 24, 2019 at 11:41:54PM +0300, Avraham Shukron wrote: > I have a library which I want to distribute in both shared object and > static library forms. Is that a requirement for your project, or a requirement for the system integrator? With my Debian Developer hat on, I'm always grateful when a project's build system doesn't do anything unexpected. We know that libtool generates shared and static libraries at the same time, and so when wrapping an autoconf based project, we use a single build tree and expect both to pop up. With CMake, we know that the build system cannot generate both at the same time. It would be cool if it could, but the expectation is that a library project will have to be built twice, and our tools mirror that expectation. If the majority of your users compile from source and need both shared and static libraries to be built, it makes sense to have two targets. Otherwise, the principle of least surprise applies. That said, a hypothetical future version of CMake that makes this easier so we can at some point remove the requirement to build twice would be awesome. Simon -- 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
Re: [CMake] Single library with both shared and static binaries
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