Hi all,
Wow, I recently had the occasion to
experiment with building the SG shared
library, DLL, in Windows... a NO GO ;=((
Well, with a fresh SG clone, yesterday I
think, first I needed to patch the
simgear/CMakeLists.txt to get cmake to
even start building - patch given below...
The two changes are to add the winsock2 library,
and since in windows there are two components
built, you MUST provide a 'target' for each.
In general the .lib goes in the 'lib' directory as
usual, but the DLL is a 'runtime' component, thus
must go in the 'bin' directory with the executable.
But that was just the tip of the iceberg ;=))
While that succeeded in getting the Windows DLL
SimGearCore.dll built, NO archive library was
generated. And without such a 'library' you can
not 'link' to the DLL. It 'exports' nothing, and
is quite useless...
Now, as the windows people know, there are just
two ways to 'export' functions, variables, classes
from a windows DLL build -
1. Use __declspec()
2. Use a DEF file
1. Use __declspec()
This declaration has to be added to each and every
function, variables, class you want to export.
This is usually done with a macro of the form -
#ifdef WIN32
#ifdef SG_LIBRARY /* building the library */
#define SG_EXPORT __declspec(dllexport)
#else /* link with application */
#define SG_EXPORT __declspec(dllimport)
#endif
#else /* not in windows */
#define SG_EXPORT extern
#endif
This could probably go in say compiler.h...
Then every function exported needs this
declaration, like -
SG_EXPORT int foo();
SG_EXPORT class X {} varX;
SG_EXPORT ULONG ulDataInDll;
Like in say xml/easyxml.hxx, in part...
class SG_EXPORT XMLAttributes
{
public:
// ...
};
...
SG_EXPORT void readXML (istream input, ...);
SG_EXPORT void readXML (const string path,...);
And so on, and On, and ON ;=)) For each SG
header that exports something as part of the
SG API...
2. Use a DEF file
=
In this Module-Definition file EVERY function,
variable to be exported has to be declared!
EXPORTS
foo @1
ulDataInDll DATA
readXML
# and onward for all SG API items
Not sure how classes are declared in here...
and the assignment of an ordinal value, like @1
to @N, is optional...
And then that simgear.def file added to the
cmake list file for the windows build. cmake
handles it without problems...
And that DEF file has to be maintained.
Function names removed or added as the API
changes...
And then another matter noted...
3. SG SO Version
At present it seems only one DLL is produced,
SimGearCore.dll
without a 'version' indication... like say
SimGearCore29.dll
SimGearCore29.lib
In a fast changing API, like SG is, then it
is essential that the DLL be version-ed... like
I assume it is in unix...
And like say the OSG Windows DLLs are, like ...
osg92-osg.dll, but just noted they do not
add this to the libraries - it is always just
osg.lib.
But that is ok since which ever osg.lib you
link with, will automatically 'force' a version
DLL...
So likewise maybe one name, SimGearCore.lib
would be ok...
But this version is important, since
if you built say the 2.8 DLL they can NOT
be used for 2.9 due to several API changes...
And in this case that is ignoring that
2.8 would be 20+ DLLs, versus 2.9 of two...
But here I am talking about API changes like -
sgGetMagVar(lon, lat, elev, ...
to
sgGetMagVar(SGGeod, ...
which may have happened even before 2.8...
did not check the date of this change...
And this SO version would needed to be
kicked for EACH API change... more maintenance,
which I hope IS being done in unix...
Conclusion
==
As you can see, this would be *L*O*T*S* of
work and FOREVER continued maintenance...
although using 1, once developers got into
the habit of using SG_EXPORT, then this could
be minimized...
But maybe we would be better off removing the
SIMGEAR_SHARED option if WIN32 ;=))
That is do NOT offer an option that can NOT
be used!
And of course, I really wonder WHY we added
a 'shared' version of SG at all... but that
is another topic...
I assume someone had a 'good' only-for-UNIX
reason ;=))
In general, in Windows, using a DLL is a
real PITA!
HTH.
Regards,
Geoff.
patch
diff --git a/simgear/CMakeLists.txt b/simgear/CMakeLists.txt
index d505998..9bb8dce 100644
--- a/simgear/CMakeLists.txt
+++ b/simgear/CMakeLists.txt
@@ -64,7 +64,10 @@ if(SIMGEAR_SHARED)
target_link_libraries(SimGearCore ${ZLIB_LIBRARY} ${RT_LIBRARY}
${EXPAT_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT})
-
+if (WIN32)
+target_link_libraries(SimGearCore ${WINSOCK_LIBRARY})
+endif (WIN32)
+
if(LIBSVN_FOUND)
target_link_libraries(SimGearCore ${LIBSVN_LIBRARIES})
endif(LIBSVN_FOUND)
@@ -86,10 +89,19 @@ if(SIMGEAR_SHARED)
${OPENGL_LIBRARY}
${JPEG_LIBRARY})
-install(TARGETS SimGearScene LIBRARY DESTINATION
${CMAKE_INSTALL_LIBDIR})