Build shared library with Clang++ - windows

I am trying to build a shared library (dll for Windows) using Clang++.
I have run the following commands:
clang++ -c -o hello.o hello.cpp
clang++ -shared -v -o hello.dll hello.o
The first command works fine but when I try to build the dll I get this error:
clang version 3.2 (tags/RELEASE_32/final)
Target: i686-pc-mingw32
Thread model: posix
"c:/MinGW/bin/g++.exe" -shared -v -m32 -o worker.dll worker.o
Using built-in specs.
COLLECT_GCC=c:/MinGW/bin/g++.exe
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.6.2/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.6.2/configure --enable-languages=c,c++,ada,fortran,objc,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgomp --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --build=mingw32 --prefix=/mingw
Thread model: win32
gcc version 4.6.2 (GCC)
COMPILER_PATH=c:/mingw/bin/../libexec/gcc/mingw32/4.6.2/;c:/mingw/bin/../libexec/gcc/;c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/bin/
LIBRARY_PATH=c:/mingw/bin/../lib/gcc/mingw32/4.6.2/;c:/mingw/bin/../lib/gcc/;c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/lib/;c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../;/mingw/lib/
COLLECT_GCC_OPTIONS='-shared' '-v' '-m32' '-o' 'worker.dll' '-shared-libgcc' '-mtune=i386' '-march=i386'
c:/mingw/bin/../libexec/gcc/mingw32/4.6.2/collect2.exe --shared -Bdynamic -e _DllMainCRTStartup#12 --enable-auto-image-base -u ___register_frame_info -u ___deregister_frame_info -o worker.dll c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../dllcrt2.o c:/mingw/bin/../lib/gcc/mingw32/4.6.2/crtbegin.o -Lc:/mingw/bin/../lib/gcc/mingw32/4.6.2 -Lc:/mingw/bin/../lib/gcc -Lc:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/lib -Lc:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../.. -L/mingw/lib worker.o -lstdc++ -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt c:/mingw/bin/../lib/gcc/mingw32/4.6.2/crtend.o
Cannot export _hello: symbol not found
collect2: ld returned 1 exit status
clang++: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)
Here is the file I am compiling:
// hello.cpp
#include <iostream>
#if defined(_WIN32)
#define LIBRARY_API __declspec(dllexport)
#else
#define LIBRARY_API
#endif
extern "C" void LIBRARY_API hello();
void hello()
{
std::cout << "Hello, World!" << std::endl;
}

A follow up to this important question is that as of clang++ version 6.0, the compilation of a DLL by clang is fine. There are differences for the name mangling of C++ functions in C++ for MSVC and CLang, that can impair the use of DLL's in mixed environments but these differences are easy to spot and correct.

Related

compiler error gtk+3 undefined reference on windows

I am trying to create a GUI program using gtk3 but I am unable to compile a program that utilize the gtk library! I am running windows 8 and I installed gtk using msys via the following method:
I have dowloaded and installed MSYS2 from msys2 website. I am running the msys2 mingw-w64 64 bits version. I updated everything using pacman -Syu and executed pacman -S mingw-w64-x86_64-gtk3 base-devel mingw-w64-toolchain.
Then I added ;C:\msys64\mingw64\bin to my path via Control Panel -> System and Security -> System -> Advanced system settings -> Environment Variables and under the System variables I modified the variable Path and appended ;C:\msys64\mingw64\bin at the end.
I then installed Code::Blocks mingw setup, 64 bit successfully
I created a console application -> c project -> GNU GCC compiler -> create project.
I pasted in the following code into the main.c file, overriding whatever was there as default, with this piece of code
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
printf("Hello world!\n");
return 0;
}
I opened the compiler settings via Settings -> Compiler... -> Other compiler options and appended pkg-config gtk+-3.0 --cflags with '`' on each side (cannot add this here because that is the format for code...
Then I added pkg-config gtk+-3.0 --libs (again with the ´ but in the other direction on each side of the argument) in Linker settings -> Other linker options:
When I try to compile and run the project I get this
Build messages
||=== Build: Debug in gtkdev (compiler: GNU GCC Compiler) ===|
c:\mingw\bin..\lib\gcc\mingw32\8.2.0........\mingw32\bin\ld.exe: obj\Debug\main.o||in function main':|
C:\Users\name\Documents\development\gtkdev\main.c|7|undefined reference togtk_init_abi_check'|
||error: ld returned 1 exit status|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
error: ld returned 1 exit status
Build log
mingw32-g++.exe -o bin\Debug\gtkdev.exe obj\Debug\main.o -LC:/msys64/mingw64/lib -lgtk-3 -lgdk-3 -lz -lgdi32 -limm32 -lshell32 -lole32 -Wl,-luuid -lwinmm -ldwmapi -lsetupapi -lcfgmgr32 -lpangowin32-1.0 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lintl -lglib-2.0 -LC:/msys64/mingw64/lib -lgtk-3 -lgdk-3 -lz -lgdi32 -limm32 -lshell32 -lole32 -Wl,-luuid -lwinmm -ldwmapi -lsetupapi -lcfgmgr32 -lpangowin32-1.0 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lintl -lglib-2.0
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: obj\Debug\main.o: in function main':
C:/Users/name/Documents/development/gtkdev/main.c:7: undefined reference togtk_init_abi_check'
collect2.exe: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
2 error(s), 0 warning(s) (0 minute(s), 0 second(s))
Output of pkg-config gtk+-3.0 --cflags in msys
-pthread -mms-bitfields -IC:/msys64/mingw64/include/gtk-3.0 -IC:/msys64/mingw64/include/cairo -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/pango-1.0 -IC:/msys64/mingw64/include/fribidi -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/atk-1.0 -IC:/msys64/mingw64/include/cairo -IC:/msys64/mingw64/include/pixman-1 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/freetype2 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/harfbuzz -IC:/msys64/mingw64/include/libpng16 -IC:/msys64/mingw64/include/gdk-pixbuf-2.0 -IC:/msys64/mingw64/include/libpng16 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/lib/libffi-3.2.1/include -IC:/msys64/mingw64/include/glib-2.0 -IC:/msys64/mingw64/lib/glib-2.0/include -IC:/msys64/mingw64/include
Output of pkg-config gtk+-3.0 --libs in msys
-LC:/msys64/mingw64/lib -lgtk-3 -lgdk-3 -lz -lgdi32 -limm32 -lshell32 -lole32 -Wl,-luuid -lwinmm -ldwmapi -lsetupapi -lcfgmgr32 -lpangowin32-1.0 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lintl -lglib-2.0
Using the flags instead of relying on pkg-config does not change anything. Compiling main.c from windows Command Propt using gcc and said flags results in the same error as in Code::Blocks. Moving the order of the options/flags in different ways does not change the error. For example having the libraries last and the cflags directly after gcc or main.c does not change the output, I have seen a "solutions" where there has to be a specific order to compile and link everything correctly, which does not work in the windows Command prompt nor in Code::Blocks apparently. Further more adding the compiler and linker options in Build Options for the project in Code::Blocks does not change anything either. Still the same error.
NOTE: When I compile the above program using msys2 console and compile it with gcc main.c -o run_me pkg-config --cflags --libs gtk+-3.0 I get errors about -ldwmapi but I get a run_me.exe file that works just as expected. I have pasted in some different example gtk c code into the main.c file and compiled it with the msys console and it compiles & links an exe file perfectly, even manages to create gtk windows flawlessly. This is not sustainable because it is awful to code in nano inside a console that does not have auto completion.

aligned_alloc not found for clang

I am running the following version of clang on a Mac OS X host:
$ clang -v
Apple LLVM version 8.1.0 (clang-802.0.42)
I have some code that uses the aligned_alloc() C11 function to allocate an aligned chunk of memory.
I am compiling my binary with the -std=c11 flag:
...
clang -g -Wall -Wextra -mavx -std=c11 -D__USE_POSIX -D__STDC_CONSTANT_MACROS -D__STDINT_MACROS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE=1 -O2 -c my_binary.c -o my_binary.o; \
clang -g -Wall -Wextra -mavx -std=c11 -D__USE_POSIX -D__STDC_CONSTANT_MACROS -D__STDINT_MACROS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE=1 -O2 my_binary.o -o my_binary -lm; \
...
I am including stdlib.h and adding POSIX flags. From my_binary.h:
...
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif /* getline() support */
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#endif /* aligned_alloc() support */
#include <stdlib.h>
...
I get the following compilation warning:
my_binary.c:245:15: warning: implicit declaration of function 'aligned_alloc' is invalid in C99 [-Wimplicit-function-declaration]
s->data = aligned_alloc(32, s->n * sizeof(*s->data));
Which follows with this error:
Undefined symbols for architecture x86_64:
"_aligned_alloc", referenced from:
_bs_initialize_signal_avx in my_binary.o
_bs_copy_signal_avx in my_binary.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [build] Error 1
What am I doing incorrectly with clang, such that compilation ignores the std C11 flag?
I am able to compile without errors on a CentOS 7 (Linux) host with gcc 5.3.0 and glibc 2.22.

Using Mono's mkbundle to cross-compile for ARM from linux

I'm trying to use Mono's mkbundle tool to compile a native app for ARM (RaspberryPi) from an AMD64 system (Ubuntu 14.04 running in a VM).
Mono version is 4.4.2.11 (latest, at time of doing this), installed from Mono's package repository, but also tried with 4.2.3.4.
I'm running:
export CC="/usr/bin/arm-linux-gnueabi-gcc"
export AS="/usr/arm-linux-gnueabi/bin/as"
/usr/bin/mkbundle --static --deps --skip-scan \
-o artifacts/MyApp \
bin/Debug/MyApp.exe bin/Debug/*.dll
This works fine if I run it on the RaspberryPi itself (though I don't need to set the CC and AS variables).
If I run it from my AMD64 VM, it eventually runs the command:
/usr/bin/arm-linux-gnueabi-gcc -o artifacts/MyApp -Wall \
-D_REENTRANT -I/usr/lib/pkgconfig/../../include/mono-2.0 \
temp.c \
-L/usr/lib/pkgconfig/../../lib \
-Wl,-Bstatic -lmono-2.0 -Wl,-Bdynamic \
-lm -lrt -ldl -lpthread \
temp.o
Which results in:
/usr/lib/pkgconfig/../../lib/libmono-2.0.a: error adding symbols: File format not recognized
collect2: error: ld returned 1 exit status
Realizing that the libmono-2.0.a comes from an architecture-specific package, I downloaded the armel architecture package from http://download.mono-project.com/repo/debian/pool/main/m/mono/ and extracted it in my home directory (so there is a /home/gregmac/libmono-armel/usr/lib/libmono-2.0.a), then tried:
/usr/bin/arm-linux-gnueabi-gcc -o artifacts/MyApp -Wall \
-D_REENTRANT -I/home/gregmac/libmono-armel/usr/include/mono-2.0 \
temp.c \
-L/home/gregmac/libmono-armel/usr/lib \
-Wl,-Bstatic -lmono-2.0 -Wl,-Bdynamic \
-lm -lrt -ldl -lpthread \
-v \
temp.o
I've also tried setting LIBRARY_PATH and LD_LIBRARY_PATH to /home/gregmac/libmono-armel/usr/lib, but always getting the same problem.
Full output (including -v option):
Using built-in specs.
COLLECT_GCC=/usr/bin/arm-linux-gnueabi-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/lto-wrapper
Target: arm-linux-gnueabi
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7.3-12ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,
obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr
/arm-linux-gnueabi/include/c++/4.7.3 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-gnu-unique-object --disable-libmudflap --dis
able-libitm --enable-plugin --with-system-zlib --enable-objc-gc --with-cloog --enable-cloog-backend=ppl --disable-cloog-version-check --disable-ppl-version-check --enable-multiarch --e
nable-multilib --disable-sjlj-exceptions --with-arch=armv5t --with-float=soft --disable-werror --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-l
inux-gnueabi --program-prefix=arm-linux-gnueabi- --includedir=/usr/arm-linux-gnueabi/include
Thread model: posix
gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-12ubuntu1)
COLLECT_GCC_OPTIONS='-o' 'artifacts/MyApp' '-Wall' '-D' '_REENTRANT' '-I' '/home/gregmac/libmono-armel/usr/include/mono-2.0' '-L/home/gregmac/libmono-armel/usr/lib' '-v' '-march=armv5t' '-mfloat-abi=soft' '-mtls-dialect=gnu'
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/cc1 -quiet -v -I /home/gregmac/libmono-armel/usr/include/mono-2.0 -imultilib sf -imultiarch arm-linux-gnueabi -D _REENTRANT temp.c -quiet -dumpbase temp.c -march=armv5t -mfloat-abi=soft -mtls-dialect=gnu -auxbase temp -Wall -version -fstack-protector -o /tmp/cchyLX23.s
GNU C (Ubuntu/Linaro 4.7.3-12ubuntu1) version 4.7.3 (arm-linux-gnueabi)
compiled by GNU C version 4.8.2, GMP version 5.1.3, MPFR version 3.1.2-p3, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/arm-linux-gnueabi"
ignoring nonexistent directory "/usr/include/arm-linux-gnueabi"
#include "..." search starts here:
#include <...> search starts here:
/home/gregmac/libmono-armel/usr/include/mono-2.0
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/include
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/include-fixed
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/include
/usr/include
End of search list.
GNU C (Ubuntu/Linaro 4.7.3-12ubuntu1) version 4.7.3 (arm-linux-gnueabi)
compiled by GNU C version 4.8.2, GMP version 5.1.3, MPFR version 3.1.2-p3, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 550509f4ff92bab4626b84fc11f267f2
temp.c: In function ‘install_dll_config_files’:
temp.c:59:2: warning: pointer targets in passing argument 2 of ‘mono_register_config_for_assembly’ differ in signedness [-Wpointer-sign]
In file included from temp.c:2:0:
/home/gregmac/libmono-armel/usr/include/mono-2.0/mono/metadata/assembly.h:102:24: note: expected ‘const char *’ but argument is of type ‘const unsigned char *’
COLLECT_GCC_OPTIONS='-o' 'artifacts/MyApp' '-Wall' '-D' '_REENTRANT' '-I' '/home/gregmac/libmono-armel/usr/include/mono-2.0' '-L/home/gregmac/libmono-armel/usr/lib' '-v' '-march=armv5t' '-mfloat-abi=soft' '-mtls-dialect=gnu'
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/bin/as -v -I /home/gregmac/libmono-armel/usr/include/mono-2.0 -march=armv5t -mfloat-abi=soft -meabi=5 -o /tmp/ccbJ6Gk5.o /tmp/cchyLX23.s
GNU assembler version 2.24 (arm-linux-gnueabi) using BFD version (GNU Binutils for Ubuntu) 2.24
COMPILER_PATH=/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/:/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/:/usr/lib/gcc-cross/arm-linux-gnueabi/:/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/:/usr/lib/gcc-cross/arm-linux-gnueabi/:/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/bin/
LIBRARY_PATH=/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/lib/../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/:/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/lib/:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-o' 'artifacts/MyApp' '-Wall' '-D' '_REENTRANT' '-I' '/home/gregmac/libmono-armel/usr/include/mono-2.0' '-L/home/gregmac/libmono-armel/usr/lib' '-v' '-march=armv5t' '-mfloat-abi=soft' '-mtls-dialect=gnu'
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/collect2 --sysroot=/ --build-id --eh-frame-hdr -dynamic-linker /lib/ld-linux.so.3 -X --hash-style=gnu --as-needed -m armelf_linux_eabi -z relro -o artifacts/MyApp /usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/lib/../lib/crt1.o /usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/lib/../lib/crti.o /usr/lib/gcc-cross/arm-linux-gnueabi/4.7/crtbegin.o -L/home/gregmac/libmono-armel/usr/lib -L/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/lib/../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc-cross/arm-linux-gnueabi/4.7 -L/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/lib /tmp/ccbJ6Gk5.o -Bstatic -lmono-2.0 -Bdynamic -lm -lrt -ldl -lpthread temp.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc-cross/arm-linux-gnueabi/4.7/crtend.o /usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/lib/../lib/crtn.o
/usr/lib/../lib/libmono-2.0.a: error adding symbols: File format not recognized
collect2: error: ld returned 1 exit status
I've also tried the same command but without --static, and get the same error, but about the .so instead of .a file:
/usr/lib/pkgconfig/../../lib/libmono-2.0.so: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
Am I missing something obvious here? Why is gcc still looking in /usr/lib/ instead of /home/gregmac/libmono-armel/usr/lib? Is there some other environment variable I should be setting so the original mkbundle command can invoke this correctly?

g++ undefined reference to `main'

I have a gcc 5.2.0 configured as follows :
Using built-in specs.
COLLECT_GCC=gcc-5.2.0
COLLECT_LTO_WRAPPER=/usr/local/lvm/gcc-5.2.0/libexec/gcc/x86_64-unknown-linux-gnu/5.2.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../configure --prefix=/usr/local/lvm/gcc-5.2.0 --enable-checking=release --with-gmp=/usr/local/lvm/gmp-6.0.0 --with-mpfr=/usr/local/lvm/mpfr-3.1.2 --with-mpc=/usr/local/lvm/mpc-1.0.3 --enable-languages=c,c++,fortran,objc,obj-c++ --with-isl=/usr/local/lvm/isl-0.14 --with-cloog=/usr/local/lvm/cloog-0.18.4 --program-suffix=-5.2.0
Thread model: posix
gcc version 5.2.0 (GCC)
and g++ :
Using built-in specs.
COLLECT_GCC=g++-5.2.0
COLLECT_LTO_WRAPPER=/usr/local/lvm/gcc-5.2.0/libexec/gcc/x86_64-unknown-linux-gnu/5.2.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../configure --prefix=/usr/local/lvm/gcc-5.2.0 --enable-checking=release --with-gmp=/usr/local/lvm/gmp-6.0.0 --with-mpfr=/usr/local/lvm/mpfr-3.1.2 --with-mpc=/usr/local/lvm/mpc-1.0.3 --enable-languages=c,c++,fortran,objc,obj-c++ --with-isl=/usr/local/lvm/isl-0.14 --with-cloog=/usr/local/lvm/cloog-0.18.4 --program-suffix=-5.2.0
Thread model: posix
gcc version 5.2.0 (GCC)
I have the following simple c++ code in tmp2.cpp file :
extern "C" {
double mysum(double x, double y)
{
return x+y;
}
}
that I am trying to compile into a dynamic library (.so) as follows :
export LD_LIBRARY_PATH=/usr/local/lvm/gmp-6.0.0:/usr/local/lvm/mpfr-3.1.2:/usr/local/lvm/mpc-1.0.3:/usr/local/lvm/cloog-0.18.4:/usr/local/lvm/isl-0.14/lib:/usr/local/lvm/gcc-5.2.0/lib64
export PATH=/usr/local/lvm/gcc-5.2.0/bin/:$PATH
g++-5.2.0 -m32 -Wall -g -c ./tmp2.cpp
g++-5.2.0 -m32 -dynamiclib ./tmp2.o -o ./tmp2.so
and the last command gives me the following error :
/usr/lib/../lib32/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
The detail output thx to -v can be found in a gist here.
I am quite new to gcc/g++ and don't really get what is going on. What's happened ?
You should use -shared option of g++ for creating a shared object.
g++-5.2.0 -m32 -shared -dynamiclib ./tmp2.o -o ./tmp2.so

Does the order in which libraries appear on the gcc command line matter?

I always thought that libraries had to be listed after any object files that depended on them, but given this simple program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
int main(int argc, char **argv) {
double res;
res = acos(2);
printf("res = %f\n", res);
return 0;
}
If I build it without linking in libm, it fails as expected:
$ gcc -o mathtest mathtest.c
/tmp/cc9x6HZA.o: In function `main':
mathtest.c:(.text+0x23): undefined reference to `acos'
collect2: error: ld returned 1 exit status
But I can list -lm either before or after the source file and it links successfully:
gcc -o mathtest -lm mathtest.c
gcc -o mathtest mathtest.c -lm
And I get the same behavior if I compile the source to an object file first and then link it as above.
Did this behavior change at some point? Or was it always like this, and I was just confused?
I confirm the unexpected link-order behaviour that you observe with gcc 5.1 and
also that I have the traditional behaviour with gcc 4.9.2. I would infer that this
novelty comes in with gcc 5.x, and that your toolchain is gcc 5.x. Possibly it
is a distro-specific anomaly of the toolchain build. My toolchain is as per ubuntu 14.04.
The novel behaviour only affects dynamic libraries. I can see what is causing it
if I link in verbose mode (-v) with gcc 4.9.2 and also with gcc 5.1, placing -lm before it is needed,
and examine the differences in the verbose output.
From gcc 4.9.2 I have (with artifical line-wrapping):
/usr/lib/gcc/x86_64-linux-gnu/4.9/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/4.9/liblto_plugin.so
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper -plugin-opt=-fresolution=/tmp/ccsHNLNB.res
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id
--eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker
/lib64/ld-linux-x86-64.so.2 -z relro -o mathtest
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.9
-L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu
-L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib -L/lib/x86_64-linux-gnu
-L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib
-L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. -lm mathtest.o -lgcc --as-needed
-lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed
/usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crtn.o
And from gcc 5.1 I have:
/usr/lib/gcc/x86_64-linux-gnu/5/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/5/liblto_plugin.so
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper -plugin-opt=-fresolution=/tmp/cc5hI8vd.res
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id
--eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker
/lib64/ld-linux-x86-64.so.2 -z relro -o mathtest
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/5
-L/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu
-L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib -L/lib/x86_64-linux-gnu
-L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib
-L/usr/lib/gcc/x86_64-linux-gnu/5/../../.. -lm mathtest.o -lgcc --as-needed
-lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed
/usr/lib/gcc/x86_64-linux-gnu/5/crtend.o
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o
The relevant difference is that the gcc 4.9.2 linkage passes the option --as-needed
in 4 places whereas the gcc 5.1 linkage passes it in only 3. gcc 4.9.2 passes --as-needed
for the first time at the the 5th quoted "line":
--eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker
gcc 5.1 does not pass it there. Thereafter, both linkages pass this option at
the same 3 places, starting as the 13th "line":
-L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. -lm mathtest.o -lgcc --as-needed
This means that for gcc 4.9.2, the library option -lm on "line" 13 falls within the
scope of the first --as-needed. For gcc 5.1 it does not. The effect of this option
is to inform the linker that the dynamic library libm (or any dynamic library that
is encountered in the option's scope) shall be linked only if it is encountered
at a point in the linkage at which it can satisfy some unresolved symbols. In the
absence of this option, at a given point in the linkage, a dynamic library is by
default deemed to be needed for the linkage regardless of whether there are yet any
unresolved symbols that it can satisfy. See the documentation of --as-needed
Thus the gcc 4.9.2 linkage will not link libm, although it appears on the
commandline, because at the point where it appears - before mathtest.o - --as-needed is
in force and there are as yet no unresolved references that libm satisfies. The gcc 5.1
linkage will link libm because it appears on the commandline at a point where --as-needed
is not in force.

Resources