|
|
<b> CMake Version 2.8.6 Now has all of this functionality built in</b>
|
|
|
|
|
|
You need to add the following to your CMake file:
|
|
|
|
|
|
include (GenerateExportHeader)
|
|
|
|
|
|
Then after you add your library using add_library(...) you should also
|
|
|
do the following in your CMake file.
|
|
|
|
|
|
add_library(MyLibrary ${LIB_TYPE} ${srcs})
|
|
|
GENERATE_EXPORT_HEADER( MyLibrary
|
|
|
BASE_NAME MyLibrary
|
|
|
EXPORT_MACRO_NAME MyLibrary_EXPORT
|
|
|
EXPORT_FILE_NAME MyLibrary_Export.h
|
|
|
STATIC_DEFINE MyLibrary_BUILT_AS_STATIC
|
|
|
)
|
|
|
|
|
|
See
|
|
|
<http://cmake.org/cmake/help/cmake-2-8-docs.html#module:GenerateExportHeader>
|
|
|
for the complete help contents.
|
|
|
|
|
|
<b>PRE CMake 2.8.5 and earlier </b>
|
|
|
|
|
|
**How to build a Windows DLL (for the NON-Windows Developer). A Short
|
|
|
introduction.**
|
|
|
|
|
|
Those folks coming from an environment like Linux, OS X or even MinGW
|
|
|
may have some initial issues when trying to create a DLL on windows.
|
|
|
Usually the problems involve the library symbols NOT getting exported.
|
|
|
This article will try to walk you through what needs to be done in order
|
|
|
for you to bring your code to an MS compiler successfully.
|
|
|
|
|
|
<b> This short explanation was taken from a recent post to the cmake
|
|
|
mailing list and generally sums up the problem.</b>
|
|
|
<code> <i>Visual Studio generates 2 files: one import library (.lib) and
|
|
|
one - dynamic library (.dll). GCC (and mingw family) exports all symbols
|
|
|
by default, VS doesn't export anything by default. And if your dll
|
|
|
doesn't export anything, VS simply doesn't generate the import library
|
|
|
(for example, if you generate resource-only dll). The only thing cmake
|
|
|
knows is when you using VS generator, library extension to link with --
|
|
|
is .lib. And when you use __declspec( dllexport ), cl.exe puts special
|
|
|
marks in objects indicating that this symbol should be exported or
|
|
|
imported. Also, VS can tell linker to add some library, as boost does
|
|
|
with \#pragma's. </i>
|
|
|
|
|
|
-----
|
|
|
|
|
|
So with all this information, how does all this work with CMake? There
|
|
|
are a few pieces of code that you will need to add to your project.
|
|
|
|
|
|
- Let us first consider the CMake code. In your CMakeLists.txt file
|
|
|
you will have something along the lines
|
|
|
of:
|
|
|
|
|
|
<!-- end list -->
|
|
|
|
|
|
# Allow the developer to select if Dynamic or Static libraries are built
|
|
|
OPTION (BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
|
|
|
# Set the LIB_TYPE variable to STATIC
|
|
|
SET (LIB_TYPE STATIC)
|
|
|
IF (BUILD_SHARED_LIBS)
|
|
|
# User wants to build Dynamic Libraries, so change the LIB_TYPE variable to CMake keyword 'SHARED'
|
|
|
SET (LIB_TYPE SHARED)
|
|
|
ENDIF (BUILD_SHARED_LIBS)
|
|
|
|
|
|
# Create a target for the library
|
|
|
ADD_LIBRARY(MyLibrary ${LIB_TYPE} MyLibrary.cpp)
|
|
|
|
|
|
On MSVC platforms and when building a DLL, CMake will add the following
|
|
|
preprocessor definition for you:
|
|
|
|
|
|
MyLibrary_EXPORTS
|
|
|
|
|
|
This is generated by concatenating the name of the target 'MyLibrary'
|
|
|
with '_EXPORTS'.
|
|
|
Now we have to exploit that definition in our code so we need to add
|
|
|
some c code into a header that will get included by every class or file
|
|
|
in the project. A Good name for this might be <b>DLLDefines.h</b>.
|
|
|
Notice I did NOT call it Win32Exports.h as GCC 4.x series has some of
|
|
|
these types of definitions that can be used and we should keep all this
|
|
|
in a single file (see [GCC
|
|
|
Visibility](http://gcc.gnu.org/wiki/Visibility) ). So, what is the
|
|
|
contents of "DLLDefines.h" you might ask?
|
|
|
|
|
|
// Contents of DLLDefines.h
|
|
|
#ifndef _MyLibrary_DLLDEFINES_H_
|
|
|
#define _MyLibrary_DLLDEFINES_H_
|
|
|
|
|
|
/* Cmake will define MyLibrary_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 MyLibrary_EXPORTS when
|
|
|
building a DLL on windows.
|
|
|
*/
|
|
|
// We are using the Visual Studio Compiler and building Shared libraries
|
|
|
|
|
|
#if defined (_WIN32)
|
|
|
#if defined(MyLibrary_EXPORTS)
|
|
|
#define MYLIB_EXPORT __declspec(dllexport)
|
|
|
#else
|
|
|
#define MYLIB_EXPORT __declspec(dllimport)
|
|
|
#endif /* MyLibrary_EXPORTS */
|
|
|
#else /* defined (_WIN32) */
|
|
|
#define MYLIB_EXPORT
|
|
|
#endif
|
|
|
|
|
|
#endif /* _MyLibrary_DLLDEFINES_H_ */
|
|
|
|
|
|
Ok. Now that we have that code, what do we do with it?
|
|
|
|
|
|
For every class or function that you want to be exported from your
|
|
|
library you need to declare like the following:
|
|
|
|
|
|
class MYLIB_EXPORT SomeLibrary
|
|
|
{
|
|
|
// All your normal code here.
|
|
|
};
|
|
|
|
|
|
If you have some static functions then you will need something like the
|
|
|
following:
|
|
|
|
|
|
class MyStaticFunctionClass
|
|
|
{
|
|
|
public:
|
|
|
static MYLIB_EXPORT void MyExportedFunction(int i);
|
|
|
};
|
|
|
|
|
|
After all this code is put in place then when you compile your library
|
|
|
as a dll, Visual Studio should create the proper set of libraries.
|
|
|
|
|
|
-----
|
|
|
|
|
|
<b>But wait\!</b> I have an existing project that I am bringing to cmake
|
|
|
and it already has this type of code in place but the definition that
|
|
|
the project uses is different than what CMake produces, now what do I
|
|
|
do? Say that project uses <b>COMPILING_DLL</b> as its definition, then
|
|
|
you can do the following in
|
|
|
CMake:
|
|
|
|
|
|
SET_TARGET_PROPERTIES (MyLibrary PROPERTIES DEFINE_SYMBOL "COMPILING_DLL" )
|
|
|
|
|
|
I hope this helps explain what needs to be done when porting a linux, OS
|
|
|
X or MinGW shared library to Windows.
|
|
|
|
|
|
----
|
|
|
This page was initially populated by conversion from its [original location](https://public.kitware.com/Wiki/BuildingWinDLL) in another wiki. |