I am currently working on a project involving Fortran and R, but the emphasis lies on the latter and not much coding is needed on the Fortran side. The aim is to create a dynamic library/shared object containing a Fortran subroutine to be loaded into R where it can be called.
Some background:
I have been given a Fortran file which contains a module called FitterModule.f95 and set up my Fortran subroutine in another Fortran file called zyzzyva.f95. The subroutine is to utilise a function (al00) that is within the module itself, and the code is as shown below:
subroutine al00wrapper(ca, d, answer)
use FitterModule
real :: ca, d, answer
answer = al00(ca, d)
return
end subroutine
After which, I proceeded to Macbook terminal to create the shared library, with the following commands:
gfortran -c zyzzyva.f95
gfortran -shared -o zyzzyva.so zyzzyva.o
gfortran -shared -o zyzzyva.so zyzzyva.o FitterModule.o
gfortran -shared -o zyzzyva.so FitterModule.o zyzzyva.o
However, each time I was given the following result:
Undefined symbols for architecture x86_64:
"_al00_", referenced from:
_al00wrapper_ in zyzzyva.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
I have looked through posts that could have been similar to mine, but I am unable to figure out what is wrong still.
I am definitely very new to this and I appreciate if I could get some advice to resolve this issue, thank you!
Related
I have a header file included in the main but when I compile the main, I have an error saying that the linker failed.
I tried to find the object files but I cannot find them.
I think the problem may come from my machine. I am kind of a beginner so I don't know how to solve this
When I try compiling my code I get this error:
Undefined symbols for architecture x86_64:
"_intClassic", referenced from:
_main in main-53b7e4.o
"_intQuadrature", referenced from:
_main in main-53b7e4.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
#zwol #JonathanLeffer I have 3 files in my project main.c, integral.h
and integral.c. integral.c contains the code of the functions
intClassic and intQuadrature that allow me to calculate different
types of integral. In integral.h I declared the functions and
structures I use. Finally in the main I included integral.h .
Also $ gcc -o output file1.o file2.o can this command help me ?
In the same directory as your files, try running the command
gcc main.c integral.c -o integral
This should take the 2 files and compile them into a program called ./integral
I am trying to compile a very simple C/C++ program to call Julia functions. Following the instructions that you find on the Julia documentation page, I set up my link path to /Users/william.calhoun/Desktop/romeo/lib/julia looking for libjulia.so and I set up my include path to /Users/william.calhoun/Desktop/romeo/include/julia looking for julia.h
I have a C file called test.c which runs the following code:
#include <stdio.h>
#include "skeleton.h"
#include <julia.h>
int main(int argc, const char * argv[]) {
jl_init(NULL);
/* run julia commands */
jl_eval_string("print(sqrt(2.0))");
/* strongly recommended: notify julia that the
program is about to terminate. this allows
julia time to cleanup pending write requests
and run all finalizers
*/
jl_atexit_hook();
return 0;
}
However this yields the following error:
Undefined symbols for architecture x86_64:
"_jl_atexit_hook", referenced from:
_main in test.o
"_jl_eval_string", referenced from:
_main in test.o
"_jl_init", referenced from:
_main in test.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I am not doing anything other than calling functions defined properly (hopefully) within the Julia source code. What am I doing wrong? This seems like the simplest example and I can't figure it out.
Any help would be much appreciated!
Linking to libjulia (libjulia.dynlib on OS/X)
This error is a result of not linking to libjulia, as all of the symbols (_jl_atexit_hook, _jl_eval_string, _jl_init) are located in that library. Broadly, for all 3 of the following platforms (Windows, OS/X, Linux), the approach is similar, and though the location of the libjulia library is different on Windows than the other 2 this stackoverflow question is applicable. Also to be completely accurate, on OS/X, dynamic libraries have the extension .dynlib not .so as they do on Linux.
The link step
For simplicity, assuming you've compiled to object code (there is a file called embed.o), here's the link step.
cc -o embed embed.o -L/Users/william.calhoun/Desktop/romeo/lib/julia -Wl,-rpath,/Users/william.calhoun/Desktop/romeo/lib/julia -ljulia
There are 2 important things to note here.
Linking using -ljulia will allow the linker to resolve all of the above symbols.
Since this is a dynamic library and that dynamic library is located in a non standard location (e.g. not in /usr/lib), the dynamic linker will not be able to find it at run time unless you give it special instructions on how to find it. The -rpath directive causes the linker to insert the path /Users/william.calhoun/Desktop/romeo/lib/juliainto the list of paths to search.
I am trying to create a dynamic library which is meant to be linked and loaded into a host environment at runtime (e.g. similar to how class loading works in Java). As such, I want the dynamic library to be left with a few "dangling" references, which I expect it to pick up from its host environment when it is loaded into that environment.
My problem is that I cannot figure out how to create the dynamic library without explicitly linking it to existing symbols. I am hoping to produce a dynamic library that does not depend on a specific host executable (or host library), rather one that is able to be loaded (e.g. by dlopen) in any host as long as the host makes a couple symbols available for use.
Right now, any linking command I've tried results in a complaint of missing symbols. I'd like it to allow symbols to be missing (ideally, just particularly specified symbols).
For example, here's a transcript with the error on OS X:
$ cat frotz.c
void blort(void);
void run(void) {
blort();
}
$ cc -c -o frotz.o frotz.c
$ cc -dynamiclib -o libfrotz.dylib frotz.o
Undefined symbols for architecture x86_64:
"_blort", referenced from:
_run in frotz.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
If I do the same thing using a GNU toolchain (on Linux), it helpfully tells me:
$ gcc -shared -o libfrotz.so frotz.o
/usr/bin/ld: frotz.o: relocation R_X86_64_PC32 against undefined symbol `blort'
can not be used when making a shared object; recompile with -fPIC
and indeed, adding -fPIC to the C compile command seems to fix the problem in that environment. However, it doesn't seem to have any effect in OS X.
All the other dynamic-linking questions I could find on SO seem to be about the more usual arrangement of libraries, where a library is being built to be linked into an executable before that executable runs, rather than the other way around. The closest related question I found was this:
Can an executable be linked to a dynamic library after its built?
which unfortunately has very little info, none of it relevant to the question I'm asking here.
UPDATE: I distilled the info from the answer along with everything else I'd figured
out, and put together this example:
https://github.com/danfuzz/dl-example
As far as my knowledge goes, you want to use weak linkage:
// mark function as weakly-linked
extern void foo() __attribute__((weak));
// inform the linker about that too
clang -dynamiclib -o bar.dylib bar.o -flat_namespace -undefined dynamic_lookup
If a weak function can be resolved at runtime, it will then be resolved. If it can't, it will be NULL, instead of generating a runtime (or, obviously, link-time) error.
I am working on a project written in a mix of Fortran 90 and Fortran 77 and now need to link the LAPACK/BLAS libraries, from netlib.org, to the project, all in a Linux environment. I used the gfortran compiler flags OPTS = -O2 -fPIC -m64 in the given Makefile, and then made it using
make blaslib
make
And it finished normally, or at least I think so.
Then, I copied the files in /usr/local/lib and /usr/local/bin/ and /usr/local/lib64/
but it didn't work. I even used the option -L/path/to/lapack/liblapack.a and it didn't work also.
When I compile my code, I get the following error:
qrB.o: In function `qrfactorizeb_':
qrB.f90:(.text+0x64f): undefined reference to `zgeqp3_'
collect2: ld returned 1 exit status
make: *** [run] Error 1
I am really unsure what to make of this error. I tested it in 3 other workstations and it didn't help! Can anyone help me?
I had the same problem some time ago! Dual working with Windows and Linux and also ease of playing with options in Windows taught me something interesting!
Try compiling such as:
[...]$
ifort liblapack.a libblas.a libslatec.a *.o -o profmm
and as you know, it means that I want to use 3 libraries to compile and link my files into profmm output file. It has no syntax error, but it leads to a lot of errors like:
preconditioner3.o: In function factorb_':
preconditioner3.f:(.text+0x1add): undefined reference tozgetrf_'
.
.
preconditioner.o: In function factorpre_':
preconditioner.f:(.text+0x13a2): undefined reference tozgetrf_'
preconditioner.f:(.text+0x18bb): undefined reference to zgetri_'
zbesh.o: In functionzbesh_':
zbesh.f:(.text+0xb3): undefined reference to d1mach_'
zbesh.f:(.text+0xcf): undefined reference toi1mach_'
.
.
.
and many more errors indicating that ifort is unable to read my libraries even though they are here in my current directory!
But simply change the command as follow:
[...]$ ifort *.o liblapack.a libblas.a libslatec.a -o profmm
and it works fine with no error! So it means that now ifort can read my library (local ones)! Also note that changing the order of libraries are very important, and it depends on the order of usage of those subroutines inside the program. So always try to reorder the library chain to check for possible errors.
Hope it helps.
I'm getting this error when I try and compile my program on my school's external server.
Undefined first referenced
symbol in file
pow /var/tmp//ccWbipvM.o
sqrt /var/tmp//ccWbipvM.o
ld: fatal: Symbol referencing errors. No output written to assign1
collect2: ld returned 1 exit status
The problem is I don't get it when I compile it locally - it runs fine. Can anyone give me some advice as to what the problem is here?? Thanks!
PS: math.h has been included.
Try linking your program with the math library by using the -lm flag:
gcc -o prg -lm prg.c