Linking error in C++ - gcc

The question here gives an example of how to use xgboost - a machine learning library written in C++. I want to run the example, and therefore install the library for C++. I added the /lib files to /usr/local/lib and /src files to /usr/local/src
I am able to compile this much part of the example :
#include <iostream>
#include <xgboost/c_api.h>
using namespace std;
int main(){
int cols=3,rows=5;
float train[rows][cols];
for (int i=0;i<rows;i++)
for (int j=0;j<cols;j++)
train[i][j] = (i+1) * (j+1);
float train_labels[rows];
for (int i=0;i<rows;i++)
train_labels[i] = 1+i*i*i;
DMatrixHandle h_train[1];
XGDMatrixCreateFromMat((float *) train, rows, cols, -1, &h_train[0]);
}
However, I am getting a linking error:
/tmp/ccuBacNh.o: In function `main':
TerrainPredict.cpp:(.text+0x278): undefined reference to `XGDMatrixCreateFromMat'
collect2: error: ld returned 1 exit status
How can I resolve this. I concluded that cpp files are missing, but I don't know where to put them. I want help regarding how to proceed with installation.
I also tried using a makefile:
LDLIBSOPTIONS=xgboost/lib/libxgboost.a xgboost/rabit/lib/librabit.a xgboost/dmlc-core/libdmlc.a -lpthread
CFLAGS=-I xgboost/include -I xgboost/rabit/include -I dmlc-core/include
all:
g++ main.cpp $(CFLAGS) $(LDLIBSOPTIONS)
I put Makefile, main.cpp and xgboost directory in the same folder.
In that case I am getting a longer linking error. Error is too long to include fully. Here it is.

Related

threading program runs with g++ but not with gcc

I have compiled a c++ code using g++ -std=c++11 -o main main.cpp -pthread and it compiled fine however if I compile the same code using gcc -std=c++11 -o main main.cpp -pthread it does not compile and throws error. The program uses threading which properly taken care of using -pthread option while compiling. For the reference I am attaching the code below. Any help is highly appreciated.
#include <iostream>
#include <thread>
class foo
{
public:
void bar(int loop_num)
{
for (int i = 0; i < loop_num; ++i) {
std::cout << "Thread executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
int n = 0;
};
int main()
{
int n = 0;
foo f;
std::thread t1(&foo::bar, &f, 5);
t1.join();
}
If you’ve written C++ code with GCC, you’ll know that you need to use the program g++, both for compilation and linking. For multi-module programs, this means every .cpp file gets compiled with g++, and then the entire program must be linked separately using g++. If you try to link the program using gcc, it will almost work, but you’ll get a lot of “undefined reference” errors, like this:
test.cpp:(.text+0x11): undefined reference to `std::cout'
The need to use g++ to link the entire program causes trouble when you have a very complicated build process you don’t have full control of. For instance, I’m trying to link C++ code with Mercury, and I have to use the Mercury linker, which in turn calls gcc.
So just a quick tip: If you are forced to use gcc to link the program, just add the library “stdc++”, as you would any other library, and it will work. That is, add the option “-lstdc++” to your GCC linker command line. For example:
g++ -c hello.cpp
gcc -lstdc++ -o hello hello.o
I assume the error you get looks something like this:
/tmp/ccUKAq0K.o: In function `main':
main.cpp:(.text+0x59): undefined reference to `std::thread::join()'
/tmp/ccUKAq0K.o: In function `__static_initialization_and_destruction_0(int, int)':
main.cpp:(.text+0xb6): undefined reference to `std::ios_base::Init::Init()'
main.cpp:(.text+0xcb): undefined reference to `std::ios_base::Init::~Init()'
/tmp/ccUKAq0K.o: In function `std::thread::~thread()':
main.cpp:(.text._ZNSt6threadD2Ev[_ZNSt6threadD5Ev]+0x1d): undefined reference to `std::terminate()'
(And so on.)
C++ programs which use the standard library (so most of them) need to be linked using g++, not gcc. Only the g++ compiler driver links in most of the standard library. The gcc compiler driver compiles C++ programs, just like g++, but when the linker is invoked, the program is treated as a C program, which usually leads to linker errors.
Try adding the -lrt flag after the pthread one.

How to compile a file using a shared library?

I am trying to compile a source given a .so file libfoo.so. The only thing in this library is a function that just returns a number (yeah, I know, advanced stuff). The header file equivalent (I was provided with both, but am only supposed to use the .so) is named foo.h and the function is named int foo().
My source file is main.c:
#include <stdio.h>
#include "foo.h"
int main()
{
int x = foo();
printf("%d", x);
return 0;
}
Now, when trying to compile I have the following commands:
gcc -Wall -fPIC -c main.c -o main.o
gcc -Wall -fPIC main.o -o main -lfoo -L.
The first command fails to create the object file, outputting the following error:
fatal error: foo.h: No such file or directory
I am using Ubuntu 16.04.
I have also tried exporting the current location to LD_LIBRARY_PATH as I've seen suggested on a few other answers.
export LD_LBIRARY_PATH=$LD_LIBRARY_PATH:machine/Desktop/lib_test
You need to have the interface definition from the .h file and that file must be in the current directory or a directory on the include search path.
Note that on some systems filenames and paths are case dependent.

gcc undefined reference to header function

I know there have been a lot of such topics, but I didn't found the answer, really. There's nothing that isn't working.
I am compiling file
gcc -std=c99 -Lmem xx.c
in the file there is
#include "include/memory.h"
#include <stdlib.h>
void main(){
meminit(100);
}
and in memory.h
#include "private.h"
#pragma once
MEMI * memdiag();
void meminit(int block_number);
void * memalloc(int desired_size);
void memfree(void * ptr);
the folder contains libmem.a, and headers, yet I'm getting error
/tmp/ccSJ4trm.o: In function `main':
xx.c:(.text+0xa): undefined reference to `meminit'
collect2: error: ld returned 1 exit status
I would be very grateful if You helped me, tomorrow I have to hand in the project.
You need to read some tutorials about using GCC.
You might want to try to compile and link with with
gcc -std=c99 -Wall -g xx.c -L. -lmem
(assuming your current directory [not folder] i.e. the . in -L. contains a libmem.a or libmem.so* library)
BTW, order of program arguments to gcc matters a big lot!

Link to cutil in GPU Computing SDK

I've been trying to link to the functions in the cutil.h ofthe GPU Computing SDK released by NVIDIA.
At the moment, I am simply trying to compile this simple piece of code:
#include <iostream>
#include <cuda.h>
#include <cutil.h>
using namespace std;
int main(){
unsigned int time_total;
cutCreateTimer(&time_total);
return 0;
}
using the following command:
nvcc -I/home/sj755/NVIDIA_GPU_Computing_SDK/C/common/inc/ -L/home/sj755/NVIDIA_GPU_Computing_SDK/C/lib/libcutil_x86_64.a cutiltest.cu
Only to get the following error:
/tmp/tmpxft_000077cc_00000000-13_cutiltest.o: In function `main':
tmpxft_000077cc_00000000-1_cutiltest.cudafe1.cpp:(.text+0x10): undefined reference to
`cutCreateTimer'
collect2: ld returned 1 exit status
ld also can't find -lcutil if I were to add the flag.
There is a static library that I'm supposed to link to, but for some reason this never works out. Here's what I tried:
I've changed my .bashrc file so that LD_LIBRARY_PATH includes the path to the static library
##########< CULA >
export CULA_ROOT=/usr/local/cula
export CULA_INC_PATH=$CULA_ROOT/include
export CULA_BIN_PATH_32=$CULA_ROOT/bin
export CULA_BIN_PATH_64=$CULA_ROOT/bin64
export CULA_LIB_PATH_32=$CULA_ROOT/lib
export CULA_LIB_PATH_64=$CULA_ROOT/lib64
##########< CUDA >
export PATH=$PATH:/usr/local/cuda/bin
export LD_LIBRARY_PATH=:/usr/local/cuda/lib64
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CULA_LIB_PATH_64
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/libnvvp/
export CUDA_SDK_ROOT_DIR=/home/sj755/NVIDIA_GPU_Computing_SDK/C
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CUDA_SDK_ROOT_DIR/lib
I've also tried renaming libcutil_x86_64.a to libcutil.a, still nothing.
Tried extracting the archive, creating a shared object file, and linking to it:
ar -x libcutil_x86_64.a
gcc -I /usr/include/GL/ -L /usr/include/GL/ -lglut -lGL -lGLU -lX11 -lXmu -lXi -lm -lpthread -shared *.cpp.o -o libcutil.so
nvcc -lcutil -I /home/sj755/NVIDIA_GPU_Computing_SDK/C/common/inc/ -L /home/sj755/NVIDIA_GPU_Computing_SDK/C/lib/libcutil.so cutiltest.cu
Only to get the following /usr/bin/ld: cannot find -lcutil
What step am I forgetting here?
Your compilation statement is incorrect. It should look something like this:
nvcc -I$SDKROOT/C/common/inc -L$SDKROOT/C/lib cutiltest.cc -lcutil_x86_64
where SDKROOT holds the root path to the SDK, which looks to be
/home/sj755/NVIDIA_GPU_Computing_SDK
in your case. The key things to note here are that the library must be passed by name as a -l option after the code and objects that require it. A concrete example on OS X using your code snippet:
$ cat cutiltest.cc
#include <iostream>
#include <cuda.h>
#include <cutil.h>
using namespace std;
int main(){
unsigned int time_total;
cutCreateTimer(&time_total);
return 0;
}
$ nvcc -I/Developer/GPU\ Computing/C/common/inc -L /Developer/GPU\ Computing/C/lib -o cutiltest cutiltest.cc -lcutil_i386
$ ls -l cutiltest
-rwxr-xr-x 1 talonmies talonmies 117548 May 25 07:57 cutiltest
But as a last remark, you really should rethink your choice of using the SDK cutils library at all. It is only intended for use with the SDK examples. It isn't part of CUDA, it has no documentation, it isn't guaranteed to work or not contain bugs, and isn't guaranteed to be consistent (or even present) from one SDK release to another.
This is not only your problem. Are you tried to link with cutil as with shared library? This solution was posted on NVIDIA dev. zone forum

A linking error related to 'gcc' and '-lm'

Well, I think my problem is a little bit interesting and I want to understand what's happening on my Ubuntu box.
I compiled and linked the following useless piece of code with gcc -lm -o useless useless.c:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * 440 * ((float) 1/44100)));
return(0);
}
So far so good. But when I change to this:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int freq = 440;
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * freq * ((float) 1/44100)));
return(0);
}
And I try to compile using the same command line, and gcc responds:
/tmp/cctM0k56.o: In function `main':
ao_example3.c:(.text+0x29): undefined reference to `sin'
collect2: ld returned 1 exit status
And it stops. What is happening? Why can't I compile that way?
I also tried a sudo ldconfig -v without success.
There are two different things going on here.
For the first example, the compiler doesn't generate a call to sin. It sees that the argument is a constant expression, so it replaces the sin(...) call with the result of the expression, and the math library isn't needed. It will work just as well without the -lm. (But you shouldn't count on that; it's not always obvious when the compiler will perform this kind of optimization and when it won't.)
(If you compile with
gcc -S useless.c
and take a look at useless.s, the generated assembly language listing, you can see that there's no call to sin.)
For the second example, you do need the -lm option -- but it needs to be at the end of the command line, or at least after the file (useless.c) that needs it:
gcc -o useless useless.c -lm
or
gcc useless.c -lm -o useless
The linker processes files in order, keeping track of unresolved symbols for each one (sin, referred to by useless.o), and then resolving them as it sees their definitions. If you put the -lm first, there are no unresolved symbols when it processes the math library; by the time it sees the call to sin in useless.o, it's too late.

Resources