How do I compile and link a 32-bit Windows executable using mingw-w64 - linux

I am using Ubuntu 13.04 and installed mingw-w64 using apt-get install mingw-w64. I can compile and link a working 64-bit version of my program with the following command:
x86_64-w64-mingw32-g++ code.cpp -o app.exe
Which generates a 64-bit app.exe file.
What binary or command line flags do I use to generate a 32-bit version of app.exe?

That depends on which variant of toolchain you're currently using. Both DWARF and SEH variants (which come starting from GCC 4.8.0) are only single-target. You can see it yourself by inspecting the directory structure of their distributions, i.e. they contain only the libraries with either 64- or 32-bit addressing, but not both. On the other hand, plain old SJLJ distributions are indeed dual-target, and in order to build 32-bit target, just supply -m32 flag. If that doesn't work, then just build with i686-w64-mingw32-g++.
BONUS
By the way, the three corresponding dynamic-link libraries (DLLs) implementing each GCC exception model are
libgcc_s_dw2-1.dll (DWARF);
libgcc_s_seh-1.dll (SEH);
libgcc_s_sjlj-1.dll (SJLJ).
Hence, to find out what exception model does your current MinGW-w64 distribution exactly provide, you can either
inspect directory and file structure of MinGW-w64 installation in hope to locate one of those DLLs (typically in bin); or
build some real or test C++ code involving exception handling to force linkage with one of those DLLs and then see on which one of those DLLs does the built target depend (for example, can be seen with Dependency Walker on Windows); or
take brute force approach and compile some test code to assembly (instead of machine code) and look for presence of references like ___gxx_personality_v* (DWARF), ___gxx_personality_seh* (SEH), ___gxx_personality_sj* (SJLJ); see Obtaining current GCC exception model.

Related

Emscripten Clang produce ELF 64-bit executabel and wasm binary cross compiler targets

I have a prepared a minimal Cmake project containing one cpp file which represent the main and one cpp file which represent the shared library, that prints basically hello world.
https://github.com/courteous/wasmELF.git
The target is to compile this miniaml code with emscripten/clang only and produce
1) one WebAssembly (wasm) binary module version 0x1 (MVP)
2) one ELF 64-bit LSB
without clearing the cmake build directory and rebuilding it again.
Currently i can successfully produce them bought by running the commands
emconfigure cmake ../ -DCMAKE_BUILD_TYPE=WASM
make
and
cmake ../ -DCMAKE_BUILD_TYPE=Linux
make
However the problem is that in order to do that i need to compile the first one with Clang the to remove the build and then to do a second compilation with GCC. I would like Emscripten/Clang to produce them bought instead. I do not want to delete the build directory since the compilation times is taking too long. (Well not in this Project but imagine if the project was much larger)
What i see is that emscripten/clang selects always a target "wasm32-unknown-emscripten"
clang++ -target wasm32-unknown-emscripten
and if i understand that correctly the target should change
I do see that the project is producing LLVM IR bitcode since i have send the flag "flto"
i.e.
file TestSharedClass.cpp.o
TestSharedClass.cpp.o: LLVM IR bitcode
and in the CMakeLists.txt
set(CMAKE_CXX_FLAGS "-flto")
x86_64-unknown-linux-gnu is a supported target by emscripten/Clang
~/Projects/emscripten/emsdk/upstream/bin$ ./llc --version
LLVM (http://llvm.org/):
LLVM version 11.0.0git
Optimized build with assertions.
Default target: x86_64-unknown-linux-gnu
Host CPU: haswell
Registered Targets:
wasm32 - WebAssembly 32-bit
wasm64 - WebAssembly 64-bit
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
In cmake i do have
SET(TARGET x86_64-unknown-linux-gnu)
however when i run
emconfigure cmake ../ -DCMAKE_BUILD_TYPE=Linux
make
i get mainTestFile.js and mainTestFile.wasm instead of ELF 64-bitcode.
what i am doing wrong here. How to tell clang to product once ELF and once wasm from the same code run without having to clear the build directory. This should be possible since clang is producing LLVM IR bitcode. Or do i understand that wrong?
https://github.com/emscripten-core/emscripten/issues/10361
OK that seems to not be possible i.e. the reply from the dev on github states that emcc or emmake can not be used with another target other then wasm32-unknown-emscripten.

Can gcc produce binary for Arm without cross compilation

Can we configure gcc running on intel x64 architecture to produce binary for ARM chip by just passing some flags to gcc and not using a cross compiler.
Short: Nope
Compiler:
gcc is not a native crosscompiler, the target architecture has to be specified at the time you compile gcc. (Some exceptions apply, as for example x86 and x86_64 can be supported at the same time)
clang would be a native crosscompiler, and you can generate code for arm by passing -target=arm-linux-gnu, but you still cant produce binaries, as you need a linker and a C-library too. Means you can run clang -target=arm-linux-gnu -c <your file> and compile C/C++ Code (will likely need to point it to your C/C++ include paths) - but you cant build binaries.
Rest of the toolchain:
You need a fitting linker and toolchain too, both are specific to the architecture and OS you want to run at.
Possible solutions:
Get a fitting toolchain, or compile your own. For arm linux you have for ex. CrossToolchains if you are on debian, for barebones you can get a crosscompiler from codesourcery.
Since you were very vague, its not possible to give you a clearer answer

How to deploy a portable gcc with cloog?

I'm trying to build a portable version of gcc 4.8.2. (for only C/C++ languages) The end result is have gcc installed into a specific application directory, eg, /opt/gcc-4.8.2 so that I can copy that directory from one computer to another (all computers are either intel corei5 or corei7, running recent Linux versions, eg, Ubuntu 12, Suse 10/11, Centos 5 & 6).
So far I'm able to build gcc ok, using --prefix to have the gcc outputs placed in a single directory (which can then be later copied to the other hosts). I configured & built gcc's dependencies (gmp, mpfr, mpc, isl) to have --disable-shared, so I can be sure that the final gcc, when copied to other hosts, won't complain about missing libraries or symbols.
I have a question with cloog. I configured gcc with --with-cloog (to pick up my locally built cloog, which I built along with the other gcc dependencies). However, what I don't know, is whether I also need to copy the cloog libraries and binary to each host I copy gcc to?
Also, how can I test gcc & cloog interaction? Is there a simple C file example and/or gcc command line that can be used to test whether gcc is successfully making use of cloog?
Additionally, are there any other considerations when trying to build a gcc which I then want to run on other hosts?
It depends if cloog is installed as a shared library libcloog-isl.so.* or as a static one libcloog.a ; use
ldd $(gcc-4.8 -print-file-name=cc1)
to find out. Of course you need to install all the shared libraries dependencies. If libcloog*so appears in the output of above ldd command, it is a shared library. Otherwise a static one.
You could set the LD_LIBRARY_PATH, or add the directory containing libcloog-isl.so.* (e.g. /usr/local/lib/ or /opt/lib/ etc...) to /etc/ld.so.conf (then run ldconfig)
I am not entirely sure your gcc build can run on every platform you mentioned. There might be libc* dependencies. See this. And perhaps also binutils dependencies (notably for gcc-4.8 -flto compilations).
To test gcc just compile with optimizations (e.g. gcc-4.8 -Wall -O3) some non-trivial file.

Using libraries compiled with GCC in a VisualC++ project (and vice versa)

It's possible to use code (and libraries) compiled with VisualC++ (so with .lib extension) in a project that will use GCC as compiler (and vice versa)? Or I have to rebuild them?
I'm trying to use SOCI 3.1 libraries that I have compiled with VisualC++ in a project that has GCC as compiler, but I'm getting some errors, and I don't know why..
You have to produce binaries for GCC using MinGW tools: reimp and dlltool. Here is MinGW wiki with complete explanation of the procedures: MSVC and MinGW DLLs
Short example:
reimp -d libmysql.lib
dlltool -k --input-def libmysql.def --dllname libmysql.dll --output-lib libmysql.a
reimp libmysql.lib
By the way, here is related thread on SOCI users mailing list which: MySQL Build fails. Look for useful links given in the thread.

Use of ia32-libs

I'm trying to use the asmlibrary which I've obtained from here
I'm running in 64-bit, but the pre-compiled static library is build for 32-bit.
I don't really want to recompile the library, because I do not have OpenCV 1.0 installed, and don't really want to install such an old version of this piece of software.
My employer has told me that you may use ia32-libs which would allow me to use the library on a 64-bit machine. I have installed these libs using apt.
In netbeans, my IDE of choice, I'm now attempting to use the library. I keep getting the messages:
/usr/bin/ld: i386 architecture of input file
`../asmlib/libasmlibrary.a(asm_shape.o)' is incompatible with
i386:x86-64 output
Etc..
I have two questions:
1) Will ia32-libs allow me to use this library?
2) How must I "enable" it's use, either generally or preferably specific to netbeans (if applicable)
Thank you
An executable (including the libraries it depends on) has to be entirely 32 bits or 64 bits. You cannot mix and match object files of different types.
So to use a 32 bits library, you must compile your program as a 32 bits executable and link with a 32 bits version of libc and other core libraries. On debian you'll need packages like libc6-dev-i386 and ia32-libs-dev.
To compile foo.c as a 32 bits executable, use
gcc -m32 -o foo foo.c
How to do this with netbeans is left as an exercise.
I don't think that you are able to use ia32-libs to compile a 64-bit program, using 32-bit libraries. That isn't what ia32-libs is designed for...it's designed to run entirely 32-bit programs on 64-bit systems.
I think your best bet would be to compile as 32-bit software. If you were using the command line, you can just add the -m32 flag to gcc. With netbeans, in Project Properties > Build > C Compiler (or C++ compiler if that's what you are using), there is a dropdown to select architecture. If 32-bit is not available in that dropdown, you can add -m32 to the Additional Options box.

Resources