rstudio calls fortran subroutines - undefined symbol error - fortran

My apologies if this is a simple question for some people but I can't find the solution anywhere.
I am an RStudio beginner and I want to call specific routines of an open source fortran77 simulation program (there is also c and c++ code in it) from within RStudio.
The Fortran program is using Makefiles for compiling and it generates many .o object files (by the way, I am using Unix). I wrote a wrapper file in fortran which compiles together with the simulation program and it is supposed to be used by RStudio for calling the fortran routines. I generate the shared object file .so of that wrapper file and all works well if I have simple calculations in that wrapper file. I am following the same process as in this excellent post:
http://www.r-bloggers.com/fortran-and-r-speed-things-up/
I use dyn.load and .Fortran successfully and I get results back as long as I do not call subroutines that are located in another file (and correspond to other object files and other .so files). When I try to call another subroutine from within the wrapper subroutine I get the following error:
Error in dyn.load("rwrapper.so") :
unable to load shared object '/home/adminuser/ESP-rSource/src/esrubps/rwrapper.so':
/home/adminuser/ESP-rSource/src/esrubps/rwrapper.so: undefined symbol: runit_
runit (without underscore) is another subroutine that is located in another file and has another object file. I then tried to make a second shared object file for that runit subroutine and I also load it with dyn.load but it did not fix the problem. I am probably doing something wrong here but I do not know what. Do I need to convert all object files to .so shared object files and then use dyn.load to load each one of them (there are around 100 of .o files) or would the "wrapper/communication" file approach work? Is there a way to establish communication between the fortran program and RStudio? I am pasting my RStudio script here for information only (note that the 2nd dyn.load does not make a difference):
myrwrapper <- function(rrrandom) {
if (!is.loaded('rwrapper')) {
dyn.load("rwrapper.so")
}
if (!is.loaded('esru_lib')) {
dyn.load("./home/adminuser/ESP-rSource/src/lib/esru_lib.so")
}
retvals <- .Fortran("RXCHNGE",icomp = as.integer(2), rCOUPLEVAR = as.numeric(rrrandom))
return(retvals$rCOUPLEVAR)
}
An easy solution would have been to write/read a text file from both programs and exchange data through that file, however my understanding is that this would make the simulations really slow because of the need to open/close a file at almost every time step, and so I am trying to avoid such an approach.
Thank you for your help.

This was actually a lot easier than I thought. It was a novice mistake with the shared .so file. Problem solved when creating the shared file and linking it to two (or more) object files rather than one. For example if you have 1.F which calls 2.F and the respective 1.o and 2.o, you should include both files when creating the shared file as:
gfortran -shared -o 1plus2.so 1.o 2.o

Related

Calling executable from C++ and getting return value

I want to call a compiled C++ executable from another script and also need the value returned by the executable. Using system() doesn't return the function output and am not able to find any other alternative. Is this possible without having to write to a file and parsing from it?
I am working with 2 different libraries and want to use one of the libraries from another. So, I thought of doing it by creating the executable and calling it from the script of the other library. I also tried to compile both together by adding the header file directories of the other library during make but get this error ImportError: /.conda/envs/myenv/lib/python3.6/site-packages/hnswlib.cpython-36m-x86_64-linux-gnu.so: undefined symbol: gzopen64 which I am not able to understand how to fix.
You haven’t specified your OS, but if you’re on a Linux/UNIX environment you can use the standard POSIX function popen, which starts a program and gives you a file handle to the program’s input/output streams. You may find the full documentation for this function here: https://pubs.opengroup.org/onlinepubs/009695399/functions/popen.html

Using __gcov_flush within a library doesn't force the other modules to yield .gcda files

Lately I have been trying to use gcc/gcov to undertake code-coverage testing for a C++ project. The project consists of its main module and several .so libraries, which should all be taken into measurement.
I have compiled all the modules with --coverage parameter each with gcc and kept them where they were generated, together with corresponding .gcno tag files. After a normal execution and graceful exit the .gcda files could be properly generated.
The problem is, the program is supposed to be a services without interruption or termination, and it's not allowed to insert any customized code (like a signal handler) into the main module. As the solutions from the web suggest, I wrote a signal handler function in a standalone .so library, which invokes __gcov_flush on receiving SIGUSR1 signal to flush the runtime coverage counters to files.
However, it was observed that, while the __gcov_flush function is guaranteed to be properly invoked, only the .gcda file of the .so library is generated during runtime. It seems to me that __gcov_flush is in charge of flushing the data of the wrapper module but not the others. I wonder if this is how it is supposed to work, or is there some tricks I need to take care of to generate complete results?
I see two problems here.
If your executable loads several shared libraries it is quite hard
to get the functionality needed. The linker adds profiling code from
libgcov.a for every shared library and it is hard to call every
library's __gcov_flush() from one central place like signal handler
defined in yet another shared library.
The function __gcov_flush() function from libgcov.a is declared
with __attribute__ ((__visibility__ ("hidden")))
If you extract _gcov.o from the archive and run
objdump -t _gcov.o
you see something like
_gcov.o: file format elf32-littlearm
SYMBOL TABLE:
000014b4 g F .text 00000016 .hidden __gcov_flush
Linker doesn't export hidden symbols even if you ask it to do that
as it mentioned here or here
So I see two solutions for the second problem.
You may try to edit symbol table for _gcov.o in libgcov.a and
set visibility to "default" instead of "hidden". I didn't take
that way because I didn't find any good elf editor.
If you managed to do that make sure to update your link command so
it links this patched _gcov.o instead of default one from
libgcov.a. Basically, you need to remove --coverage option from
your linker flags for that.
You may create a wrapper for __gcov_flush() declare and export it
as it suggested in the links above. Call this wrapper from your
signal handler in the shared library.
I suggest you not to add profiling for the small signal handler
library - it is really unnecessary.

C++ compiling and linking

I found one question about compiling and linking in C++ and I don't know which answer is correct. It was discussed with my friends and opinions are divided. Here is a question:
In order to run program written in C++ language its source code is:
(A) compiled to machine code,
(B) compiled and linked to machine code
In my opinion the correct answer is A but I don't have any source to prove it.
Google, first hit.
Linkage is needed as well to create a standalone executable.
You need to link the code you have produced to make it into an executable file. For simple programs, the compiler does this for you, by calling the linker at the end of the compilation process.
The compiler proper simply translates C code to either assembler (classic C compiler) which is then assembled with an assembler or directly to machine code (many modern compilers). The machine code is usually produced as "object files", which are not "executable", because they refer to external units - such as when you call printf(). It is possible to write C code that is completely standalone, but you still typically need to combine more than one object file, and it certainly needs to be "formatted" to the right way to make an executable file - which is a different file-format than an object file [although typically fairly SIMILAR].
Compilation does nothing except creation of object files which means converting C/C++ source code to machine codes.
Linking process is the creation of executable file from multiple obj files. So for running an application/executable you have to also link it.
During compilation, compiler doesn't complain about non existing functions or broken functions, because it will assume it might be defined in another object (source code file). Linker verifies all functions and their existance, so if you have a broken function, you'll get error in linking process
Compiling: Takes input C/C++-code and produces machinecode (object file)
gcc –c MyProgram.c
Note that the object file does not contain all external references!
Linking: Combines object file with external references into an executable file
gcc MyProgram.o –o MyProgram
Note that no unresolved references!
Illustration:
Where libc.a is the standard C library and it's automatically linked into your programs by the gcc.
I've just noticed that your question was about c++, the same concept is in c++ too, if you understand this, you'll understand how it works in c++ too
strictly speaking. Answer A.
But for you to see the whole picture, lets say you have defined some function. Then the compiler writes the machine code code of that function at some address, and puts that address and the name of the function in the object ".o" file where the linker can find it. The linker then take this "machine code" and resolve the symbols as you might heard in some previous error.

Can i compile a c++ file within a c++ file execution without any extra programs or installations?

I was reading on Clang and Ch (c++ interpreters), but its not clear for me, is it possible to run a newly generated .cpp file without any installations? Because i need to run the final program on any pc...
ps. if yes, does anyone have a good example, where a .cpp file is being executed within c++ code?
This is probably impossible or at least very hard. You would have to include the whole compiler (including linker, assembler, optimizer, preprocessor, ...) inside your program and that would make it extremely big.
One way of doing this is with Clang (as you already noted), there is even a demo project called "Clang interpreter" in the source: http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/clang-interpreter/
However I once tried to compile this "beast" into my program and gave up halfway, because the file size of the result binary (or binaries with external libraries) gets into tens of megabytes (maybe even a hundred).
My suggestion is to either produce a different script (e.g. bash/sh script, which you could execute on any unix machine) that can be interpreted easily.
As far as I know, it is impossible, because compilation process of a CPP file is like this-
Preprocessing: the preprocessor takes a C++ source code file and deals with the #includes, #defines and other preprocessor directives. The output of this step is a "pure" C++ file without pre-processor directives.
Compilation: the compiler takes the pre-processor's output and produces an object file from it.
Linking: the linker takes the object files produced by the compiler and produces either a library or an executable file.
So, there should be intermediate files and executable files.
More can be found here-
https://stackoverflow.com/a/6264256/7725220
Kind of depends on what you mean by "installations".
Yes you can distribute your program with a full compiler, compile the source code and then execute the final result (all from the original exe).

What is *.o file?

I'm compiling own project. And it halted by this error:
LINK||fatal error LNK1181: cannot open
input file
'obj\win\release\src\lua\bindings.o'|
Compiling using Code::Blocks with VS 2005/2008 compiler under win7.
There are also lot of another empty directories where *.o files are missing.
What do they do?
A file ending in .o is an object file. The compiler creates an object file for each source file, before linking them together, into the final executable.
You've gotten some answers, and most of them are correct, but miss what (I think) is probably the point here.
My guess is that you have a makefile you're trying to use to create an executable. In case you're not familiar with them, makefiles list dependencies between files. For a really simple case, it might have something like:
myprogram.exe: myprogram.o
$(CC) -o myprogram.exe myprogram.o
myprogram.o: myprogram.cpp
$(CC) -c myprogram.cpp
The first line says that myprogram.exe depends on myprogram.o. The second line tells how to create myprogram.exe from myprogram.o. The third and fourth lines say myprogram.o depends on myprogram.cpp, and how to create myprogram.o from myprogram.cpp` respectively.
My guess is that in your case, you have a makefile like the one above that was created for gcc. The problem you're running into is that you're using it with MS VC instead of gcc. As it happens, MS VC uses ".obj" as the extension for its object files instead of ".o".
That means when make (or its equivalent built into the IDE in your case) tries to build the program, it looks at those lines to try to figure out how to build myprogram.exe. To do that, it sees that it needs to build myprogram.o, so it looks for the rule that tells it how to build myprogram.o. That says it should compile the .cpp file, so it does that.
Then things break down -- the VC++ compiler produces myprogram.obj instead of myprogram.o as the object file, so when it tries to go to the next step to produce myprogram.exe from myprogram.o, it finds that its attempt at creating myprogram.o simply failed. It did what the rule said to do, but that didn't produce myprogram.o as promised. It doesn't know what to do, so it quits and give you an error message.
The cure for that specific problem is probably pretty simple: edit the make file so all the object files have an extension of .obj instead of .o. There's room for a lot of question whether that will fix everything though -- that may be all you need, or it may simply lead to other (probably more difficult) problems.
A .o object file file (also .obj on Windows) contains compiled object code (that is, machine code produced by your C or C++ compiler), together with the names of the functions and other objects the file contains. Object files are processed by the linker to produce the final executable. If your build process has not produced these files, there is probably something wrong with your makefile/project files.
It is important to note that object files are assembled to binary code in a format that is relocatable. This is a form which allows the assembled code to be loaded anywhere into memory for use with other programs by a linker.
Instructions that refer to labels will not yet have an address assigned for these labels in the .o file.
These labels will be written as '0' and the assembler creates a relocation record for these unknown addresses. When the file is linked and output to an executable the unknown addresses are resolved and the program can be executed.
You can use the nm tool on an object file to list the symbols defined in a .o file.
Ink-Jet is right. More specifically, an .o (.obj) -- or object file is a single source file compiled in to machine code (I'm not sure if the "machine code" is the same or similar to an executable machine code). Ultimately, it's an intermediate between an executable program and plain-text source file.
The linker uses the o files to assemble the file executable.
Wikipedia may have more detailed information. I'm not sure how much info you'd like or need.