Closed gschmottlach closed 8 years ago
I've never tried cross-compiling. The library should compile under Windows with Mcrosoft compilers (VC 2013 or later), Intel compilers (version 11 or later) and clang. However, clang is a bit experimental at this point.
Regarding the referenced symbols, just by including the header it should ideally not pull in those symbols. I'll look into this.
Regarding crash_dump_file_buffer and crash_dump_file symbols, please try the develop branch and see if the change I pushed solved this problem at least.
I updated my crash.c with the one from the develop branch. It almost works but I had to make the following modifications:
Before:
void
crash_debug_break(void) {
#if FOUNDATION_PLATFORM_WINDOWS
DebugBreak();
#elif FOUNDATION_COMPILER_GCC || FOUNDATION_COMPILER_CLANG
__builtin_trap();
#else
(*(volatile int*)3 = 0);
#endif
}
After:
void
crash_debug_break(void) {
#if FOUNDATION_PLATFORM_WINDOWS
DebugBreak();
#elif FOUNDATION_COMPILER_GCC || FOUNDATION_COMPILER_CLANG
__builtin_trap();
#else
(*(volatile int*)3 = 0);
#endif
while(1);
}
I had to add the while (1)
so the compiler woudl stop complaining that the "noreturn" function was in fact returning. Probably a problem because DebugBreak()
may not be marked as noreturn.
I also had to fix crash.c:243 as follows:
Before:
_crash_exception_closure.name = name;
After:
_crash_exception_closure.name.str = name;
_crash_exception_closure.name.length = length;
You were trying to assign a const char* to a string_const_t structure and they're obviously not compatible.
Let me know if you can figure out what's going on with the duplicate symbols in every object file.
Thanks . . .
Pushed fixes to crash.c (develop branch).
Regarding the symbols, it's something MinGW adds when _MSC_VER is defined (which platform.h declares to make sure the clang native Windows build works). You can see it by changing the test.c file to
#ifndef _MSC_VER
# define _MSC_VER 1300
#endif
#include <string.h>
#include <stdio.h>
#include <math.h>
void test_it(char* buf)
{
strcpy(buf, "hello");
sprintf(buf, "%f", fabs(5.0));
return;
}
I commented out the two instance where _MSC_VER is defined as shown:
# ifndef __GNUC__
# ifndef _MSC_VER
# define _MSC_VER 1300
# endif
# endif
It builds the static library fine but fails linking a DLL because of the scheme that main.c uses to callback into the application (e..g main_initialize()
, main_run()
, and main_finalize()
).
In Linux, I can build a shared-library version of foundation_lib fine because the run-time loader/linker will resolve the missing main__xxxx
symbols in the application that loaded it. Unfortunately, the Windows loader/linker is not as smart and it is difficult for a DLL to implicitly call directly into the application. One approach is described here.
My question, for you, is whether you anticipate supporting a shared library versions of foundation_lib? I'm wondering if you've ever considered changing the mechanism that the application uses to define functions that main.c should call. Perhaps it might be better if the application explicitly called an "initialize" function and passed in a function table (e.g. vtable) containing pointers to its implementation of main_initialize()
, main_run()
, and main_finalize()
. This way foundation_lib never directly calls back into the application with the assumption these correctly named functions exist (e.g. what happens if my application uses these same names for something else?). The current scheme forces the application to reserve these names for foundation_lib when it's not entirely necessary (given a vtable approach).
Just interested on you thoughts here for shared library support. . .
Building as a shared library has not been a goal, but if there is interest in it, why not? :)
The problem is that the library aims to abstract away all the different entry points for different platforms and application types. I guess the most logical thing in a shared library would be to simply not wrap any entry points. I'll look into it.
Did some updates on develop branch, check it out and define BUILD_DYNAMICLINK=1 when building as a shared library. It will define the dll export and also disable the entry point wrapper code (and the need for the main* symbols).
Thanks . . . I've been side-tracked by some other issues at the moment but I'll give it a try when I get the chance and let you know the results.
I merged your development branch and after some work, managed to create both a static archive and shared library under MSYS2 using your updates and my standard GNU makefile. Unfortunately, I had to make a few changes when building the Windows 32-bit version of the library.
1) In hash.c I had to force it to use the definition for _rotl64(), e.g.
#elif FOUNDATION_COMPILER_GCC || FOUNDATION_COMPILER_CLANG
//#ifndef _rotl64
#undef _rotl64
# define _rotl64(a, bits) (((a) << (uint64_t)(bits)) | ((a) >> (64ULL - (uint64_t)(bits))))
//#endif
#endif
If I don't do this I get the following error (for 32-bit only - the 64-bit Windows variant builds fine):
/home/swdev/project/foundation/hash.c:120:4: error: implicit declaration of function '__rolq' [-Werror=implicit-function-declaration]
bmix64(h1, h2, k1, k2, c1, c2);
^
cc1: all warnings being treated as errors
Makefile:271: recipe for target '/home/swdev/project/output/win32/deploy/foundation/objs/hash.o' failed
2) In platform.h(~722) I have to define STDCALL to use __stdcall
for the GNUC compiler, e.g.
# if FOUNDATION_PLATFORM_WINDOWS
# define STDCALL __stdcall
# ifndef __USE_MINGW_ANSI_STDIO
# define __USE_MINGW_ANSI_STDIO 1
# endif
# ifndef _CRT_SECURE_NO_WARNINGS
# define _CRT_SECURE_NO_WARNINGS 1
# endif
# ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
# define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 0
# endif
# endif
Again, this seems to be 32-bit Windows specific but it's probably safe practice anyway to define it.
I haven't tried to build/link anything to these libraries yet but I thought you might be interested in the feedback. Thanks for taking on this challenge (shared library support) and making it a reality. Hopefully actually using the library will be the easy part.
Pushed some additional changes to the develop branch based on your suggestions
Furthe windows gcc & clang compatibility fixes have been made on the develop branch now.
New 1.5 release has been compiled and verified with both GCC (MinGW-64) and Clang on Windows
My workflow typically involves building Windows libraries from a Linux host using MSYS2 and a cross GCC tool-chain (e.g. cross compile on Linux for a Windows target). Microsoft's Visual Studio is not available.
First Question: Has anyone tried this work-flow or alternate Microsoft compiler?
I put together a GNU makefile to compile foundation_lib directly because in addition to the static archive (libfoundation.a) I also needed a shared library variant (libfoundation.so). On a Linux host (for a Linux target) this works fine - both static and shared libraries are produced using the makefile.
When building the Windows variant of foundation_lib I've encountered the following problem. It appears (somehow) that any file I build within foundation_lib has extra symbols defined (T) in the object file even though they're never referenced in that file. This seems to occur whenever #include <foundation/platform.h> is included in the source file. Here's a simple example function:
File: test.c
Running
nm
on the resulting test.o I see the following:If I add one line to the file to include <foundation/platform.h> . . .
and recompile and execute
nm
again to see the symbols I see . . .Where did all these (unreferenced) functions like frexpf() or sinhf() come from??? When I build the entire Foundation library for Windows and try to link a shared library (DLL) the linker complains about multiple definitions since each *.o file contains these duplicate symbols. The command line I'm using to compile this example is:
I am also attaching a file that contains the settings of all the macro definitions defined in the environment as well as in foundation/platform.h. This environment is derived by executing:
I've also run into some issues with MinGW where functions like
_ftime_s()
are not defined (had to fall back to using_ftime64()
) andlocaltime_s()
andgmtime_s()
are not available either. Finally, there is also an issue with crash.c and specifically_crash_dump_file_buffer
and_crash_dump_file
. Apparently these aren't defined anywhere in the library either. Where are these defined in Windows?Any help and/or suggestions would be very much appreciated. I'd love to be able to use this library but the Windows support under MinGW seems to be an issue at this time.
Thanks for your time and patience . . .
env.txt