Undefined symbols for architecture x86_64: gfortran - fortran

Hi so I'm trying to compile a Fortran code written by someone else in what I believe is F77 (.for extension). The error I'm getting is:
Undefined symbols for architecture x86_64:
"_random_", referenced from:
_pms_ in ccx1qzWD.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
I'm not posting the code now but I've been searching online for what this error even means so I can start searching for the solution but can't find any helpful information. I have no previous Fortran experience! Any help on the meaning of this error is really appreciated. I'm using a mac and the only section that includes the "random" is part of a subroutine:
DOUBLE PRECISION RANDOM
DO 1 J=1,M
w(J)=dw+REAL(J*2-1)*dw/2.0
W1=w(J)*w(J)*w(J)*w(J)*w(J)
Vel1=Vel*Vel*Vel*Vel*W1/w(J)
Vel1=-6844.0697/Vel1
Gw(J)=0.77898/W1*EXP(Vel1)
Phi(J)=RANDOM()*8.0*ATAN(1.0)
1 CONTINUE
I am using: gfortran SEASIM.FOR to compile
Thanks in advance for any advice!

OK, it definitely looks like you're not providing the linker with a library containing an implementation of random. You could dig around and find such a library, modify your linkage, and see how that goes. But it would be easier to replace the call to random with a call to the gfortran intrinsic rand which returns a number from a uniform distribution between 0 and 1. So that's what I suggest you do. Consult the documentation for further details.
A better approach would be to use the now-standard random_number but that's a subroutine and would require more of a modification to your program.
I have a nagging suspicion that if the only step you take to build the program is to execute gfortran SEASIM.FOR at the command-line then you may be missing linking to other necessary libraries so I won't be surprised if you report failure.
This line
DOUBLE PRECISION RANDOM
declares that RANDOM is a DOUBLE PRECISION thing. That it is a function returning a value rather than a variable holding a value is made clear by the later use of RANDOM(). The compiler is indifferent to the location of the code implementing the routine, but the linker is not.

Related

Undefined symbols for io_context: linking error for the latest boost library

My code used to copmile well previously, until boost library got updated with changes in asio.
In my code, I define a variable: boost::shared_ptr<Face> face(boost::make_shared<ThreadsafeFace>(io_service)); which, as can be seen, takes io_service for the constructor. Face and ThreadsafeFace are a library classes, my app links to.
The problem occurs at linking stage of my binary, where I get undefined symbols error:
Undefined symbols for architecture x86_64:
"ndn::ThreadsafeFace::ThreadsafeFace(boost::asio::io_context&)", referenced from:
boost::detail::sp_if_not_array<ndn::ThreadsafeFace>::type boost::make_shared<ndn::ThreadsafeFace, boost::asio::io_context&>(boost::asio::io_context&&&) in ndnrtc_client-main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
As can be seen, linker can't find a constructor for ThreadsafeFace that takes boost::asio::io_context& argument. And it won't -- because library does not provide one. The only one library does provide -- is with io_service argument.
Now, I don't quite understand, where does this constructor definition come from, as neither my code, nor library's code have this definition.
This makes me think that with new boost (I'm linking against 1.67 using homebrew, macOS), io_service gets replaced by io_context automatically (during preprocessing?), thus leading to the problem.
I tried providing -DBOOST_ASIO_ENABLE_OLD_SERVICES when compiling my code, but it didn't help either.
Shall I downgrade boost version until library gets updated?
UPDATE
I've ran clang for preprocessing (clang++ -E ...) and found this in the output:
# 21 "/usr/local/include/boost/asio/io_service.hpp" 2 3
namespace boost {
namespace asio {
typedef io_context io_service;
}
}
Which confirms that all io_service variables will in fact be io_context and guarantee headaches.
"Which confirms that all io_service variables will in fact be io_context and guarantee headaches"
In fact that guarantees no headaches. Typedefs are aliases: they're exactly the same. So io_service becomes just another way to refer to the same type, even if the spelling happens to be different in some spots. This is actually what you need.
Reading the message:
Undefined symbols for architecture x86_64:
"ndn::ThreadsafeFace::ThreadsafeFace(boost::asio::io_context&)", referenced from:
boost::detail::sp_if_not_array::type boost::make_shared(boost::asio::io_context&&&) in ndnrtc_client-main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This tells you that ndn::ThreadsafeFace does provide the required constructor, because it's referenced from your code. If it weren't provided, it would have been a compile error, not a link error.
So your problem is different. You either lack a linker input, or the library object you link against was compiled /differently/ in such a way that it doesn't provide the definition of the constructor that is declared when you include the header that declares ThreadsafeFace.
Usually, this happens if namespaces change, or when you (ab)used compiler defines to change the meaning of the code (did you perhaps mess around with something like #define io_context io_service? Because that is a recipe for headaches).
Note linker errors can even result when you use different compiler versions/flags when compiling your code versus when compiling the library.
For far more troubleshooting tips see: What is an undefined reference/unresolved external symbol error and how do I fix it?

How to solve C++ conflicts between system and library dependencies

My problem is rather specific, but bear with me.
This in the end is kinda reverse engineering, but this problem in particular seems to fit more this board.
So, I have a shared object compiled for MIPS written in C++. I don't have the source code of the lib. The lib is compiled using GCC 4.3.3. I want to use functions present in this shared object in my amd64 computer running elementary OS. To do this, I used the sourcery cross compiler to cross compile some C++ code to MIPS, that would use this object.
So far I managed this except for this one compile error, which I cannot figure out. The lib is called libdvl.so, and uses as dependency libc.so.0 (and both are in the same folder as the cpp code).
mips-linux-gnu-g++ -g -L/path/to/lib -Wl,-rpath,/path/to/lib -o verifier verifier.cpp -ldvl
which gives me
(...)/mgc/embedded/codebench/bin/../lib/gcc/mips-linux-gnu/4.9.1/../../../../mips-linux-gnu/bin/ld: warning: libc.so.0, needed by /path/to/lib/libdvl.so, may conflict with libc.so.6
(...)/mgc/embedded/codebench/bin/../lib/gcc/mips-linux-gnu/4.9.1/../../../../mips-linux-gnu/bin/ld: errno##GLIBC_PRIVATE: TLS definition in (...)/mgc/embedded/codebench/bin/../mips-linux-gnu/libc/lib/libc.so.6 section .tbss mismatches non-TLS definition in /path/to/lib/libc.so.0 section .bss
/path/to/lib/libc.so.0: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
So I added "-l:libc.so.0" and got this
(...)/mgc/embedded/codebench/bin/../lib/gcc/mips-linux-gnu/4.9.1/../../../../mips-linux-gnu/bin/ld: errno: TLS definition in (...)/mgc/embedded/codebench/bin/../mips-linux-gnu/libc/lib/libc.so.6 section .tbss mismatches non-TLS definition in libc.so.0 section .bss
(...)/mgc/embedded/codebench/bin/../mips-linux-gnu/libc/lib/libc.so.6: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Any idea how to solve this? I know I am using GCC 4.9.1, but I already downloaded the older code sourcery version which uses GCC 4.3.154 and got the exact same error.
EDIT 1: Exactly as Lol4t0 said, filtered using c++filt it gives an actual function name from stdc++. Using
mips-linux-gnu-g++ -g -L/path/to/lib -Wl,-rpath,/path/to/lib -I/path/to/lib -o verifier verifier.cpp -ldvl -l:libuClibc++.so.0 -l:libutil.so.0 -l:libc.so.0 -l:ld-uClibc.so.0 -nodefaultlibs
to give to libdvl its depencies (as I will not rewrite stdc++ :p), I get the following compile error:
(...)/mgc/embedded/codebench/bin/../lib/gcc/mips-linux-gnu/4.9.1/../../../../mips-linux-gnu/bin/ld: /tmp/cc66DLda.o: undefined reference to symbol '_Unwind_Resume##GCC_3.0'
(...)/mgc/embedded/codebench/bin/../mips-linux-gnu/libc/lib/libgcc_s.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
I already confirmed lib dependencies and the order in which they appear.
Any thoughts on this?
Thanks for all the help.
Using -nodefaultlibs solves the first problem though.
You are linking against GLIBC (libc.so.6) and some other libc (libc.so.0).
That could never work: you have to have everything compiled and linked against a single, consistent libc.
Since your libdvl.so uses as dependency libc.so.0, and assuming you can't rebuild libdvl.so, you have to use crosscompiler that targets libc.so.0 (which is possibly dietlibc, or uClibc), and compile and link everything else using that toolchain. Your crosscompiler on the other hand appears to target GLIBC, and will not do you any good.
After a lot of trial and error, you may be able to link the final binary using inconsistent builds, and your binary may even get to main (that is very unlikely). But chances of such binary actually working correctly are minuscule.

Including expect/tcl library for C/C++

Recently I found an example of how to use the expect library in C++. I tried to compile it, but the compiler (g++) said, that tcl8.5/expect.h doesn't exists. So I tried to include tcl8.6/expect.h - still the same error. I checked the /usr/include/ directory and I wasn't surprised when I've noticed, that there is no tcl8.x directory.
I've searched for files with "expect" in their name. Here's what I found:
/usr/include/expect_tcl.h
/usr/include/expect_comm.h
/usr/include/expect.h
Unfortunately when I tried to include any of these I got the following list of errors during compilation:
> g++ test.cpp -Wall -std=c++0x -ltcl8.6 -lglog -o test
/tmp/cce8k1BA.o: In function `task(std::string const&, std::string const&, std::string const&)':
test.cpp:(.text+0x16): undefined reference to `exp_is_debugging'
test.cpp:(.text+0x20): undefined reference to `exp_timeout'
test.cpp:(.text+0x38): undefined reference to `exp_popen'
etc...
How can I solve this problem?
[EDIT]
When I tried to link it with the expect lib (-lexpect) I got the following error:
/usr/bin/ld: cannot find -lexpect
collect2: error: ld returned 1 exit status
I'm sure that both - tcl8.6 and expect 5.45-4 are installed.
The usual way of distributing Expect these days puts the shared library in a non-standard location and loads it dynamically by full pathname. This works well and is minimal fuss for most people, but does make it rather hard to use Expect's C interface in your own code.
The easiest way is going to be to build your own copy from source, especially as that will give you control over how exactly it was built. This can particularly include keeping the majority of symbols in the library instead of stripping them on install, which will help a lot with debugging. You probably ought to use the current supported version. (Yes, it's a release from several years ago. It doesn't need a lot of support effort most of the time.)
You haven't linked to the expect library during your build. Add -lexpect to your g++ command.

Program not compiling, even though I'm copying code from book

I have taken this example directly from a book on C++ (shortened it so it's easier to see what the problem is).
My class won't compile with g++. The class is:
class stack{
private:
int count;
public:
void init(void);
};
inline void stack::init(void){
count= 0;
}
~
As you can see, I'm trying to prototype my functions inside the class, then define them outside the class. The book did exactly what I am trying this, but it doesn't work. Where is the mistake? Is it my computer (I'm using a mac). The error I get is the question, but also here:
user-MacBook-Pro:cplusplus trevortruog$ g++ Stack2.cpp
Undefined symbols for architecture x86_64: "_main", referenced from:
start in crt1.10.6.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status
The code compiles fine. It just doesn’t do anything useful since it’s missing a main function and therefore no executable can be generated from it.
This is not an error in the compiler but rather in the linker, which precisely complains about the lack of an entry point. You can see this from the error message:
ld: symbol(s) not found for architecture
The first thing, ld, is the name of the application which created the error message. ld is the linker application which is (internally) called by the actual compiler. Once that gets called, the code is already compiled.
Add a main function to solve the linker error.
As an added comment, the code uses bad practice. This is a sure hint that the programming book you’re using is bad. Unfortunately, bad teaching material is the bane of C++, which is a highly complex language even when taught correctly. Do yourself a favour and ditch the book in favour of a good one.

Linker Command Fail in Xcode with Pure Virtual Objects

I'm a n00b so correct me on anything.
I've been working on this for a couple days and have done research but can't seem to solve the issue. This is for a programming class that mainly uses Visual Studio and many of my fellow classmates didn't have a problem. Although, I'm on Xcode so maybe it has something to do with that. Basically, I'm creating a Pure Virtual objects called Geometric_Object with child classes Circle.h and Rectangle.h, however when I run the code I get the following error:
Undefined symbols for architecture x86_64:
"GeometricObject::GeometricObject()", referenced from:
Circle::Circle() in main.o
Rectangle::Rectangle() in main.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'm beyond lost. Because I don't have enough reputation points I can't post all the links so I had to compress them as one on Dropbox. Hopefully someone can bypass this for me so nobody is afraid to unzip the contents.
https://dl.dropboxusercontent.com/u/82764116/Xcode.zip
The problem is exactly what the error says. You haven't defined GeometricObject::GeometricObject(). You also haven't defined many other methods in GeometricObject, like the destructor, getColor, setColor etc.
I'm not sure where you think the definitions for these functions are, but they aren't in the code you've linked to.
You have defined (for instance) Rectangle::Rectangle(). Just define GeometricObject::GeometricObject() in the same way (and all the other missing definitions).