I'm compiling GHDL on my machine either with:
AdaCore GNAT GPL 2017
This is a standalone Ada compiler for Windows that produces a single executable;
or with
MSYS2 / MinGW64 (GCC + GNAT + CLANG, CLANG++, ...)
This is the GCC compiler tool chain for Windows. It produces an executable that needs a handful of DLLs from MinGW in the installation directory.
Is it possible to add a linker flag to integrate the DLLs into the executable to reduce the number of shipped files?
What flags need to be set to merge the required dependencies into the executable?
In this GitHub Issue, I listed all DLL dependencies for GHDL with LLVM backend:
libgcc_s_seh-1.dll
libstdc++-6.dll
libwinpthread-1.dll
zlib1.dll
There might be static libraries available for those things in the /mingw32/lib or /mingw64/lib directory if the MSYS2 developers built static versions of those libraries. You can try passing the -static option to GCC during the link step and I think it will try to use the static versions if they are available. I don't know of any way to merge DLLs into an executable, you have to link against static libraries instead.
Related
I am using gcc 8.1.0 on Windows. To install it I set up Code::Blocks on my computer and updated the environment variable list by adding the path to the gcc.exe program within the installation folder of CodeBlocks. The file editor I used was the built-in editor in Visual Studio. The terminal to compile was the power shell from Visual Studio as well.
In the library development folder I have the files mul.c and mul.h. Their content is irrelevant.
To compile the library I use the command:
gcc -c mul.c
When I run it, it creates a file object mul.o and not mul.lib. I needed to use the option -o mul.lib to successfully create the desired extension file. After placing the header, the .lib file and the main.c in the same parent folder I am obvioudly able to build the executable by running.
gcc main.c -I./include -L/static -lmul -o my_program.exe
I have two questions:
Why does gcc produces a .o if I am in a Windows environment?
I followed a tutorial that compile the static library under Linux and it names it libmul.o, in this way the -lmul option is able to retrieve the library. But if I call my generated static library libul.lib it generates the error:
C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/x86_64-w64-ingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lmul
collect2.exe: error: ld returned 1 exit status
Are these a normal behaviours by gcc, or is it side effect of making gcc available just by updating the Windows environmental variables list?
Thank you to the community in advance.
GCC comes from the *nix world where libraries have the .a extension. When using GCC+MinGW this remains the case.
Shared libraries in MinGW are .dll files but their libraries for linking are .dll.a files.
The advantage of .a files is that a lot of sources build out of the box on Windows with MinGW, especially when using MSYS2 shell.
If you use -l it will look for .a (or .dll.a for shared build) file adding the lib prefix and the extension automatically.
So -lmul will look for libmul.a (static, e.g. when --static linker flag is given) or libmul.dll.a (shared).
By the way, you are using quite an old GCC 8.1.0.
As I write this current version is 12.2.0. Check https://winlibs.com/ for a standalone download (instructions on how to configure in Code::Blocks are on the site) or use MSYS2's package manager pacman.
Is it possible to build GMP for MSVC on Windows?
I need fully static solution (static library), without any DLL dependencies. So that my final EXE doesn't depend on any external (non-system) DLLs.
I'm alright if building GMP will need Cygwin or MSYS, as far as it can be used later in MSVC without any problems. But as far as I know at least Cygwin builds always depend on extra DLLs like cygwin1.dll which is not affordable for me, fully static-library solution is needed.
I'm aware there exists MPIR library that is more Windows friendly. But right now I need specifically GMP solution if possible.
Of course would be great if all optimizations and assembly is used when building for Windows. But if assembly is not possible then at least non-assembly (generic) variant of GMP is needed.
Of course I need 64-bit version.
If someone can post all steps needed to produce such static library for MSVC usage? Or maybe link some web-site that has such instructions?
I successfully managed to compile a working fully statically linked program with GMP using MSVC under Windows.
For that I used installation of MSYS, which is located in c:/bin/msys/ on my machine.
Then inside MSYS shell installed GMP packages mingw-w64-clang-x86_64-gmp and gmp-devel (pacman -S gmp-devel to install and pacman -Ss gmp to search).
In MSVC compiler I added include directory c:/bin/msys/clang64/include/.
Wrote an example of GMP usage program in C++, that implements Trial Division / Pollard's Rho / Pollard's P-1 factoring algorithms using long arithmetics. This program uses both mpz_...() C routines and mpz_class C++ wrapper class. For example this program is located in main.cpp.
To linker command line I added following libraries:
c:/bin/msys/clang64/lib/libgmp.a
c:/bin/msys/clang64/lib/libgmpxx.a
c:/bin/msys/mingw64/lib/gcc/x86_64-w64-mingw32/10.3.0/libgcc.a
c:/bin/msys/clang64/x86_64-w64-mingw32/lib/libmingwex.a
Also I had to add /FORCE flag (read about it here) to linker command, because libmingwex.a has some symbols overlapping with default MSVC's libraries, precisely without /FORCE I had following errors:
libucrt.lib(strnlen.obj) : error LNK2005: wcsnlen already defined in libmingwex.a(lib64_libmingwex_a-wcsnlen.o)
libucrt.lib(strnlen.obj) : error LNK2005: strnlen already defined in libmingwex.a(lib64_libmingwex_a-strnlen.o)
bin\win-msvc-m-64-release\drafts\gmp_int_msvc.exe : fatal error LNK1169: one or more multiply defined symbols found
All steps produced working (tested) final statically-linked program without any external DLL dependencies (of course except for default system DLLs of Windows).
It means MSYS's libraries .a are fully compatible with MSVC and link successfully in MSVC compilation.
Not to have /FORCE linker flag I also did extra following steps. Made a copy of c:/bin/msys/clang64/x86_64-w64-mingw32/lib/libmingwex.a library. Used c:/bin/msys/clang64/bin/objcopy.exe util, which probably was installed together with Clang. With objcopy renamed overlapping symbols:
objcopy --redefine-sym wcsnlen=msys_wcsnlen libmingwex.a
objcopy --redefine-sym strnlen=msys_strnlen libmingwex.a
which allowed me to successfully use this modified libmingwex.a library to link in MSVC without using /FORCE.
I'm not sure what the meaning of installing a compiler(say, gcc) is.
I have an windows machine and will install cygwin.
cygwin has many packages and i installed gcc-related-packages.
But wait, gcc is just a compiler and is not including header files such as stdio.h, stdlib.h, etc.
What compiler does is just finding a header file specified in a some source file.
Installing compiler means (implicitly) installing related header files?
The Cygwin installer knows about package dependencies, and installing gcc will pull in the minimum set of packages needed to compile C programs. However, if you need particular libraries beyond the basic C library, you will have to install them separately.
I created a software that has native components and therefore requires the creation of operating system specific shared libraries (.dylib , .dll and .so ). I have a Mac OSX and I have already created a version of the software that is compatible with Mac OSX machines. I need to release versions that are compatible with other operating systems. Can I simply go on my mac terminal and write:
gcc -o c_prog.dll -shared c_prog.c
and
gcc -o libc_prog.so -shared c_prog.c
Or do I have to create the .so and .dll files on their respective operating systems?
What you suggest is NOT possible. Your compiler can create code for ONE specific target platform, specified by the "host triplet", for example on my linux machine:
> gcc -dumpmachine
x86_64-linux-gnu
Meaning of the host triplet ist $(machine)-$(vendor)-$(operatingsystem).
GCC (and probably some other compilers) can be built as a cross compiler. This is a compiler with a different target host-triplet from the machine it is running on. For my system (Debian Linux), there is a ready made package of GCC for compiling windows 64bit binaries: gcc-mingw-w64-x86-64. So in theory, you can build everything on your system. But don't forget you need the target platform's header files, the matching binutils (for things like packaging a shared library) and a linker and standard C library for the target platform. All together is called a cross toolchain.
Now you could look around for a cross toolchain to target Linux and Windows on your Mac. Maybe you will find something working. Or you could take the though path and try to compile your cross tools yourself from gcc, glibc and binutils sources.
In the end, I resorted to using a real Windows virtual machine for building my software, that I developed on Linux, for Windows. This was a lot easier :)
I am trying to build a gcc cross compiler. I understand that before compiling the cross compiler I need to have the target binutils built already. why the building of the compiler need the target binutils ? the compiler alone only takes high level code and turn it to the assembly that I defined it in the compiler sources. so why do I need the target bintools for compiling the cross compiler ? It is written in all of the cross compiler documentation that I need them to be build before compiling the cross compiler. (e.g. http://wiki.osdev.org/Building_GCC and http://www.ifp.illinois.edu/~nakazato/tips/xgcc.html).
GCC needs an assembler to transform the assembly it generates into object files (machine code), and a linker to link object files together to produce executables and shared libraries. It also needs an archiver to produce static libraries/archives.
Those three are usually provided by the binutils package (among other useful tools): the GNU assembler as, linker ld and the ar archiver.
Your key question seems to be:
why the building of the compiler need the target binutils ?
As described in Building a cross compiler, part of the build process for a GNU cross-compiler is to build runtime libraries for the target using the newly-compiled cross-compiler. So the binutils for the target need to be present for that step to succeed.
It may be possible to build the cross-compiler first, using empty files for the subset of binutils components that gcc needs - such as as and ld and ar and ranlib - then build and install the target binutils components into the proper locations, then build the target runtime libraries.
But it would be less error-prone to do things the following way (and the documentation recommends this): build binutils for the target first, place the specified executables in gcc's source tree, then build the cross-compiler.
The binutils (binary utilities) provide low-level handling of
binary files, such as linking, assembling, and parsing ELF files. The GCC
compiler depends on these tools to create an executable, because it generates
object files that binutils assemble into an executable image.
ELF is the format that Linux uses for binary executable
files. The GCC compiler relies on binutils to provide much of the platform-specific functionality.
Here your are cross-compiling for some other architecture not for x86. So resulting binutils are platform-specific
while configuring has to give --host!=target. i.e --host=i686-pc-linux-gnu
where --target=arm-none-linux-gnueabi.
So resulting executable are not same which host already having binutils.
addition
the basic things needs to be known.
The build machine, where the toolchain is built.
The host machine, where the toolchain will be executed.
The target machine, where the binaries created by the
toolchain are executed.
So binutils will be having tools to generate and manipulate binaries
for a given CPU architecture. Not for the one host is using