Windows dependencies when statically linking - windows

I am compiling with GCC 4.8.2 (MinGW) on Windows. I am using openMP in my program. When I compile without -static flag I get this output from dumpbin /dependents myapp.exe:
Dump of file myapp.exe
File Type: EXECUTABLE IMAGE
Image has the following dependencies:
KERNEL32.dll
msvcrt.dll
USER32.dll
libgomp-1.dll
Now including libgomp-1.dll in the same folder as myapp.exe won't be enough as that depends on some more .dlls (libwinpthread-1.dll and libgcc_s_seh-1.dll) and dumpbin only goes one level deep.
Now I compile including -static in compilation flags and I get this output from dumpbin:
File Type: EXECUTABLE IMAGE
Image has the following dependencies:
KERNEL32.dll
msvcrt.dll
USER32.dll
Is it now going to work without .dlls on which libgomp-1.dll depends? Did GCC include static version of those libraries as well? Would dumpbin be able to detect those new dependencies ?
(I am probably getting a bit paranoid here but those things are very difficult to test on local machine where I have those dlls in many places on my PATH)

You can't link MSVCRT (the Windows C Library) static with MinGW, but that shouldn't be much of a problem. MSVCRT.dll, KERNEL32.dll, USER32.dll should be present on all Windows versions. You don't need to redistribute them.

Related

Question for GCC equation.com for building the using static

I like windows gcc equation.com because it like ran natively just like windows compiler. However :
I will need some dll's that not included on distributed package. if i compiled a windows equation.com gfortran program like using Openblas, it will need libgcc_s_seh-1.dll libgfortran-5.dll libquadmath-0.dll libwinpthread-1.dll.
I could find it on web. But how to make it statically linked, i saw libgcc.a libgfortran.a libquadmath.a libpthread.a so i dont have to copy the dll from other. It is possible ?
For several c source code it need include <sys/resource.h> that not included. It's compatible with resource.h from where. After just copied from others, and recompile.
I got error :
c:\gcc\x86_64-w64-mingw32\include\sys\resource.h:74:29: error: unknown type name 'id_t'; did you mean 'pid_t'?
Is there any forum for this type gcc? Is there any debugger for windows gcc that friendly like VisualStudio Community for Intel Fortran.
Regards.

Lift x64 Windows executable to LLVM bitcode and then compile back to x32 one?

So my idea is to "lift" 64-bits Windows executable to LLVM bitcode (or whatever is higher than assembly) and then compile it back to 32-bit executable.
I found that RetDec and McSema can lift PE binary to LLVM IR (and optionally C), but McSema requires IDA pro so I haven't tried it yet.
I have installed MSVC v143 and Windows SDK version 10.0.19041.0:
Clang version:
clang version 13.0.1 (https://github.com/llvm/llvm-project 75e33f71c2dae584b13a7d1186ae0a038ba98838)
Target: x86_64-pc-windows-msvc
Thread model: posix
So I compile this Hello World code in C using Clang:
#include <stdio.h>
int main()
{
printf("Hello, world!\n");
}
then clang hello.c -o hello.exe
Check hello.exe file type with WSL:
$ file hello.exe
hello.exe: PE32+ executable (console) x86-64, for MS Windows
You can download it here.
Then I use RetDec to lift it to LLVM IR:
python retdec-decompiler.py --no-memory-limit hello.exe
Output: here
After that we get:
Compile bitcode back to executable:
clang hello.exe.bc -m32 -v -Wl,/SUBSYSTEM:CONSOLE -Wl,/errorlimit:0 -fuse-ld=lld -o hello.x86.exe
Output: here
I guess functions like _WriteConsoleW are Win32 APIs, but ___decompiler_undefined_function_0 might be generated from the decompiler by some way.
Also, the decompiled code has no main function, but it had entry_point function. From hello.exe.ll:
hello.exe.c also has entry_point instead of main:
And also, hello.exe.c doesn't have ___decompiler_undefined_function_0
I also tried running the bitcode with lli:
lli --entry-function=entry_point hello.exe.bc
Output: here
Here is the link to the files.
How to make this compile? Thanks!
That's very ambitious.
I'm going to go out on a limb and say that every windows application includes thousands of system header files, most of which use types whose size differs between 32- and 64-bit systems and many of which contains #ifdef or other platform-dependent differences. You'll have a large .ll file full of windows64-specific types and code.
If the developers at Microsoft saw windows64 as a good chance to drop some hacks that were needed for w95 code, then you'll have w32-incompatible code there, too.
What you have to do is what the wine developers did — add code to cater to each problem in turn. There will be thousands of cases to handle. Some of it will be very difficult. When you see the number 128 in the .ll file, was it sizeof(this_w64_struct) in the original source, sizeof(that_other_struct) or something else entirely? Should you change the number, and if so, to what?
You should expect this project to take at least years, maybe a decade or more. Good luck.

Link a Windows .exe with other Fortran routines on Linux

I have a Fortran ".exe" file generated in Windows. I want to link it with other Fortran routines while compiling on Linux platform.
For example, I have "a.exe" file generated on Windows. I wrote "b.f90" and "c.f90" on linux machine. I want to compile "b.f90" and "c.f90" and link them to "a.exe" to generate the final ".exe" file.
Is it possible?
No, it is not possible.
(Or it would be very very complicated and the .exe would have to be specially prepared for that.)
Not only Linux and Windows executables are incompatible. You do not link an .exe with anything, not on Windows, not on Linux, nowhere (except linking with the .dll or .so dynamic libraries the executable always requires). What you normally do is that you compile your Fortran or other language sources to object files and then you can link the object files to form a library (dynamic or static) or to form an executable.
What you could theoretically do, IF the .exe file already requires some .dll libraries, or is able to load some on request, is to compile your .f90 files to make these .dll libraries (somewhere with Windows or with a Windows compiler under Linux in Wine or with a cross-compiler) and then run everything under Linux using Wine. But I would just recompile everything on Linux from scratch.

Compile using Cygwin without cygwin dependency

-mno-cygwin compiler parameter doesn't exist.
I tried to use '-static', but then compiler can't find installed -lpng
You need to cross compile it. Run x86_64-w64-mingw32-gcc, included in package mingw64-x86_64-gcc-g++, in cygwin64 to cross compile a native windows 64bit executable. It is similar if you are in cygwin or to compile a 32bit executable.
However, without cygwin compatibility layer, a program using POSIX APIs cannot be compiled. If your program needs POSIX APIs, you have to compile with cygwin dependency.
Reference Executable file generated using GCC under cygwin

Can't get GCC's -static-libgcc working with DYLIB libraries on Mac OS X

I've installed GCC 4.6.3 into a non-system path on a Mac system and it works fine. However, GCC wants to use code from libgcc for all the binaries I compile, and running otool -L shows that these compiled programs look for libgcc_s.1.dylib in GCC's install path. I can override this by passing -static-libgcc, which just compiles the stuff needed into the binary and that's fine. The problem is this only seems to work with executables, not shared libraries. If I use GCC to compile some third-party lib I want to use in one of my programs as a .dylib, these libraries still look for libgcc_s.1.dylib in the local GCC install path even if I specify -static-libgcc! Needless to say, this is a problem as there's no guarantee that those libraries will find libgcc when run on some other system.
I tried this with ffmpeg. If I look at config.log, the -static-libgcc is most certainly being used. GCC is just not linking libgcc statically with the resulting dylibs. I even tried the -nostdlib, -nostartfiles and -nodefaultlibs options but they were ignored. Again, I checked config.log and they're definitely there!
I believe this is to do with throwing exceptions across the shared library boundary. This page says:
There are several situations in which an application should use the
shared libgcc instead of the static version. The most common of these
is when the application wishes to throw and catch exceptions across
different shared libraries. In that case, each of the libraries as
well as the application itself should use the shared libgcc.
Therefore, the G++ and GCJ drivers automatically add -shared-libgcc
whenever you build a shared library or a main executable, because C++
and Java programs typically use exceptions, so this is the right thing
to do.
The rest of that sections gives a possible workaround (it appears) and that is to use the GCC driver to link your shared library, however if the statically-linked library throws exceptions you'll probably get a Segmentation Violation.

Resources