gcc and g++ linker - gcc

I am not yet at the point of linking, but as soon as my project compiles I will face this issue:
I have one c.o object file compiled by gcc from pure C code
I have one d.o object file compiled by g++ with extern"C" for C compatibility of functions that needs to be callable by the c.o
I have a lot of *.o object files compiled by g++ from pure C++ code that are called by the d.o part
How should I link the whole as a one block shared library? Using gcc or g++?
This library will then be used by Apache2 as a C module.

Using g++ you can link both types of .o files. Only gcc will fail.

Related

Compiling OpenMP to WebAssembly

I am trying to compile a multi threaded application to WebAssembly. The application uses OpenMP for multithreading.
To compile I am using the Emscripten framework.
I have already downloaded the source files for OpenMP and compiled it for my host machine using make. With the following command I can get it to link with a simple demo application on my machine:
g++ -Wall -Werror -pedantic main.o -o main.x /$PATH_TO_OPENMP/build/runtime/src/libgomp.a -pthread -lstdc++ -Wl,--no-as-needed -ldl
I then tried to compile OpenMP to the llvm bytecode format used by Emscripten. To do so I tried to run 'emmake make', so that the emscripten framework executes the OpenMP makefiles with a suitable compiler. As emscripten does not like shared object files I compiled it to static library .a files.
This works and actually gives me object files to which I can link.
I then wanted to link my demo application with the following command
em++ -Wall -Werror -pedantic main.o -o main.html /home/main/data/Programming/openMP/openmp_web/build/runtime/src/libgomp.a -pthread -lstdc++ -Wl,--no-as-needed -ldl
But I get these warnings, that it couldn't link to OpenMP files:
shared:WARNING: object /tmp/emscripten_temp_ONa0eU_archive_contents/kmp_atomic.cpp.o is not a valid object file for emscripten, cannot link
.
.
shared:WARNING: object /tmp/emscripten_temp_ONa0eU_archive_contents/kmp_str.cpp.o is not a valid object file for emscripten, cannot link
shared:WARNING: object /tmp/emscripten_temp_ONa0eU_archive_contents
So I figured I must have compiled OpenMP with the wrong compiler. I then tried to change the compiler when building the library by using the following commands:
cmake -DCMAKE_C_COMPILER=emcc -DCMAKE_CXX_COMPILER=em++ -DLIBOMP_LIB_TYPE=normal -DLIBOMP_ENABLE_SHARED=OFF -DCMAKE_BUILD_TYPE=Release -DLIBOMP_ARCH=x86_64 OPENMP_STANDALONE_BUILD=1 ..
emmake make
But this just gives strange errors on some missing system variables
/home/main/data/Programming/openMP/openmp_web/runtime/src/kmp_platform.h:82:2: error: Unknown OS
/home/main/data/Programming/openMP/openmp_web/runtime/src/kmp_platform.h:203:2: error: Unknown or unsupported architecture
In file included from /home/main/data/Programming/openMP/openmp_web/runtime/src/kmp_alloc.cpp:13:
In file included from /home/main/data/Programming/openMP/openmp_web/runtime/src/kmp.h:77:
/home/main/data/Programming/openMP/openmp_web/runtime/src/kmp_os.h:171:2: error: "Can't determine size_t printf format specifier."
Does anyone have an idea on what I could do differently?

Can compile and link use different compilers when cross-compile?

I'd like to know if I can use different compilers for compile and link.
For example ,I have two files ,a.c and b.c,
I use clang to compile a.c and b.c:
clang -c a.c -o a.o
clang -c b.c -o b.o
and then use gcc to link the two .o file as a so library:
gcc -lm -lz -shared a.o b.o -o libad.so
I generate the so file successfully,but the app will crash when using this library.
Update:
More detailed information: What I have done is cross-compile , and target platform is armv7a.I use android-NDK and compile the codes on MAC.So the gcc is arm-linux-androideabi-gcc and clang is arm-linux-androideabi-clang.
Unless special flags are specified at link time (-fuse-ld=xxx[1][2]), both clang and gcc call the default system linker (which on macOS is lld and will probably be gold on linux). So running the second statement with either gcc or clang will produce the same linked binary.
[1] https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
[2] http://clang-developers.42468.n3.nabble.com/LLD-to-be-the-default-linker-in-Clang-td4053949.html

Non-GOT style relocation for executable in GCC

In GCC, if I compile something into a shared library with GCC with g++ -shared func.cpp -o libfunc.so -fPIC, internal function calls to global symbols go through GOT in this generated shared library file. But if I compile with g++ func.cpp -o libfunc.so -mcmodel=large, it will not generate GOT but instead relocate by patching with R_X86_64_64 style relocation directly.
I want this behavior for executables as well. If I compile an executable with g++ main.cpp libfunc.so -o a.out, GCC will generate GOT for any function call from main.cpp to one defined in libfunc.so. I don't want this behavior. I want R_X86_64_64 style relocation. How can I achieve that?
Executables are compiled with -fPIE by default in modern distros for security reasons. To get old behavior add -no-pie to CFLAGS/CXXFLAGS.

CMake: correctly linking system library using gcc

I have a static libary mylib that depends on the math library.
If I first link mylib with math and then to my executable it works:
add_executable(myapp main.c)
target_link_libraries(mylib m)
target_link_libraries(myapp mylib)
But if I do the linking directly with the executable it fails when using gcc (with clang it works!)
add_executable(myapp main.c)
target_link_libraries(myapp m mylib)
Why does this make any difference?
I thought that it is anyway not possible to link libraries together?
When using cmake's target_link_libraries it does not mean you will link anything. It rather will create a dependency between a target and a library of type/action link.
I guess that the actually build line of the first example will result in something like that:
gcc -o myapp myapp.o -lmylib -lm
and the second one
gcc -o myapp myapp.o -lm -lmylib
. If mylib has references to m the second example (might) not link.
Try to run make VERBOSE=1 and study the command-line of the link-process to really understand what's happening. The linker of clang is maybe intelligent and waits for all calls to be linked before actually dropping a library during the link-process.
When using target_link_libraries it matters in which order you specify linked libraries.
This does not work when using gcc (at least in v4.6.3):
target_link_libraries(myapp m mylib)
while this works:
target_link_libraries(myapp mylib m)
So all libraries mylib depends on have to come after mylib.
If you track down the actual linker invocation with make VERBOSE=1 you will find this for the broken example:
gcc main.c.o -o luatest -rdynamic -lm mylib.a
and this for the working one:
gcc main.c.o -o luatest -rdynamic mylib.a -lm
Invoking clang with the exact same parameters works in both cases!
So #PatrickB seems to be right:
The linker of clang is maybe intelligent and waits for all calls to be
linked before actually dropping a library during the link-process.

fail when creating shared library with libstdc++ statically linked

using gcc 4.5.1 in a 64bit x86 machine,I first create a.o as following:
g++ -fPIC -c a.cc -o a.o
then try to create liba.so as following:
g++ -static-libstdc++ -shared -W1,-soname,liba.so -o liba.so.1.0.0 a.o
but failed, with the following information:
relocation R_X86_64_32S against `vtable for __gnu_cxx::stdio_filebuf >' can not be used when making a shared object; recompile with -fPIC
I try to recompile libstdc++ library,with -fPIC added,but it failed anyway
I would expect that the static libstdc++ library was not build with -fPIC, and therefore can't be linked into a shared library.
Theoretically you could put non-PIC compiled code into a dynamic library, but it wouldn't be sharable (each program using it would have to have its own copy) so it's often not implemented.
You're going to need to link against the shared C++ library, make your own library a static library, or else rebuild libstdc++ yourself and grab the .o files from the build directory.
There is a similar question about this topic on stackoverflow, which refers to an external site about static linking of libstdc++.

Resources