C++ cross-platform dynamic libraries for Linux and Windows
Asked Answered
Q

3

29

I am wanting to write some cross-platform library code.

I am creating a library both static and dynamic with most of the development done in Linux, I have got the static and shared library generated in Linux but now wanted to generate a Windows version of a static and dynamic library in the form of .lib and .dll using the same source code.

Is this possible? I'm a bit worried because I noticed generating Windows .dll files required using _dllspec or something similiar in your source code.

I am seeking the best and quickest solution to getting my code compiled on Windows. I don't need to do the compiling under Linux; I am happy to do it directly under Windows. Also I am using two external libraries which are Boost and Xerces XML which I have installed on both my Windows and Linux system so hopefully they shouldn't be a problem.

What I really want is to have a single source code copy that can be compiled under both Linux and Windows to generate libraries specific to each platform. I don't really care if I have to edit my code in favour of Windows or Linux as long as I can have a single source code copy.

Quacksalver answered 5/8, 2009 at 19:11 Comment(4)
Cross-compiling usually refers to building software on one platform that is to run on another. Since you say you want source code that can be compiled on both Linux and Windows, then your question is really more about writing a portable, cross-platform source code base than it is about cross-compiling.Rah
GIYF Actually, in this case, libtool is your friend...Jinni
While you wait for answers, check out CMake: cmake.orgNorthwestwards
well i'm happy with either cross-compiling or portable code that will do the same. Of course cross-compiling would be ideal as it saves me time but like I said i'm in no position to pick, which ever is best or easiest i'll take. Also what about using code::blocks IDE i hear they have shared library template and its' available in linux and windows, anyone know if this does what i want?Quacksalver
R
21

In general, there are two issues you need to be concerned with:

  1. The requirement that, on Windows, your DLL explicitly exports symbols that should be visible to the outside world (via __declspec(dllexport), and
  2. Being able to maintain the build system (ideally, not having to maintain a separate makefile and Microsoft Visual C++ Project/Solution)

For the first, you will need to learn about __declspec(dllexport). On Windows only projects, typically this is implemented in the way I describe in my answer to this question. You can extend this a step further by making sure that your export symbol (such as MY_PROJECT_API) is defined but expands to nothing when building for Linux. This way, you can add the export symbols to your code as needed for Windows without affecting the linux build.

For the second, you can investigate some kind of cross-platform build system.

If you're comfortable with the GNU toolset, you may want to investigate libtool (perhaps in conjunction with automake and autoconf). The tools are natively supported on Linux and supported on Windows through either Cygwin or MinGW/MSYS. MinGW also gives you the option of cross-compiling, that is, building your native Windows binaries while running Linux. Two resources I've found helpful in navigating the Autotools (including libtool) are the "Autobook" (specifically the section on DLLs and Libtool) and Alexandre Duret-Lutz's PowerPoint slides.

As others have mentioned, CMake is also an option, but I can't speak for it myself.

Rah answered 5/8, 2009 at 19:21 Comment(2)
thanks, i did do some google searching and guess I searched the wrong things, libtool does sound interesting and perhaps cmake as someone mentioned above. I am sort of new to linux so this tools don't quickly ring a bell :pQuacksalver
Se usi Boost puoi usare boost/config.hh che definisce le macro per esportare i simboli in maniera appropriata per tutti i compilatori e piattaformeInfrangible
V
13

You can pretty easily do it with #ifdef's. On Windows _WIN32 should be defined by the compiler (even for 64 bit), so code like

#ifdef _WIN32
#  define EXPORTIT __declspec( dllexport )
#else
#  define EXPORTIT
#endif

EXPORTIT int somefunction();

should work OK for you.

Vogt answered 5/8, 2009 at 19:30 Comment(3)
hmm yeah I thought about that, i'll see how that would go, might use this as my last resort if I have no luck with the above toolsQuacksalver
@iQ: You're going to still have to do this, even with the above tools. They don't handle the exporting for you, they just hide some of the differences between the build process on the different platforms.Rah
yeah I guess your right, i'm going to have to use macros. I'm currently trying to look at codeblocks which I think it can automatically define a .def file for you although I don't know how good or bad that is. I'm going to have to experiment a bit.Quacksalver
B
8

Maybe it's better if you Add extern "C" !!!,

/* file CMakeLists.txt */

 SET (LIB_TYPE SHARED)
 ADD_LIBRARY(MyLibrary ${LIB_TYPE} MyLibrary.h)

/* file MyLibrary.h */

#if defined(_WIN32) || defined(__WIN32__)
#  if defined(MyLibrary_EXPORTS) // add by CMake 
#    define  MYLIB_EXPORT extern "C" __declspec(dllexport)
#  else
#    define  MYLIB_EXPORT extern "C" __declspec(dllimport)
#  endif // MyLibrary_EXPORTS
#elif defined(linux) || defined(__linux)
# define MYLIB_EXPORT
#endif

MYLIB_EXPORT inline int Function(int a) {
    return a;
}
Braze answered 20/1, 2010 at 15:35 Comment(1)
@tstenner you mean to say you don't just absolutely LOVE when people make up their own formatting style on-the-fly as they're typing their code? :)Gandhi

© 2022 - 2024 — McMap. All rights reserved.