Link C++ library statically lazarus / 34-Windows ---------------------------------------------------------------------- alex1 · 2014-12-11 11:30 Hi, I have a following requirements for the windows app and want to use Lazarus for it: 1) must compile to single exe file, this exe file must run on Windows XP without redistributable packages 2) must use C++ library (with a C wrapper) compiled with MinGW The first point works out of the box, but I gave up on second one after some time. I can link statically simple C lib (with {$linklib libmsvcrt.a} from mingw) into lazarus app. And I can link a C++ lib that doesn't use C++ stdlib and declares public functions with extern "C". But if I cannot link C++ lib which uses stdlib internally (string, vector etc). If I link with {$linklib libstdc++.a} I got a bunch of "Duplicated symbols error". Link with {$linklib libstdc++.dll.a} succeed, but the application won't run asking for libstdc++-6.dll (no such lib exists in mingw). I read "CInFreePascal.pdf" but unfortunately it is linux-specific. Any help would be appreciated. ---------------------------------------------------------------------- Leledumbo · 2014-12-12 06:02 Quote from: alex1 on December 11, 2014, 12:30:36 pmIf I link with {$linklib libstdc++.a} I got a bunch of "Duplicated symbols error". Try compiling with mingw g++ statically and try to get the linker script (I forgot the option, please search yourself). Open it and find the list of required libraries to link. Quote from: alex1 on December 11, 2014, 12:30:36 pmLink with {$linklib libstdc++.dll.a} succeed, but the application won't run asking for libstdc++-6.dll (no such lib exists in mingw). libstdc++-6.dll does exist in mingw, if you install gcc-c++--mingw32-dll package, it's should be there because it's required by g++ compiled programs, which are linked dynamically by default. ---------------------------------------------------------------------- alex1 · 2014-12-13 02:25 Thanks for the response. Experimented for some time with different variants and was unable to make it work. libstdc++.a cannot be linked statically (a lot of "Multiple defined symbol" errors). And it doesn't matter much, as If I try to use exceptions inside C++ sample lib (in internal functions, without crossing the border) I cannot link this lib statically even with libstdc++.dll.a. And of course you were right about libstdc++-6.dll it is shipped with mingw and it and libgcc_s_dw2-1.dll is required in runtime when I link my lib dynamically. With dynamic linking C++ exceptions work fine. Going to use a dynamic library and ship the app with minimal installer instead of standalone exe. ---------------------------------------------------------------------- Leledumbo · 2014-12-13 07:39 Quote from: alex1 on December 13, 2014, 03:25:43 amGoing to use a dynamic library and ship the app with minimal installer instead of standalone exe. Yes, that's a better way for multi language project. Static linking suffers too much problems. ---------------------------------------------------------------------- alex1 · 2014-12-13 12:41 It turned out to be easier than expected. I tried static linking (and MinGW) because I wanted single EXE. But I realized, that I can bundle C++ DLL and Lazarus EXE into "fat" EXE with NSIS. And I do not need to use MinGW for Lazarus integration - MSVC DLL works fine without any wrappers. So with Lazarus I can actually build snappy UI on top of my C++11 lib without resorting to MFC/WTL. If someone will be interested, here is the full example for a single EXE app with Lazarus, MSVC2013 Express, CMake and NSIS. I haven't used it myself yet (maybe some hidden problems), but simple examples work for me so far. lazarus_lib1.cpp (with exceptions and stdlib to check these features): Code: [Select]#include #include std::string myfun(int num) /* noexcept(false) */ {     return num > 0 ? std::to_string(num) : throw std::exception(); } extern "C" __declspec(dllexport) int libfun1(int num) /* noexcept */ {     try {         return myfun(num).length();     } catch(...) {         return -1;     } } CMakeLists.txt: Code: [Select]project ( lazarus_lib1 ) add_library ( lazarus_lib1 SHARED "lazarus_lib1.cpp" ) Unit1.pas (snippet): Code: [Select]interface uses   CTypes; function libfun1(v: CTypes.cint32): CTypes.cint32; cdecl; external 'lazarus_lib1.dll' name 'libfun1'; lazarusapp.nsi: Code: [Select]!define exe 'lazarusapp.exe' OutFile ${exe} SilentInstall silent RequestExecutionLevel user ; prevent UAC window Section     InitPluginsDir     SetOutPath '$PLUGINSDIR'     File lazarus_lib1.dll     File project1.exe     ExecWait '"$PLUGINSDIR\project1.exe"'     SetOutPath $TEMP ; allows NSIS to delete PLUGINSDIR SectionEnd