[CMake] import/export and DLL's

Michael Jackson mike.jackson at bluequartz.net
Tue Dec 6 22:09:31 EST 2011


___________________________________________________________
Mike Jackson                      www.bluequartz.net
Principal Software Engineer       mike.jackson at bluequartz.net 
BlueQuartz Software               Dayton, Ohio

On Dec 6, 2011, at 7:59 PM, Totte Karlsson wrote:

> On 12/6/2011 8:10 AM, Michael Jackson wrote:
>> Read this article.
>> 
>> http://www.cmake.org/Wiki/BuildingWinDLL
> Yeah, I did start with that one. My main problem was (as M. Wild) pointed out, defining the build flags correctly. I ended up using
> add_definitions(-DEXPORT_MOLECULE_DLL)
> 
> In the article, the
> SET_TARGET_PROPERTIES (MyLibrary PROPERTIES DEFINE_SYMBOL  "COMPILING_DLL" )
> construct is used. What is the difference?

The difference is that if you have existing code that already defined a symbol for their import/export macros then you use the "SET_TARGET_PROPERTIES" call. Otherwise let CMake define the symbol for you.

> 
> Also, my dll's links to other dll's and that is not in the article. So I needed to use target_link_libraries(...) for those.

I have a project that creates many sub libraries as part of the build. I have a header file for each library that does all the definitions. Similar to this:

/* Cmake will define MXA_EXPORTS on Windows when it
configures to build a shared library. If you are going to use
another build system on windows or create the visual studio
projects by hand you need to define MXA_EXPORTS when
building the MXADatModel DLL on windows.
*/

#if defined (MXA_BUILT_AS_DYNAMIC_LIB)

  #if defined (MXA_EXPORTS)  /* Compiling the MXA DLL/Dylib */
    #if defined (_MSC_VER)  /* MSVC Compiler Case */
      #define  MXA_EXPORT __declspec(dllexport)
    #elif (__GNUC__ >= 4)  /* GCC 4.x has support for visibility options */
      #define MXA_EXPORT __attribute__ ((visibility("default")))
    #endif
  #else  /* Importing the DLL into another project */
    #if defined (_MSC_VER)  /* MSVC Compiler Case */
      #define  MXA_EXPORT __declspec(dllimport)
    #elif (__GNUC__ >= 4)  /* GCC 4.x has support for visibility options */
      #define MXA_EXPORT __attribute__ ((visibility("default")))
    #endif
  #endif
#endif

/* If MXA_EXPORT was never defined, define it here */
#ifndef MXA_EXPORT
  #define MXA_EXPORT
#endif

A couple of notes from above. I have a header file that gets configured where the MXA_BUILT_AS_DYNAMIC_LIB is defined or not based on the value of "BUILD_SHARED_LIBS" from CMake. CMake will define MXA_EXPORTS when MXA is built as a shared library. So repeating this for each library in the project allows my project to defined everything leaving nothing to be defined by a user of this package.


> 
> I also had a more complex #define structure:
> #if defined(EXPORT_COMMON_DLL)
>    #define MTK_COMMON __declspec(dllexport)
> #elif defined(IMPORT_COMMON_DLL)
>    #define MTK_COMMON __declspec(dllimport)
> #elif defined(EXPORT_COMMON_PKG)
>    #define MTK_COMMON __declspec(package)
> #elif defined(IMPORT_COMMON_PKG)
>    #define MTK_COMMON __declspec(package)
> #else
>    #define MTK_COMMON
> #endif
> forcing the user to #define everything needed. In the example that is not the case since the dllimport is defined "automatically" if not building a dll.
> 
> I ended up changing my #define structure to
> #if defined(EXPORT_COMMON_DLL)
>    #define MTK_COMMON __declspec(dllexport)
> #elif defined(EXPORT_COMMON_PKG)
>    #define MTK_COMMON __declspec(package)
> #elif defined(IMPORT_COMMON_PKG)
>    #define MTK_COMMON __declspec(package)
> #else
>    #define MTK_COMMON __declspec(dllimport)
> #endif
> 
> which is more user friendly.
> 
> Thanks for feedback,
> Regards,
> Totte
> 
>> 
>> If you have questions after that please post. That article should clear everything up.
>> 
>> Thanks
>> ___________________________________________________________
>> Mike Jackson                    Principal Software Engineer
>> BlueQuartz Software                            Dayton, Ohio
>> mike.jackson at bluequartz.net              www.bluequartz.net
>> 
>> On Dec 6, 2011, at 3:47 AM, Totte Karlsson wrote:
>> 
>>> Hi,
>>> I have a project where several DLL's are to be built, say A, B and C.
>>> B needs to import functions/classes from A, and C need to import functions from both A and B.
>>> In each library, a flag is defined for exporting or importing, i.e. __declspec(dllexport) or __declspec(import)
>>> 
>>> The build order is first A, then B and then C.
>>> I have defined build flags in CMakeList.txt files as, in A for example
>>>    SET_TARGET_PROPERTIES (${target} PROPERTIES DEFINE_SYMBOL  "EXPORT_A_DLL")
>>> 
>>> in B
>>>    SET_TARGET_PROPERTIES (${target} PROPERTIES DEFINE_SYMBOL  "EXPORT_B_DLL")
>>>    SET_TARGET_PROPERTIES (${target} PROPERTIES DEFINE_SYMBOL  "IMPORT_A_DLL")
>>> 
>>> and in C
>>>    SET_TARGET_PROPERTIES (${target} PROPERTIES DEFINE_SYMBOL  "EXPORT_C_DLL")
>>>    SET_TARGET_PROPERTIES (${target} PROPERTIES DEFINE_SYMBOL  "IMPORT_A_DLL")
>>>    SET_TARGET_PROPERTIES (${target} PROPERTIES DEFINE_SYMBOL  "IMPORT_B_DLL")
>>> 
>>> The only dll that seem to be built OK is A. In B and C, nothing seem to be exported.
>>> Any tips on how to deal with this?
>>> I am using CodeGear platform. Building static libs works fine.
>>> 
>>> -totte
>>> 
>>> --
>>> .........................
>>> Totte Karlsson, Ph.D.
>>> Dune Scientific, LLC
>>> 425-296 1980 (office)
>>> 425-780 9648 (cell)
>>> www.dunescientific.com
>>> .........................
>>> 
>>> 
>>> --
>>> 
>>> Powered by www.kitware.com
>>> 
>>> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>>> 
>>> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>>> 
>>> Follow this link to subscribe/unsubscribe:
>>> http://www.cmake.org/mailman/listinfo/cmake
>> 
> --
> 
> Powered by www.kitware.com
> 
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
> 
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
> 
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake



More information about the CMake mailing list