Re: [CMake] Proper way to export a library
On 2013-11-02 13:38, Cyrille Faucheux wrote: [...] from what I understood from Matthew first answer (implicit compile flags [...] for imported tagets), I was under the impression that I could get MYPROJECT_STATIC automatically defined when linking another program against a static version of my library (through its imported target). Yes and no. *You* have to set the flag as part of your library's interface compile definitions. But once you do that, cmake should export that, and anyone linking to your library (via imported target) should automatically pick up the flag. I've looked the documentation of target_compile_definitions, but it seems to be about compiling the library, not linking against its imported target. Am I right? No; at least not entirely in the case of 't_c_d({PUBLIC|INTERFACE})'. A PUBLIC definition is used both to compile your library and by anyone linking to it. An INTERFACE definition is used *only* by other targets linking to it. See also the INTERFACE_COMPILE_DEFINITIONS property and note in the t_c_d documentation how t_c_d affects that property. -- Matthew -- 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: http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proper way to export a library
Wow, this thread has gone wild... To clarify my case: The prototype of each functions I want to export is prefixed by a MYPROJECT_EXTERNAL preprocessor constant. With Visual Studio, this constant is, by default, set to __declspec(dllimport). This way, I can link against the shared version of this library without having to define anything. When compiling this library as a shared library, I have to define a MYPROJECT_EXPORT_SHARED constant, which will set MYPROJECT_EXTERNAL to __declspec(dllimport). But if I want to build/link against a static version of this library, I need to pass a MYPROJECT_STATIC as a define in order to set MYPROJECT_EXTERNAL to nothing. From what I've read in your answers, it seems to be the way to go. My question was perhaps not clear. Compiling the library is not a problem, but from what I understood from Matthew first answer (implicit compile flags [...] for imported tagets), I was under the impression that I could get MYPROJECT_STATIC automatically defined when linking another program against a static version of my library (through its imported target). I've looked the documentation of target_compile_definitions, but it seems to be about compiling the library, not linking against its imported target. Am I right? 2013/10/31 David Cole dlrd...@aol.com Microsoft believed in hidden by default for shared libraries. Don't say things like this: people will never hide anything ever again... ;-) But seriously, making only those things public that are explicitly exported has some major benefits: for one, it minimizes the probability of clashes when combining multiple independent components. It really should be a software developer's rule of thumb / best practice to have the minimal set of symbols necessary be exported. Anything exported that does not need to be is a maintenance burden, a learning curve hurdle for newbies, and increases the likelihood of name clashes with other libraries: all bad things. So minimize your public APIs and your exports. 2 cents worth, D -- 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: http://www.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: http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proper way to export a library
Ok, great. Can you tell me a bit more about implicit compile flags [...] for imported tagets? On the library I'm currently working on, with Visual Studio, I have to declare some compile definition in order to get the proper __declspec(dllimport) or __declspec(dllexport) defined (or not defined when compiling/using a static version of this library). Does implicit compile flags means that those compile definition could be automatically declared by the imported target? 2013/10/30 Matthew Woehlke matthew.woeh...@kitware.com On 2013-10-30 13:56, Cyrille Faucheux wrote: I'm trying to learn how to properly import/export librairies with CMake. I think I've read somewhere that the proper way to export libraries is through the module mode (as described in [1]), but: a) I can't find back where I've read that, b) Lots of libraries are still using the module mode (Find*.cmake). Can you confirm me which mode I should choose? It's definitely preferred these days to work with exported/imported targets where possible. Unlike find modules, imported targets let you link to target names in consuming projects. Also, now that target usage requirements have arrived, you can have implicit compile flags, include directories, and interface link libraries for imported targets. All of this makes it much easier to use external libraries and lessens the distinction between an imported and local target. Additionally, this happens in one place. Find modules tend to end up copied about to different projects until/unless they wind up in CMake proper, and even then can linger on, resulting in multiple versions in varying states of bitrot. They can even be written multiple times by different people in unrelated projects. By providing a package config file (even one that just sets find module style variables) you prevent this proliferation and duplication of work. The flip side (and why you have a lot of find modules still) is that the onus to provide a package config file is on the upstream. This means that upstream must either build with CMake in the first place, and have the necessary logic in the CMake build instructions to generate a package config file (ideally with exported targets), or else be friendly enough to CMake to generate 'by hand' such a file despite using some other build system. It should go without saying that, especially in the latter case, politics can become involved here. -- Matthew -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/**CMake_FAQhttp://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.htmlhttp://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/**consulting.htmlhttp://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/**training.htmlhttp://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/** opensource/opensource.htmlhttp://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://www.cmake.org/mailman/**listinfo/cmakehttp://www.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: http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proper way to export a library
On 2013-10-31 05:26, Cyrille Faucheux wrote: Can you tell me a bit more about implicit compile flags [...] for imported tagets? See documentation on target_compile_definitions. On the library I'm currently working on, with Visual Studio, I have to declare some compile definition in order to get the proper __declspec(dllimport) or __declspec(dllexport) defined (or not defined when compiling/using a static version of this library). This sounds like you're doing it wrong. When building with CMake, the preferred way is to unconditionally define an ABI export symbol via a header which exists for that purpose (e.g. config.h, my_package_exports.h, etc.). The value of the definition however is conditional on a symbol that is only defined when building the library, to choose between import and export as appropriate. Even better, CMake will define target_EXPORTS for you when building a library, so you shouldn't need to manually specify any definitions at all. IOW you libraries headers would somewhere contain: #if defined(_WIN32) # define MYPROJECT_ABI_EXPORT __declspec(dllexport) # define MYPROJECT_ABI_IMPORT __declspec(dllimport) #elif __GNUC__ = 4 # define MYPROJECT_ABI_EXPORT __attribute__ ((visibility(default))) # define MYPROJECT_ABI_IMPORT __attribute__ ((visibility(default))) #else # define MYPROJECT_ABI_EXPORT # define MYPROJECT_ABI_IMPORT #endif ...and: #ifdef mylibrary_EXPORTS # define MYLIBRARY_EXPORT MYPROJECT_ABI_EXPORT #else # define MYLIBRARY_EXPORT MYPROJECT_ABI_IMPORT #endif That said... Does implicit compile flags means that those compile definition could be automatically declared by the imported target? ...this was my understanding of how target_compile_definitions(PUBLIC) is supposed to work. (Note: I haven't actually used this feature myself yet.) -- Matthew -- 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: http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proper way to export a library
Cyrille Faucheux wrote: Ok, great. Can you tell me a bit more about implicit compile flags [...] for imported tagets? On the library I'm currently working on, with Visual Studio, I have to declare some compile definition in order to get the proper __declspec(dllimport) or __declspec(dllexport) defined (or not defined when compiling/using a static version of this library). Use the GenerateExportHeader module. Thanks, Steve. -- 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: http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proper way to export a library
Matthew Woehlke matthew.woeh...@kitware.com schrieb: On 2013-10-31 05:26, Cyrille Faucheux wrote: Can you tell me a bit more about implicit compile flags [...] for imported tagets? See documentation on target_compile_definitions. On the library I'm currently working on, with Visual Studio, I have to declare some compile definition in order to get the proper __declspec(dllimport) or __declspec(dllexport) defined (or not defined when compiling/using a static version of this library). This sounds like you're doing it wrong. Not really as you can only cover the export import with this case but not static vs. dynamic linking to that library with the same header file. That it's usually solved with a define when linking statically When building with CMake, the preferred way is to unconditionally define an ABI export symbol via a header which exists for that purpose (e.g. config.h, my_package_exports.h, etc.). The value of the definition however is conditional on a symbol that is only defined when building the library, to choose between import and export as appropriate. Even better, CMake will define target_EXPORTS for you when building a library, so you shouldn't need to manually specify any definitions at all. IOW you libraries headers would somewhere contain: #if defined(_WIN32) # define MYPROJECT_ABI_EXPORT __declspec(dllexport) # define MYPROJECT_ABI_IMPORT __declspec(dllimport) #elif __GNUC__ = 4 # define MYPROJECT_ABI_EXPORT __attribute__ ((visibility(default))) # define MYPROJECT_ABI_IMPORT __attribute__ ((visibility(default))) #else # define MYPROJECT_ABI_EXPORT # define MYPROJECT_ABI_IMPORT #endif ...and: #ifdef mylibrary_EXPORTS # define MYLIBRARY_EXPORT MYPROJECT_ABI_EXPORT #else # define MYLIBRARY_EXPORT MYPROJECT_ABI_IMPORT #endif That said... Does implicit compile flags means that those compile definition could be automatically declared by the imported target? ...this was my understanding of how target_compile_definitions(PUBLIC) is supposed to work. (Note: I haven't actually used this feature myself yet.) -- 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: http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proper way to export a library
something like (but probably mostly in a common header) if( IS_THIS_PROJECT ) if( UNIX or STATIC ) set( EXPORT ) # nothing, everything is exported by default; gcc/unix else( UNIX or STATIC ) set( EXPORT __declspec(dllexport) ) endif( UNIX or STATIC ) else( IS_THIS_PROJECT ) # if something else includes this if( UNIX or STATIC ) set( EXPORT extern ) else( UNIX or STATIC ) set( EXPORT __declspec(dllimport) ) endif( UNIX or STATIC ) endif( IS_THIS_PROJECT ) On Thu, Oct 31, 2013 at 11:46 AM, Hendrik Sattler p...@hendrik-sattler.de wrote: Matthew Woehlke matthew.woeh...@kitware.com schrieb: On 2013-10-31 05:26, Cyrille Faucheux wrote: Can you tell me a bit more about implicit compile flags [...] for imported tagets? See documentation on target_compile_definitions. On the library I'm currently working on, with Visual Studio, I have to declare some compile definition in order to get the proper __declspec(dllimport) or __declspec(dllexport) defined (or not defined when compiling/using a static version of this library). This sounds like you're doing it wrong. Not really as you can only cover the export import with this case but not static vs. dynamic linking to that library with the same header file. That it's usually solved with a define when linking statically When building with CMake, the preferred way is to unconditionally define an ABI export symbol via a header which exists for that purpose (e.g. config.h, my_package_exports.h, etc.). The value of the definition however is conditional on a symbol that is only defined when building the library, to choose between import and export as appropriate. Even better, CMake will define target_EXPORTS for you when building a library, so you shouldn't need to manually specify any definitions at all. IOW you libraries headers would somewhere contain: #if defined(_WIN32) # define MYPROJECT_ABI_EXPORT __declspec(dllexport) # define MYPROJECT_ABI_IMPORT __declspec(dllimport) #elif __GNUC__ = 4 # define MYPROJECT_ABI_EXPORT __attribute__ ((visibility(default))) # define MYPROJECT_ABI_IMPORT __attribute__ ((visibility(default))) #else # define MYPROJECT_ABI_EXPORT # define MYPROJECT_ABI_IMPORT #endif ...and: #ifdef mylibrary_EXPORTS # define MYLIBRARY_EXPORT MYPROJECT_ABI_EXPORT #else # define MYLIBRARY_EXPORT MYPROJECT_ABI_IMPORT #endif That said... Does implicit compile flags means that those compile definition could be automatically declared by the imported target? ...this was my understanding of how target_compile_definitions(PUBLIC) is supposed to work. (Note: I haven't actually used this feature myself yet.) -- 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: http://www.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: http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proper way to export a library
On 2013-10-31 14:46, Hendrik Sattler wrote: Matthew Woehlke schrieb: On 2013-10-31 05:26, Cyrille Faucheux wrote: On the library I'm currently working on, with Visual Studio, I have to declare some compile definition in order to get the proper __declspec(dllimport) or __declspec(dllexport) defined (or not defined when compiling/using a static version of this library). This sounds like you're doing it wrong. Not really as you can only cover the export import with this case but not static vs. dynamic linking to that library with the same header file. That it's usually solved with a define when linking statically Ah, yes, I forgot. You are right, you either need to pass a define that you are built static or else have it defined or not in a generated header. Is it just the MYPROJECT_STATIC that you need to pass as a define? That would indeed be a good candidate for t_c_d(PUBLIC). (I got the - erroneous? - impression you were actually passing e.g. -DMY_ABI=__dllspec(dllimport)...) -- Matthew -- 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: http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proper way to export a library
I am a firm believer that static libraries should have hidden visibility. This is based on my experience on the Mac and may be different in Linux. A shared library (dylib, framework) can export a symbol that came in from a static library as a private extern. If the symbol is extern (visibility=default) in the static library, the shared library cannot hide it unless the shared library is linked using an explicit list of the symbols to export. A list of exports maybe isn't so bad for a small to intermediate C library, but for any kind of C++ library, it's a huge pain. The proper use of visibility avoids all that pain. The static library symbol visibility makes no difference when the static library is linked into an executable. -Original Message- From: cmake-boun...@cmake.org [mailto:cmake-boun...@cmake.org] On Behalf Of J Decker Sent: Thursday, October 31, 2013 3:27 PM To: Hendrik Sattler Cc: Matthew Woehlke; cmake@cmake.org Subject: Re: [CMake] Proper way to export a library something like (but probably mostly in a common header) if( IS_THIS_PROJECT ) if( UNIX or STATIC ) set( EXPORT ) # nothing, everything is exported by default; gcc/unix else( UNIX or STATIC ) set( EXPORT __declspec(dllexport) ) endif( UNIX or STATIC ) else( IS_THIS_PROJECT ) # if something else includes this if( UNIX or STATIC ) set( EXPORT extern ) else( UNIX or STATIC ) set( EXPORT __declspec(dllimport) ) endif( UNIX or STATIC ) endif( IS_THIS_PROJECT ) On Thu, Oct 31, 2013 at 11:46 AM, Hendrik Sattler p...@hendrik-sattler.de wrote: Matthew Woehlke matthew.woeh...@kitware.com schrieb: On 2013-10-31 05:26, Cyrille Faucheux wrote: Can you tell me a bit more about implicit compile flags [...] for imported tagets? See documentation on target_compile_definitions. On the library I'm currently working on, with Visual Studio, I have to declare some compile definition in order to get the proper __declspec(dllimport) or __declspec(dllexport) defined (or not defined when compiling/using a static version of this library). This sounds like you're doing it wrong. Not really as you can only cover the export import with this case but not static vs. dynamic linking to that library with the same header file. That it's usually solved with a define when linking statically When building with CMake, the preferred way is to unconditionally define an ABI export symbol via a header which exists for that purpose (e.g. config.h, my_package_exports.h, etc.). The value of the definition however is conditional on a symbol that is only defined when building the library, to choose between import and export as appropriate. Even better, CMake will define target_EXPORTS for you when building a library, so you shouldn't need to manually specify any definitions at all. IOW you libraries headers would somewhere contain: #if defined(_WIN32) # define MYPROJECT_ABI_EXPORT __declspec(dllexport) # define MYPROJECT_ABI_IMPORT __declspec(dllimport) #elif __GNUC__ = 4 # define MYPROJECT_ABI_EXPORT __attribute__ ((visibility(default))) # define MYPROJECT_ABI_IMPORT __attribute__ ((visibility(default))) #else # define MYPROJECT_ABI_EXPORT # define MYPROJECT_ABI_IMPORT #endif ...and: #ifdef mylibrary_EXPORTS # define MYLIBRARY_EXPORT MYPROJECT_ABI_EXPORT #else # define MYLIBRARY_EXPORT MYPROJECT_ABI_IMPORT #endif That said... Does implicit compile flags means that those compile definition could be automatically declared by the imported target? ...this was my understanding of how target_compile_definitions(PUBLIC) is supposed to work. (Note: I haven't actually used this feature myself yet.) -- 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: http://www.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
Re: [CMake] Proper way to export a library
Giordano Khouri kgiord...@nikon.net schrieb: I am a firm believer that static libraries should have hidden visibility. This is based on my experience on the Mac and may be different in Linux. This is about Windows, not Linux or Mac. Linking libraries works a bit different there. A shared library (dylib, framework) can export a symbol that came in from a static library as a private extern. If the symbol is extern (visibility=default) in the static library, the shared library cannot hide it unless the shared library is linked using an explicit list of the symbols to export. A list of exports maybe isn't so bad for a small to intermediate C library, but for any kind of C++ library, it's a huge pain. The proper use of visibility avoids all that pain. The static library symbol visibility makes no difference when the static library is linked into an executable. -Original Message- From: cmake-boun...@cmake.org [mailto:cmake-boun...@cmake.org] On Behalf Of J Decker Sent: Thursday, October 31, 2013 3:27 PM To: Hendrik Sattler Cc: Matthew Woehlke; cmake@cmake.org Subject: Re: [CMake] Proper way to export a library something like (but probably mostly in a common header) if( IS_THIS_PROJECT ) if( UNIX or STATIC ) set( EXPORT ) # nothing, everything is exported by default; gcc/unix else( UNIX or STATIC ) set( EXPORT __declspec(dllexport) ) endif( UNIX or STATIC ) else( IS_THIS_PROJECT ) # if something else includes this if( UNIX or STATIC ) set( EXPORT extern ) else( UNIX or STATIC ) set( EXPORT __declspec(dllimport) ) endif( UNIX or STATIC ) endif( IS_THIS_PROJECT ) On Thu, Oct 31, 2013 at 11:46 AM, Hendrik Sattler p...@hendrik-sattler.de wrote: Matthew Woehlke matthew.woeh...@kitware.com schrieb: On 2013-10-31 05:26, Cyrille Faucheux wrote: Can you tell me a bit more about implicit compile flags [...] for imported tagets? See documentation on target_compile_definitions. On the library I'm currently working on, with Visual Studio, I have to declare some compile definition in order to get the proper __declspec(dllimport) or __declspec(dllexport) defined (or not defined when compiling/using a static version of this library). This sounds like you're doing it wrong. Not really as you can only cover the export import with this case but not static vs. dynamic linking to that library with the same header file. That it's usually solved with a define when linking statically When building with CMake, the preferred way is to unconditionally define an ABI export symbol via a header which exists for that purpose (e.g. config.h, my_package_exports.h, etc.). The value of the definition however is conditional on a symbol that is only defined when building the library, to choose between import and export as appropriate. Even better, CMake will define target_EXPORTS for you when building a library, so you shouldn't need to manually specify any definitions at all. IOW you libraries headers would somewhere contain: #if defined(_WIN32) # define MYPROJECT_ABI_EXPORT __declspec(dllexport) # define MYPROJECT_ABI_IMPORT __declspec(dllimport) #elif __GNUC__ = 4 # define MYPROJECT_ABI_EXPORT __attribute__ ((visibility(default))) # define MYPROJECT_ABI_IMPORT __attribute__ ((visibility(default))) #else # define MYPROJECT_ABI_EXPORT # define MYPROJECT_ABI_IMPORT #endif ...and: #ifdef mylibrary_EXPORTS # define MYLIBRARY_EXPORT MYPROJECT_ABI_EXPORT #else # define MYLIBRARY_EXPORT MYPROJECT_ABI_IMPORT #endif That said... Does implicit compile flags means that those compile definition could be automatically declared by the imported target? ...this was my understanding of how target_compile_definitions(PUBLIC) is supposed to work. (Note: I haven't actually used this feature myself yet.) -- 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: http://www.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
Re: [CMake] Proper way to export a library
On Thu, Oct 31, 2013 at 1:21 PM, Hendrik Sattler p...@hendrik-sattler.de wrote: Giordano Khouri kgiord...@nikon.net schrieb: I am a firm believer that static libraries should have hidden visibility. This is based on my experience on the Mac and may be different in Linux. This is about Windows, not Linux or Mac. Linking libraries works a bit different there. While that's true, I will concur that hidden is a good thing; there have been several times I have accidentally defined a function with the same name as some library included by a library by a library by a library that ended up with a stack overflow or other bad behavior; everyone should know how to target every platform :) Microsoft believed in hidden by default for shared libraries. A shared library (dylib, framework) can export a symbol that came in from a static library as a private extern. If the symbol is extern (visibility=default) in the static library, the shared library cannot hide it unless the shared library is linked using an explicit list of the symbols to export. A list of exports maybe isn't so bad for a small to intermediate C library, but for any kind of C++ library, it's a huge pain. The proper use of visibility avoids all that pain. The static library symbol visibility makes no difference when the static library is linked into an executable. -Original Message- From: cmake-boun...@cmake.org [mailto:cmake-boun...@cmake.org] On Behalf Of J Decker Sent: Thursday, October 31, 2013 3:27 PM To: Hendrik Sattler Cc: Matthew Woehlke; cmake@cmake.org Subject: Re: [CMake] Proper way to export a library something like (but probably mostly in a common header) if( IS_THIS_PROJECT ) if( UNIX or STATIC ) set( EXPORT ) # nothing, everything is exported by default; gcc/unix else( UNIX or STATIC ) set( EXPORT __declspec(dllexport) ) endif( UNIX or STATIC ) else( IS_THIS_PROJECT ) # if something else includes this if( UNIX or STATIC ) set( EXPORT extern ) else( UNIX or STATIC ) set( EXPORT __declspec(dllimport) ) endif( UNIX or STATIC ) endif( IS_THIS_PROJECT ) On Thu, Oct 31, 2013 at 11:46 AM, Hendrik Sattler p...@hendrik-sattler.de wrote: Matthew Woehlke matthew.woeh...@kitware.com schrieb: On 2013-10-31 05:26, Cyrille Faucheux wrote: Can you tell me a bit more about implicit compile flags [...] for imported tagets? See documentation on target_compile_definitions. On the library I'm currently working on, with Visual Studio, I have to declare some compile definition in order to get the proper __declspec(dllimport) or __declspec(dllexport) defined (or not defined when compiling/using a static version of this library). This sounds like you're doing it wrong. Not really as you can only cover the export import with this case but not static vs. dynamic linking to that library with the same header file. That it's usually solved with a define when linking statically When building with CMake, the preferred way is to unconditionally define an ABI export symbol via a header which exists for that purpose (e.g. config.h, my_package_exports.h, etc.). The value of the definition however is conditional on a symbol that is only defined when building the library, to choose between import and export as appropriate. Even better, CMake will define target_EXPORTS for you when building a library, so you shouldn't need to manually specify any definitions at all. IOW you libraries headers would somewhere contain: #if defined(_WIN32) # define MYPROJECT_ABI_EXPORT __declspec(dllexport) # define MYPROJECT_ABI_IMPORT __declspec(dllimport) #elif __GNUC__ = 4 # define MYPROJECT_ABI_EXPORT __attribute__ ((visibility(default))) # define MYPROJECT_ABI_IMPORT __attribute__ ((visibility(default))) #else # define MYPROJECT_ABI_EXPORT # define MYPROJECT_ABI_IMPORT #endif ...and: #ifdef mylibrary_EXPORTS # define MYLIBRARY_EXPORT MYPROJECT_ABI_EXPORT #else # define MYLIBRARY_EXPORT MYPROJECT_ABI_IMPORT #endif That said... Does implicit compile flags means that those compile definition could be automatically declared by the imported target? ...this was my understanding of how target_compile_definitions(PUBLIC) is supposed to work. (Note: I haven't actually used this feature myself yet.) -- 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: http://www.cmake.org
Re: [CMake] Proper way to export a library
On 31 October 2013 20:21, Hendrik Sattler p...@hendrik-sattler.de wrote: Giordano Khouri kgiord...@nikon.net schrieb: I am a firm believer that static libraries should have hidden visibility. This is based on my experience on the Mac and may be different in Linux. This is about Windows, not Linux or Mac. Linking libraries works a bit different there. BTW, the original question in this thread was about exporting libraries as targets in the CMake configuration. Suddenly, the thread has switched to completely unrelated and messy topic on Microsoft-specific storage-class attributes dllexport and dllimport. IMO, OP should split the threads for sake of the list usability. Best regards, -- Mateusz Loskot, http://mateusz.loskot.net -- 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: http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proper way to export a library
Microsoft believed in hidden by default for shared libraries. Don't say things like this: people will never hide anything ever again... ;-) But seriously, making only those things public that are explicitly exported has some major benefits: for one, it minimizes the probability of clashes when combining multiple independent components. It really should be a software developer's rule of thumb / best practice to have the minimal set of symbols necessary be exported. Anything exported that does not need to be is a maintenance burden, a learning curve hurdle for newbies, and increases the likelihood of name clashes with other libraries: all bad things. So minimize your public APIs and your exports. 2 cents worth, D -- 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: http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proper way to export a library
On 2013-10-30 13:56, Cyrille Faucheux wrote: I'm trying to learn how to properly import/export librairies with CMake. I think I've read somewhere that the proper way to export libraries is through the module mode (as described in [1]), but: a) I can't find back where I've read that, b) Lots of libraries are still using the module mode (Find*.cmake). Can you confirm me which mode I should choose? It's definitely preferred these days to work with exported/imported targets where possible. Unlike find modules, imported targets let you link to target names in consuming projects. Also, now that target usage requirements have arrived, you can have implicit compile flags, include directories, and interface link libraries for imported targets. All of this makes it much easier to use external libraries and lessens the distinction between an imported and local target. Additionally, this happens in one place. Find modules tend to end up copied about to different projects until/unless they wind up in CMake proper, and even then can linger on, resulting in multiple versions in varying states of bitrot. They can even be written multiple times by different people in unrelated projects. By providing a package config file (even one that just sets find module style variables) you prevent this proliferation and duplication of work. The flip side (and why you have a lot of find modules still) is that the onus to provide a package config file is on the upstream. This means that upstream must either build with CMake in the first place, and have the necessary logic in the CMake build instructions to generate a package config file (ideally with exported targets), or else be friendly enough to CMake to generate 'by hand' such a file despite using some other build system. It should go without saying that, especially in the latter case, politics can become involved here. -- Matthew -- 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: http://www.cmake.org/mailman/listinfo/cmake