Unable to run windows binary compiled with clang/lld/mingw - c

I have downloaded and installed clang on windows 10 from http://releases.llvm.org/download.html
and mingw from https://sourceforge.net/projects/mingw-w64/
I am trying to compile a very basic C program using clang/lld/mingw:
int main(int argc, char* argv[argc + 1])
{
return 0;
}
To compile I invoke:
clang.exe -target x86_64-windows-gnu -fuse-ld=lld.exe -g -gcodeview -Wl,/debug,/pdb:example.pdb example.c -o example.exe
This creates an exe which faults on startup in mainCRTStartup (__security_init_cookie to be precise).
However, running with default ld from binutils is successful:
clang.exe -target x86_64-windows-gnu example.c -o example.exe
Please note that I wish to use mingw headers, not msvc.
In total I tried:
x86_64-8.1.0-posix-seh-rt_v6-rev0
x86_64-7.3.0-posix-seh-rt_v5-rev0
x86_64-8.1.0-win32-seh-rt_v6-rev0
x86_64-8.1.0-win32-sjlj-rt_v6-rev0
without any luck producing a functional program.
So I am wondering, is there something obvious I am doing wrong here?
EDIT:
I have also tried with msys2 to no avail. Specifically:
pacman -S mingw-w64-x86_64-clang mingw-w64-x86_64-lld

According to https://bugs.llvm.org/show_bug.cgi?id=40568
Linking against mingw import libraries from a normal mingw installation is a new feature, first present in LLD 8.
Unless wanting to compile a pre-release version of lld, have to wait for binary release of llvm 8.0.0. This will hopefully be sometime in March.

Related

Undefined refrences to '__imp' and '__cxa' when linking libraw

I'm trying to link the c++ library, libraw, into my c program.
windows 10 msys2. Using clion, but also trying to compile from mingw64 terminal using gcc and clang
At first, I was using the version of libraw that i got from msys2 pacman. The issue is that the version in the repo is the latest release, but it is quite old and I need the beta release of libraw to support one of my newer cameras.
I've built the libraries from source (https://github.com/LibRaw/LibRaw) in mingw, and moved the libraw.a file, and .h files into the mingw64/lib and /include folder respectively, just as they appeared when added using pacman.
The issue is that now when I compile, a long list of errors is spit out including things such as undefined references to '__cxa'
I'm wondering what is causing these compile errors and what I can do to fix them, so that I can use libraw in my project. I assume it has something to do with how I'm compiling libraw, since using the version from pacman, the exact same c and cmake code works perfectly.
Here a simplified version of my c program (note that libtiff is working just fine, can can be ignored from the samples):
#include <stdio.h>
#include <tiffio.h>
#include <libraw.h>
int main(void);
int main(void)
{
const char* libtiffVersion;
const char* librawVersion;
libtiffVersion = TIFFGetVersion();
if(libtiffVersion)
printf("%s\n", libtiffVersion);
else
printf("libtiff not found!\n");
librawVersion = libraw_version();
if(librawVersion)
printf("%s\n", librawVersion);
else
printf("libraw not found!\n");
return 0;
}
and my cmake (tried with various c standards from 90 to 23, although i don't think it mattres):
cmake_minimum_required(VERSION 3.23)
project(MyProject C)
set(CMAKE_C_STANDARD 90)
find_library(LIBRAW libraw)
find_library(LIBTIFF libtiff)
add_executable(MyProject main.c)
target_link_libraries(MyProject ${LIBTIFF} ${LIBRAW})
The linker command generated by cmake is:
cmd.exe /C "cd . && C:\msys64\mingw64\bin\gcc.exe -g CMakeFiles/MyProject.dir/main.c.obj -o MyProject.exe -Wl,--out-implib,libMyProject.dll.a -Wl,--major-image-version,0,--minor-image-version,0 C:/msys64/mingw64/lib/libtiff.dll.a C:/msys64/mingw64/lib/libraw.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
I read that what could be causing some of the issue, is that libraw is a c++ library (includes a c wrapper), while I'm trying to compile a c program, but trying to compile from the command line with g++, clang++, gcc with -lsupc++ with no luck. doing it this way gives me different errors, many of them including undefined reference to '__imp'
I've also tried copying the libraw.a file into my source directory compiling with a path to the .a file, with the no success.
I've tried using the binary release of the older version of libraw that I know was working, by copying the libraw.lib file to my source directory and changing my cmake file:
cmake_minimum_required(VERSION 3.23)
project(MyProject C)
set(CMAKE_C_STANDARD 90)
find_library(LIBTIFF libtiff)
add_executable(MyProject main.c)
target_link_libraries(MyProject ${LIBTIFF} ${PROJECT_SOURCE_DIR}/libraw.lib)
This time it compiles, but immediatly segfualts. Might have something to do with the binaries being built for windows using msvc while in using msys2/mingw64

How do I compile code using Clang with the MinGW C/C++ Library? (Particular issue with float.h)

I have a simple program which I can successfully compile with clang, using MinGW's C/C++ Library:
#include <stdio.h>
int main(int argc, char **argv) { printf("Hello world!\n"); return 0; }
I am able to compile this with mingw-gcc successfully:
$ gcc test.c -o test
$ ./test
Hello world!
I am also able to compile it successfully using clang+mingw:
$ clang test.c -o test -target
$ ./test
Hello world!
However, if I make a small change to my program (include float.h), it continues to compile with gcc but no longer compiles with clang:
#include <stdio.h>
#include <float.h>
int main(int argc, char **argv) { printf("Hello world!\n"); return 0; }
$ gcc test.c -o test
$ ./test
Hello world!
$ clang test.c -o test -target x86_64-pc-windows-gnu
In file included from test.c:2:
In file included from C:\llvm\built\lib\clang\8.0.0\include\float.h:45:
C:\mingw64-8.1.0\x86_64-w64-mingw32\include\float.h:28:15: fatal error: 'float.h' file not found
#include_next <float.h>
^~~~~~~~~
1 error generated.
Is there some configuration issue with clang or some missing command line argument? Googling around a bit, it appears that the order of paths when including float.h is important, but this is all supposed to be handled internally by the clang driver.
The older binary releases of MinGW-w64 have an incompatibility with Clang 8.0+'s float.h. To fix this, copy this specific revision of float.h into the correct location and use it.
I think that it would be advisable to pass this issue on to one of the clang developers.
Comparing the previous release 7.1.0's float.h to the one in 8.0.0 shows only a few differences. The first one I myself would be asking about, is why they change to the header guard from __FLOAT_H to __CLANG_FLOAT_H.
Have a play around changing the 8.0.0 header guard and see what happens.
Edit: Did a bit more searching. The MinGW-w64 developers know of this change since August 2018. Add or adapt the patch from https://sourceforge.net/p/mingw-w64/mailman/message/36386405/ to your MinGW install may sort it out.
Edit 2: Something that I have not used for a while is my MSYS2 install of MinGW. It shows g++.exe (Rev1, Built by MSYS2 project) 8.2.1 20181214. This has the applied patch to line 27 of float.h.
#if !defined(_FLOAT_H___) && !defined(__FLOAT_H) && !defined(__CLANG_FLOAT_H)
While the source forge download of MinGW-w64 8.1.0 has it shown as
#if !defined(_FLOAT_H___) && !defined(__FLOAT_H)
Note: I'm also sure that MSYS2 uses a rolling release update, but I would have to check on that. It's not something that I use on a regular basis.
Edit3: MSYS2 looks like it's a rolling release. Latest versionis 9.1.0.
My opinion unless you need a stand alone MinGW, then go with MSYS2 with the latest updates. Just trying to patch one of the old versions may work, but there could be other issues that my show themselves. If you do need a stand alone version, then I think that the only option would be to build MinGW-w64 directly from source.
NOTE: I would have added comments to the above discussion, but being new I'm not allowed yet.
EDIT 4:
NOTE: The third party multilib toolchains are more than likely built with sjlj exceptions as default. See https://stackoverflow.com/a/17968530/11879567 on how to check.
Edit 5:
Hopefully this is the last edit I will be making.
Checking out the MinGW-w64 forums to see if anyone had asked when the next official release was due. I came across someone who did ask about when 8.2 was to be released. I got the impression that you could be in for a very long wait for any new MinGW-w64 release.
https://sourceforge.net/p/mingw-w64/discussion/723797/thread/ea9a5b00fb/
SIDE NOTE:
As I have found out when dealing with Clang, you are always going to have one issue or another with it, either with MinGW or Visual Studio.

Cross-compiled library not found by toolchain

I'm new to developing for embedded systems, but I have installed arm-linux-gnueabi-gcc via the Linux Mint package manager and managed to build a few programs successfully.
I'm currently struggling with getting a program to compile using libusb. I've done the following:
Downloaded and unpacked the libusb 1.0.20 sources from https://sourceforge.net/projects/libusb/.
Compiled and installed them using the following commands:
~/Downloads/libusb-1.0.20 $ ./configure --host=arm-linux-gnueabi --prefix=/opt/ --disable-udev
~/Downloads/libusb-1.0.20 $ sudo make
~/Downloads/libusb-1.0.20 $ sudo make install
(The reason for sudo-ing the make commands was because I encountered permission problems related to removing old files.)
Copied a small sample file from somewhere on the internet:
#include <libusb-1.0/libusb.h>
#include <stdio.h>
int main()
{
int i=0;
libusb_context **c = NULL;
i = libusb_init(c);
printf("\nusing libusb.h\n");
return 0;
}
Tried to build it and run it with gcc:
~/Desktop/libtest $ gcc libtest1.c -o libtest1 -lusb-1.0
~/Desktop/libtest $ ./libtest1
using libusb.h
However, when I try to do the same with arm-linux-gnueabi-gcc, it can't find the library:
~/Desktop/libtest $ arm-linux-gnueabi-gcc libtest1.c -o libtest1 -lusb-1.0
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/bin/ld: cannot find -lusb-1.0
collect2: error: ld returned 1 exit status
Where did I go wrong? Is there something else I need to do in order to use the library? Did I fail at compiling the library for the arm compiler? I didn't include the compiler output here since it's quite long, but there are no obvious errors. This might be a very stupid question, but I'm completely clueless.

Compiling SQLite for Windows (64-bit)

I have MinGW and I wish to compile the SQLite amalgamation source into a 64-bit dll. I'm fairly new to this sort of compilation and my efforts so far have resulted in failure. (I first started using the autoconf amalgamation and used the configure & make tool on Linux. But apparently that will never work for Windows binaries.)
Anyway, I've been told I need the following preprocessor defines:
Here are the compiler pre-processor defines I use for a 64-bit release build:
WIN64 NDEBUG
_WINDOWS
_USRDLL
NO_TCL
_CRT_SECURE_NO_DEPRECATE
THREADSAFE=1
TEMP_STORE=1
SQLITE_MAX_EXPR_DEPTH=0
Here are the compiler pre-processor defines I use for a 32-bit release build:
WIN32
NDEBUG
_WINDOWS
_USRDLL
NO_TCL
_CRT_SECURE_NO_DEPRECATE
THREADSAFE=1
TEMP_STORE=1
SQLITE_MAX_EXPR_DEPTH=0
I had no idea where to put these in. I eventually took an educated guess, made a new file (for neatness) called sqlite3w64.h and pasted in the following:
#define WIN64 NDEBUG
#define _WINDOWS
#define _USRDLL
#define NO_TCL
#define _CRT_SECURE_NO_DEPRECATE
#define THREADSAFE 1
#define TEMP_STORE 1
#define SQLITE_MAX_EXPR_DEPTH 0
I then compiled the source with the following command:
gcc sqlitew64.h sqlite3.h sqlite3ext.h shell.c sqlite3.c -o sqlite_x64.dll
What resulted was a 733KB DLL file. Nice! Did it actually work? Did it nuts - I got a BadImageFormatException. I also then tried doing an x86 compilation using the same method. Once again, I got a 733KB DLL file (that's odd?) and once again, I got a BadImageFormatException.
Help.
Update
Used the following command instead:
gcc -shared -DWIN64 -DNDEBUG -D_WINDOWS -D_USRDLL -DNO_TCL -D_CRT_SECURE_NO_DEPRECATE -DTHREADSAFE=1 -DTEMP_STORE=1 -DSQLITE_MAX_EXPR_DEPTH=0 -I. shell.c sqlite3.c -o sqlite_x64.dll -Wl,--out-implib,sqlite3.a
Resulted in a 740KB DLL file which still gives a BadImageFormatException.
Final Update
Turns out my MinGW build was 32-bit only. Getting a 64-bit version then allowed me to make SQLite for 64-bit. Adding the flag -m64 sets the compiler into 64-bit mode.
64-bit:
gcc -shared -DWIN64 -DNDEBUG -D_WINDOWS -D_USRDLL -DNO_TCL -D_CRT_SECURE_NO_DEPRECATE -DTHREADSAFE=1 -DTEMP_STORE=1 -DSQLITE_MAX_EXPR_DEPTH=0 -m64 -I. shell.c sqlite3.c -o sqlite3_x64.dll -Wl,--out-implib,sqlite3_x64.a
32-bit:
gcc -shared -DWIN32 -D_WINDOWS -D_USRDLL -DNO_TCL -D_CRT_SECURE_NO_DEPRECATE -DTHREADSAFE=1 -DTEMP_STORE=1 -DSQLITE_MAX_EXPR_DEPTH=0 -m32 -I. shell.c sqlite3.c -o sqlite3_x86.dll -Wl,--out-implib,sqlite3_x86.a
MinGW-64 Precompiled: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds/mingw-w64-bin_i686-mingw_20111220.zip/download?use_mirror=ignum
Installation Instructions: http://code.google.com/p/tonatiuh/wiki/InstallingMinGWForWindows64
You are compiling to an EXE. Calling it a DLL won't magically make it a DLL.
You need to pass special linker options to gcc to make it create DLLs.
Quoted from Mingw site: (Sort of, I replaced g++ with gcc)
gcc -c -DBUILDING_EXAMPLE_DLL example_dll.cpp
gcc -shared -o example_dll.dll example_dll.o -Wl,--out-implib,libexample_dll.a
The page also explains that functions you want your DLL to export, must be declared with __declspec(dllexport). (Further down, there is an example on how to export all global functions to the DLL, like usually happens in Unix.)
The -Wl argument to gcc is what tells gcc to pass on the further arguments --out-implib,libexample_dll.a to the linker.
I would also make 100% sure that the built DLL is actually a 64 bit DLL and not a 32 bit DLL. Do you have any way to check that? On Linux you can run the "file" command.
You can also try adding the -m64 option to the gcc commandline, that should force gcc to target the amd64 target.
If that doesn't work, you may have the wrong compiler altogether. Make sure you have the x86_64/amd64 version of the Mingw toolchain. Installation is as simple as finding the right ZIP, unpacking it, and setting the path.
If all of that fails, or if you just want to verify against a supposedly correctly compiled setup, try precompiled 64-bit binaries here or from here.
What would work in your case is this single link-and-compile command:
g++ -shared
-DWIN64
-DNDEBUG
-D_WINDOWS
-D_USRDLL
-DNO_TCL
-D_CRT_SECURE_NO_DEPRECATE
-DTHREADSAFE=1
-DTEMP_STORE=1
-DSQLITE_MAX_EXPR_DEPTH=0
-I.
shell.c sqlite3.c
-o sqlite_x64.dll
-Wl,--out-implib,libsqllite_x64.dll.a
The compile and link stage will be performed at once. The defined can be added on the commandline. The headers need not be compiled, but you need to pass the current directory as a header search directory, and specify the names of the dll and import file.

gcov: cannot open graph file

I am trying to use gcov. I have this simple file a.c:
int main() {
return 0;
}
So I do
gcc -fprofile-arcs -ftest-coverage a.c -o a
./a
gcov a.c
and I get
a.gcno:cannot open graph file
Am I doing something wrong? I'm under Mac OS X Lion.
By default on Lion, "gcc" is not gcc. It's LLVM. And it doesn't support generating test coverage data.
If you run gcc-4.2 -fprofile-arcs -ftest-coverage a.c -o a instead that will use a real gcc, and it'll probably work.
Are you sure you are running the command from the same directory as the source file? You must be in the same directory, unless you specify the -o flag. Try:
gcov -o a.c
Try using clang instead of gcc. I had the same problem, and using clang fixed it for me.
Often this happens when the version of gcov you're running doesn't match the version of GCC used to compile the application. On some systems, package managers have odd practices in how they link GCC and gcov. For example on many systems gfortran is the same as gfortran-5 but gcov might be something old and crusty.
I used the following on Mac 10.8.4:
Installed via xcode the command line tools:
wrote this example code from the gcc website:
#include <stdio.h>
main()
{
int i, total; total = 0;
for (i = 0; i < 10; i++)
total += i;
if (total != 45)
printf ("Failure\n");
else
printf ("Success\n");
}
Compiling using the real GCC gcc-mp-4.7 -fprofile-arcs -ftest-coverage tmp.c
And using GCC's gcov: gcov-mp-4.7 -b tmp.c will give you this output:
File 'tmp.c'
Lines executed:87.50% of 8
Branches executed:100.00% of 4
Taken at least once:75.00% of 4
Calls executed:50.00% of 2
Creating 'tmp.c.gcov'

Resources