Is it possible to bundle a Mono executable using mkbundle that uses the sgen GC?
I assume that because the produced bundle requires the libmono-2.0.so.1 instead of the libmonosgen-2.0.so that it is using the standard boehm GC. I have tried using $MONO_OPTIONS=--gc=sgen but the resulting bundle still requires the non-sgen lib.
Am I misunderstanding the use of the libmono and libmonsgen libs?
Thank you for any assistance or guidance
This is a bit tricky, because Mono actually has two separate executables and two separate libraries, one for each garbage collector. For example, if you run mono --gc=sgen ... then mono will actually do an execvp() of mono-sgen ... to switch to a different executable.
Similarly, mkbundle will use pkg-config to select the library and link one or the other (i.e. whichever is the system default). To get the other library, there are two options:
One is to rebuild Mono with sgen being the default. Obviously, that may not be a viable solution.
The alternative is to use pkg-config to override the selection. You'd create a copy of mono-2.pc, replace -lmono-2.0 with -lmonosgen-2.0, update prefix and exec_prefix and use the PKG_CONFIG_PATH environment variable to pick that version.
Note that I've never actually tried the latter, but there is no reason why it shouldn't work, since pkg-config is where mkbundle gets the library path from.
Thanks for this question as it helps me to determine why one of my applications is running too slowly after bundling with the mkbundle. It was because of the Boehm GC engine being used.
To include SGen you just need to invoke mkbundle with --keeptemp flag and then rewrite compiler command (which is printed by mkbundle) to include monosgen-2 instead of mono-2.
Example: (for Mac, but could be easily rewritten for Linux)
export PATH=/Library/Frameworks/Mono.framework/Commands/:$PATH
export AS="as -arch i386"
export CC="cc -arch i386 -framework CoreFoundation -lobjc -liconv"
mkbundle TestApp.exe --deps --static -o TestAppBundleName --keeptemp
cc -arch i386 -framework CoreFoundation -lobjc -liconv -o TestAppBundleName -Wall `pkg-config --cflags monosgen-2` temp.c `pkg-config --libs-only-L monosgen-2` `pkg-config --variable=libdir monosgen-2`/libmonosgen-2.0.a `pkg-config --libs-only-l monosgen-2 | sed -e "s/\-lmonosgen-2.0 //"` temp.o
Related
I'm building a dll to use PocoNetSSL to get some data via an HTTPS endpoint. I need to call that dll via C# in Unity which runs an old version of Mono.
I am using mingw-w64 shell to build my dll. There is a package of the Poco libraries available via the package manager pacman and I am using that.
$ pacman -Qs 'poco'
local/mingw-w64-x86_64-poco 1.6.0-2
POrtable COmponents C++ Libraries (mingw-w64)
I can build an executable and it builds fine & runs fine hitting the https endpoint. I have openssl installed somewhere or it may have come with mingw.
My problem is that I cannot open the dll with LoadLibrary. I get a null pointer and I'm guessing it's a dependency problem. Here's my build commands and a snapshot of dependency walker. Is there anything I am missing here. I think I should be able to do this but maybe not?
sburke#sburke-pc MINGW64 ~/sandbox/hitaws
$ scons
scons: Reading SConscript files ...
msys
scons: done reading SConscript files.
scons: Building targets ...
g++ -o gdoaws.os -c -Wall -DPOCO_WIN32_UTF8 -I/mingw64/include gdoaws.cpp
g++ -o gdoaws.dll -Wl,-no-undefined -shared -Wl,--out-implib=libgdoaws.dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive gdoaws.os -Wl,--no-whole-archive -L/mingw64/lib -lPocoNetSSL.dll -lPocoNet.dll -lPocoUtil.dll -lPocoFoundation.dll
scons: done building targets.
Assuming your loading a dynamic library code is correct your app is very likely trying to load different version of openssl dlls than Poco was built against.
In msys2 you can check a dynamic library dependencies by:
ldd /mingw64/bin/libPocoNetSSL.dll
which depends on:
LIBEAY32.dll => /mingw64/bin/LIBEAY32.dll
SSLEAY32.dll => /mingw64/bin/SSLEAY32.dll
Is this what you see in dependency walker?
The best workround for this problem is to copy above dlls to the folder where your executable is and always distribute them with your software.
I've been trying to create a CMake-based build-system for a project that is supposed to use SDL2_image library. I do not want to force user to install any libraries to the system to be able to build the project, so I took advantage of the CMake's ability to download and build dependencies (freetype, SDL2 and SDL2_image) from source code as External Projects.
Everything is fine with freetype and SDL2 (which both include CMakeLists.txt files out of the box), but I've ran out of ideas how to make it work for SDL2_image. CMake's external projects support custom configuration and building settings which I used in different variants with no success.
The CMake file itself can be found here, but the problematic part is this:
# SDL_image library
ExternalProject_Add(sdl2_image_project
URL https://www.libsdl.org/projects/SDL_image/release/SDL2_image-2.0.0.tar.gz
DEPENDS sdl2_project
PREFIX ${LIBS_DIR}/SDL2_image
CONFIGURE_COMMAND LDFLAGS=-L${SDL2_BIN} CFLAGS=-I${SDL2_SRC}/include SDL2_CONFIG=${SDL2_BIN}/sdl2-config <SOURCE_DIR>/configure --prefix=<INSTALL_DIR> --enable-shared=no
BUILD_COMMAND make
INSTALL_COMMAND ""
)
An error occurs while building sdl2_image_project. Some trivial research discovered that the error is generated by the undefined references to parts of libdl. Here is a tiny part of the hole error:
libtool: link: gcc -I/home/snikitin/_src/img_glypher/libs/SDL2/src/sdl2_project/include -I/usr/local/include/SDL2 -D_REENTRANT -o showimage showimage.o -Wl,-rpath -Wl,/usr/local/lib -pthread -L/home/snikitin/_src/img_glypher/libs/SDL2/src/sdl2_project-build ./.libs/libSDL2_image.a -L/usr/local/lib -lSDL2 -pthread
/home/snikitin/_src/img_glypher/libs/SDL2/src/sdl2_project-build/libSDL2.a(SDL_dynapi.c.o): In function `get_sdlapi_entry':
/home/snikitin/_src/img_glypher/libs/SDL2/src/sdl2_project/src/dynapi/SDL_dynapi.c:227: undefined reference to `dlopen'
I think the problem takes place due to the fact that linker tries to create a shared version of SDL2_image library while linking it to a static libSDL2.a. The thing is - if this is right - SDL2 building step creates both static and shared versions of itself so one would assume that linker would use libSDL2-2.0.so instead (I do not actually need a shared library - just the static one, but I do not know how to prevent the build system from trying to create it apart from passing --enable-shared=no to SDL2_image configure script, which does not help in this case).
After a lot of googling I've discovered that the possible source of the problem is that sdl2-config (which is called to get some flags for compiler during SDL_image building) may be called with wrong arguments and produces wrong cflags which confuse everything else. But I'm not sure that is the case and also I do not know how to influence sdl2_config call from CMake (configure --help does not seem to unveil any useful options for this situation).
I am running Ubuntu 14.04 x64 if it matters in any way. Would appreciate any advice!
Looks like you need to link some libraries like m and dl. It can be fixed by providing
custom sdl2-config file. Copy sdl2-config from extracted archive and substitute --libs result:
--libs)
echo -L${exec_prefix}/lib -Wl,-rpath,${libdir} -pthread -lSDL2 -lm -ldl
;;
Note that order is important (that's why just modifying LIBS not works for me).
Now this file can be used in your ExternalProject_Add command instead of SDL2_CONFIG=${SDL2_BIN}/sdl2-config:
...
... CFLAGS=-I${SDL2_SRC}/include SDL2_CONFIG=${CMAKE_CURRENT_LIST_DIR}/sdl2-config <SOURCE_DIR>/configure
...
I was checking out the portability of Objective-C via gnustep and ran into some problems...
I mean everything works on my 2 machines but the major problem is if I run my application on a platform where gnustep is not pre-installed... So I want to build it with static libraries. But I ran into several problems:
1.) I cant find the static libaries under /usr/local/lib so the question came up do they even exist within gnustep?
2.) In case there are static libraries available how to integrate it correctly into my gcc command?
sudo gcc -o main main.m GameRef.m SDLApplication.m SDLEvent.m SDLImage.m SDLMap.m SDLSprite.m Settings.m Utility.m -I -static `gnustep-config --variable=GNUSTEP_SYSTEM_HEADERS` -L `gnustep-config --variable=GNUSTEP_SYSTEM_LIBRARIES` -lgnustep-base -lSDL -fconstant-string-class=NSConstantString -std=c99 2>logFile
I'm currently using Ubuntu 12.04LTS and installed the SDL and Gnustep on one machine so the application runs fine... But not on the second because the shared libraries are missing so I need to add them as static but how?
The libraries in /usr/local/lib and other system 'lib' directories will be dynamic. They can't be used as static (AFAIK), and finding them wouldn't really help.
I'm no expert with GNUstep, but it sounds like you are missing the Objective-C runtime. You will need to download the source code of the GNUstep libraries and frameworks, and then compile them into static libraries yourself.
Really, wrapping all of those frameworks into your application will just add unnecessary work for both you and your end users. Dynamic libraries exist for a purpose. There's no reason to have multiple copies of the same code on the filesystem. Just require GNUstep as a dependency. Although its a slight pain for the users, they only need to do it once, and with most distros, installation is only a command or two away.
What options set, to statically linked the library curl ?
Library should be integrated to executable file.
tried different: added options g++ -DCURL_STATICLIB -lcurl ... added #define CURL_STATICLIB to the code ..., in the IDE NetBeans added libcurl.a, libcurldll.a ... etc.,
Compile is successful and all works great. But still require external libcurl.dll! (Size of executable file also increases!)
What's wrong ? might have something add to the IDE (also used NetBeans, Eclipse)
Please show a correct example as you would make
Executable file should be without calling an external dll library
it my first question :)
Fix.
Example compile for library curl with OpenSSL + zlib + libidn + libssh2 + librtmp:
g++ -static main.cpp -lcurl -lidn -lwldap32 -lssh2 -lz -lrtmp -lssl -lssl32 -lcrypto -lgdi32 -lws2_32 -lwinmm -o test.exe
note: here shouldn't be specified -lcurldll. This will lead to that: compile is successful, but still require external libcurl.dll
you need to specify -static in the linker options
When compiling Objective-C from the command line (gcc), what are some good flags to use? Many of the standard C flags (-Wall, -ansi, etc) don't play well with Objective-C.
I currently just use -lobjc and -frameworkwith various frameworks.
Many of the standard C flags (-Wall, -ansi, etc) don't play well with Objective-C
-Wall works perfectly fine with Objective-C.
The thing to do is build an Objective-C file with Xcode and have a look at the build transcript. I've just done that and here are some highlights:
-x objective-c I guess that means "compile as Objective-C", probably important
-arch x86_64 build for a particular CPU architecture
-std=gnu99 build for C99 + GNU extensions (actually surprised me, I thought Xcode used -std=c99).
-isysroot .... specifies the location of the SDK.
-mmacosx-version-min=10.6 I am compiling for 10.6 and up
-fobjc-gc-only this file was intended to be used with garbage collection and won't work without it, so I compile for GC only.
-Wall the obvious.
If you are compiling from the command line, it's probably a good idea to set the option to treat warnings as errors. I don't from within Xcode because the build results window remembers the uncleared warnings from previous builds.