I am currently trying to implement some 3rd party code (program A) within another 3rd party program (program B). Unfortunately, it seems like some COMMON blocks and subroutines share names between the two codes. This is not detected by the compiler (I suspect because the compilation process involves many different files and creating a shared object), but the program crashes when accessing certain common blocks / subroutines with very general names (e.g. BASIS, JACOBIAN), and renaming them alleviates the problem. However, renaming all common blocks and subroutines within program A is not feasible because of its size.
At the moment, I have two seperate directories of code. I compile both seperately with the intel compiler into .o files and then create a shared object from both:
ifort -c -fPIC -fp-model precise codeA.f
ifort -c -fPIC -fp-model precise codeB.f
ifort -c -fPIC -fp-model precise code_coupling.F90
ld -shared -o library.so codeA.o codeB.o code_coupling.o
The code in code_coupling.F90 is for coupling both codes and it is called within codeB.f, which I cannot change.
Is there a possibility to compile codeA.f with some additional compiler flags so that the names of the COMMON blocks and subroutines don't interfere with each other?
Is there some other way I can prevent the names from interfering with each other?
One (a little bit hacky) solution I have discovered is to compile codeA.f with the flag -assume nounderscore, and rename the functions that need to be called in code_coupling.F90 manually with a trailing underscore:
ifort -c -fPIC -fp-model precise -assume nounderscore codeA.f
ifort -c -fPIC -fp-model precise codeB.f
ifort -c -fPIC -fp-model precise code_coupling.F90
ld -shared -o library.so codeA.o codeB.o code_coupling.o
Rename the subroutine codeA_subroutine within codeA.f to codeA_subroutine_.
Related
I am creating a gcc shared library having a static library dependency.
I compile the parts for static library as following:
gcc -c -m64 -O2 -fPIC -std=c99 -Wall ms*.c //there are 10 C files, no warnings
Next I create a static library with:
ar rc static_lib.a ms*.o
Next I compile the parts for my program as following:
g++ -c -m64 -O2 -fPIC -std=c++14 -Wall ab*.cpp //there are 5 C++ files, just -Wunused-variable warnings
Then I create a shared library as following:
g++ -shared -g -Wall ab*.o static_lib.a -o shared_lib.so
in the normal case, this shared_lib.so will be called by a Ruby program using a foreign function interface. There is no problem if I do it on ubuntu or mac(.dylib), but if I try this on debian stretch I get an error related to the static library as if the configurations are not set properly. If I run the application without foreign function interface, such as creating a tester and running with the cpp file main function as following:
> g++ -o library_test ab*.o static_lib.a
> ./library_test
There is no problem!
My question is what kind of configuration for creating a shared library may be missing here to not get that undesirable behaviour. Especially on debian stretch 9.5!
Or is there a way that I can understand if there is a problem in the shared library.
From the comments, you indicate the problem is with a #define. Those are preprocessor directives. Libraries are for the linker.
You might be confused because g++ does include the preprocessor phase, and might call the linker depending on the requested output. Still, g++ follows the C++ language rules.
I am using mingw 64 bit with cygwin.
I know that if I compile using
x86_64-w64-mingw32-g++.exe -std=c++11 hello.cpp
the output .exe does not run unless the library path to libstdc++ and other libraries is specified in the Path environment variable.
An alternative is to link statically
x86_64-w64-mingw32-g++.exe -std=c++11 hello.cpp -static-libgcc -Wl,-Bstatic -lstdc++ -lpthread
Since I want a single .exe that I can easily copy on different machines, the second solution is better for me. My only problem is that, since I link statically, even for a simple helloworld program, the size of the executable rises to more than 10 Mb. So my question is: is it possible to link statically only the library parts that are actually used by the program?
The binutils linker on Windows, ld, does not support the --gc-sections argument properly, which in combination with compiler flags -ffunction-sections and -fdata-sections, allow the linker to throw away blocks of unused code.
You are straight out of luck. The only thing you can do is the usual: strip the executable (by running the strip command on it after it is linked) and compile your code optimising for size with -Os.
Keeping in mind these options do not work on Windows (which for the purpose of this answer, includes the Cygwin platform), this is generally how you can do this:
g++ -c -Os -ffunction-sections -fdata-sections some_file.cpp -o some_file.o
g++ -c -Os -ffunction-sections -fdata-sections main.cpp -o main.o
g++ -Wl,--gc-sections main.o some_file.p -o my_executable
I have a vexing C++ problem. I've got a huge, complex wedge of code which is compiled into a Linux shared object. When it goes through one specific code path, it segfaults. (Basically one of the STL iterators seems to point a few bytes to the side of where it should.) But, if I #include all the code into one giant source file and compile it into a stand-alone program, everything works perfectly.
How do I even begin to debug this? The problem appears to not be a source-level problem, but (I guess?) some kind of weird linker issue. I'm completely lost. (I thought STL was all compile-time stuff...)
In case it matters, the SO is compiled like so:
g++ -m64 -c -D_CONSOLE -D__UNICODE__ -fPIC -O0 -g -D_DEBUG -D_GLIBCXX_DEBUG <name> -o <name>.o
g++ -m64 -shared -o MangoLib.so <objects...>
The stand-alone consists of a small driver program with a bunch of #include directives, built like so:
g++ -m64 -fPIC -O0 -g -D_DEBUG -D_GLIBCXX_DEBUG Test.cpp -o Test
I don't think I did anything wrong here... but the SO segfaults every single time, so I guess I did? I don't know what to do now.
I would start to check the usage of global variables and static initializers. The order of these things happening is not well defined AFAIK. Every global variable or static initializer that more complicated than "just fill this memory with 0 bits" should be suspect. Several static initializers referencing each other is basically a no go.
As per official instructions, to compile a program with debugging support you can run
g++ -std=c++11 -O0 -g -c -o program1.o program1.cpp
Now to do the same with a C program, it's just:
gcc -O0 -g -c -o program2.o program2.c
In order to link both types together, I could use:
g++ --std=c++11 -O0 -g -o program program.o program2.o
Then, to debug:
gdb program
gdb > run <PARAMS>
It worked completely after several attempts at tinkering with the compiler options (the above options are for a working version). In some cases the C symbols would load, but the C++ symbols would not.
Can someone shed some light as to what the recommended options are to enable debugging for non-trivial examples that mix several compiled languages? All of the documentation only refers to trivial examples.
Note that if you use just the -g option then the compiler will use operating system's native format, which can vary. You can explicitly specify the format instead, using other -g... varieties (for example -gdwarf-3 or -g-stabs). This allows you to guarantee that your object files will all have a consistent debug format, irrespective of where they were built.
You can also disable gdb-only extensions by using this approach, should you wish to use other debuggers. See this for details.
In each compilation and linking step, add the -g option to the compiler flags. -O0 is recommended too for debug builds so you don't get the compiler optimizing functions away. Being inconsistent may result in no debug symbols or partial debug symbols.
I'm trying to build a self contained executable, which I can run on any/most linux host.
I know I can do that with containers, but for now I'm trying to just statically link my exe.
I compile with:
g++ -std=c++1y -fopenmp -Ofast -g -march=x86-64 -mtune=generic -m64 -c <source>.cpp -MMD -MP -o <object>.o
And link with:
g++ -std=c++1y -fopenmp -Ofast -g -march=x86-64 -mtune=generic -m64 <list of object files> <list of absolute path to static libs .a> -lpthread -static-libgcc -static-libstdc++ -o exe
It used to work just fine, but I just discovered it now breaks on some hosts with
error while loading shared libraries: libmvec.so.1: cannot open shared object file: No such file or directory
I don't know if it's something in the code or system libraries update. I have tried (to no avail):
removing -fopenmp
adding -lmvec -lm to the linker
My exe is indeed statically linked: ldd exe says not a dynamic executable. But it insists on loading libmvec.so at runtime: strace exe says:
execv
a bunch of mmap
open(ld-linux-x86-64.so), read it and close it
open(ld.so.cache), stat, mmap, and close it
open(libpthread.so), read, stat, mmap and close it
open(libmvec.so) => fail on hosts where it doesn't exist
[...]
As I understand libmvec is an extension of libm, dealing with x86 vectorization, used by OpenMP.
So basically, I'm asking if there is a way to make it work statically - I see at least 3 solutions:
disable its use - but that would probably mean performance loss, plus it is used even when I disable OpenMP
statically link it, and somehow explain to the runtime that it then doesn't have to dynamically link to it since it's already linked.
make it optional, i.e. dynamically select a slower code path if it's not available. This sounds complex but could in theory be possible.