gcc undefined reference to header function - gcc

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!

Related

GCC builtin functions - 2003 vs 2019 behaviour

At page 14 of the book "Introduction to GCC" by Brian Gough, the author wants to show a linker error due to not supplying gcc with the libm library, where the code for the function sqrt resides:
$ gcc -Wall calc.c -o calc
/tmp/ccbR6Ojm.o: In function ‘main’:
/tmp/ccbR6Ojm.o(.text+0x19): undefined reference to ‘sqrt’
The file calc.c (where the functionsqrt is invoked) is this:
#include <math.h>
#include <stdio.h>
int main (void)
{
double x = sqrt (2.0);
printf ("The square root of 2.0 is %f\n", x);
return 0;
}
This book is from 2003.
On my current Ubuntu Linux 18, I can't reproduce the link error: it links and works, printing the correct result:
$ ./calc
1.414214
I found with ldd calc that the libm.so shared library is not invoked at runtime. Nor of course is the static library libm.a involved here.
So how does gcc deal with the function sqrt? I found that in this case it uses the sqrt GCC built-in function.
Its code gets inserted in the calc.o object file at compile time. So no "undefined reference" error.
First question: this the whole story or am I missing something?
Second question: why did this behavior regarding the built-in functions of GCC change so much between 2003 (when the book was written) and now? (Practically invalidating the whole example, it seems to me)
Third question: why does the author make his examples (e.g.$ gcc -Wall calc.c -lm -o cal) implying that the static library libc.a will be used, when in reality in Linux that syntax invokes the dynamic library libm.so? Is this specific to Linux and not to GNU GCC? What am I mising?
I think this is due to optimization of a constant value. Modern GCC can compute exact value of sqrt (2.0). If you force it not to use the built-ins with -fno-builtin, it will still fail to link. Also, if you change the code a little bit so that the argument to sqrt() is not literal, it will fail to link:
#include <math.h>
#include <stdio.h>
double t = 2.0;
int main (void)
{
double x = sqrt (t);
printf ("The square root of 2.0 is %f\n", x);
return 0;
}
This produces link error:
> gcc -o test test.c
/usr/bin/ld: /tmp/ccLjHnQx.o: in function `main':
test.c:(.text+0x11): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
Regarding your 3rd question, -lm does not imply static library, AFAIK.

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.

Linking error in C++

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.

Problem compiling program using fork in cygwin

I am trying to run a simple program in cygwin that includes fork and wait.
I thought it would be very easy to compile but I am having problems.
#include <stdio.h>
#include <unistd.h>
void testFork(){}
int main(int argc,char* argv[]){
if (fork()==0) {testFork();return 0;}
while (wait() == -1);
return 0;
}
Compiled using:
gcc -Wall -Wextra -o test.o test
I get the following error:
C:\Users\Aaron\AppData\Local\Temp\ccgh3MfS.o:ostest.c:(.text+0x11): undefined reference to `fork'
C:\Users\Aaron\AppData\Local\Temp\ccgh3MfS.o:ostest.c:(.text+0x22): undefined reference to `wait'
collect2: ld returned 1 exit status
I'm sure I'm missing something trivial. Any ideas?
The linker can't find the standard C libraries.
Did you install Cygwin in the normal way? (Here's a simple guide: http://www.eecg.utoronto.ca/~aamodt/ece242/cygwin.html).
Have you been able to compile even simpler programs:
#include <stdio.h>
int main(int argc, char **argv) {
printf("Found C library.\n");
}
If that doesn't compile, you might just want to try removing and reinstalling Cygwin - something is broken.
C:\Users\Aaron\AppData\Local\Temp\ccgh3MfS.o is a Windows-style path. If you're using Cygwin, you only be seeing Cygwin-style paths, perhaps something like /cygdrive/C/Users/Aaron/AppData/Local/Temp/ccgh3MfS.o.
You said your command line was
gcc -Wall -Wextra -o test.o test
but it was probably
gcc -Wall -Wextra -o test.o test.c
Are you invoking gcc from the Cygwin command line? What does type gcc say?
It seems that MinGW gcc is being invoked because the cygwin gcc package is not installed.
You can verify that by calling the "cygcheck -c" in the cygwin commandline which will list all the installed packages, if you can't find the gcc in the list you need to install it

linking g++ code with shared library build with gcc

I made shared library using gcc . I would like to link this library using g++ comiler with source code *.c.
Example
test_init.c
#include<stdio.h>
int test_init()
{
printf(" test init success\n");
return 0;
}
gcc -shared -o libtest.so test_init.c
test.c
#include<stdio.h>
extern int test_init();
main()
{
test_init();
}
g++ -I. -L. -ltest test.c
/tmp/ccuH5tIO.o: In function main':
test.c:(.text+0x7): undefined
reference totest_init()' collect2:
ld returned 1 exit status
Note: If i compile test.c with gcc it works, but i would like to use this approach due to other dependencies. Is it possible??
You call C routines from C++ by declaring them
extern "C" {
....
}
Look into a few header files on your system or Google around -- that's the only way to do it because of different function signature systems between the languages.
As Dirk said, change extern int test_init(); to extern "C" { int test_init(); }
Usually -llibrary should be after object files or c/c++ files in gcc command line
g++ -I. -L. test.c -ltest
The linker searches for the symbols mentioned in test.c after it's processed and when you put -llib before test.c, it's just unable to find them.
See man ld for more info.
Not sure how the things are when you use extern, perhaps something is different in this case.

Resources