Linking a library in g++ doesn't work - linker

I am trying to compile a .cpp-file which uses a matrix-library. The library-files libnewmat.a and libnewmat.so are in the path /usr/lib64 . The include-files are in path /usr/include/newmat , so I tried (several ways) to compile i.e. with:
g++ -I/usr/include -L/usr/lib64 -lnewmat new.cpp -o new3
but the compiler doesn't find the library. The content of the .cpp is:
#include <iostream>
#include <newmat/newmat.h>
#include <newmat/newmatio.h>
using namespace std;
int main()
{
Matrix A(2,2);
Real b[] = {1,2,3,4};
A << b;
cout << A << endl;
return 0;
}
The compiler says:
test.cpp: In function ‘int main()’:
test.cpp:9: error: ‘Matrix’ was not declared in this scope
test.cpp:9: error: expected ‘;’ before ‘A’
test.cpp:10: error: ‘Real’ was not declared in this scope
test.cpp:10: error: expected ‘;’ before ‘b’
test.cpp:11: error: ‘A’ was not declared in this scope
test.cpp:11: error: ‘b’ was not declared in
this scope
Could You provide me with the correct c++ code, or the correct command line instruction?
Thanks, Kepler

If you recently installed this library yourself you probably need to run sudo ldconfig to load the so into the linker cache.
EDIT: As Kevin said not a linking error that you're getting.
Perhaps it's a name space issue?
using namespace NEWMAT;
according to this: http://www.robertnz.net/nm10.htm#namesp

This isn't a library problem - it's a compiler problem - it can't find any definition for Matrix (probably in your include files, but we can't determine that with the information given)
[edit]
Ascertain if your classes in the include files are being referenced correctly
[/edit]

Related

ccosl undeclared when trying to use cos(double) from tgmath.h on arm-none-eabi-gcc

Consider the following test code:
#include <tgmath.h>
void test()
{
double x=cos(4.5);
}
Compiling it as with
arm-none-eabi-gcc test.c -c
on Ubuntu 18.04 (gcc 6.3.1, newlib 2.4.0) works fine, but on Ubuntu 20.04 (gcc 9.2.1, newlib 3.3.0) I get the following errors:
In file included from test.c:1:
test.c: In function 'test':
test.c:5:14: error: 'ccosl' undeclared (first use in this function); did you mean 'ccosh'?
5 | double x=cos(4.5);
| ^~~
test.c:5:14: note: each undeclared identifier is reported only once for each function it appears in
test.c:5:14: error: argument 6 of '__builtin_tgmath' is not a function pointer
Apparently, the definition of cos has somehow changed, so that it now mentions ccosl which is not declared anywhere.
If I change from tgmath.h to math.h, the error no longer appears. This is of course just a workaround, not a fix, since this way I lose the type genericity for float vs double.
My question is: how do I make it work properly? Do I have to add some compilation option, or is it just a bug in the toolchain?
It appears that the difference between the versions of the toolchains is in the GCC implementation of tgmath cos macro in different versions. Namely, compiling with -E option for gcc yields the following (cleaned up) expansion of double x=cos(4.5) in 6.3.1:
double x=__builtin_choose_expr(__builtin_classify_type(4.5) == 9,
__builtin_choose_expr(__builtin_types_compatible_p(__typeof__(__real__(4.5)), long double),
ccosl(4.5),
__builtin_choose_expr(__builtin_types_compatible_p(__typeof__(__real__(4.5)), double) || __builtin_classify_type(__real__(4.5)) == 1,
ccos(4.5),
ccosf(4.5))
),
__builtin_choose_expr(__builtin_types_compatible_p(__typeof__(4.5), long double),
cosl(4.5),
__builtin_choose_expr(__builtin_types_compatible_p(__typeof__(4.5), double) || __builtin_classify_type(4.5) == 1,
cos(4.5),
cosf(4.5))
)
);
while in GCC 9.3.0 the expansion is as a simple function call:
double x=__builtin_tgmath (cosf, cos, cosl, ccosf, ccos, ccosl, 4.5);
The main difference between the two is that __builtin_choose_expr doesn't evaluate the expression that is not chosen (as said in the docs), while __builtin_tgmath is a function, which needs all the arguments to be valid.
And it looks like newlib has never had ccosl in its complex.h, so it appears incompatible with the newer version of GCC.

Compiling C programs with static files

I am trying to compile a c program with a static library and its not working .
This is the error :
undefined reference to `calculatearea'
collect2.exe: error: ld returned 1 exit status .
The static files were made with the gcc / g++ compilers .
This is the main code :
#include <stdio.h>
#include <stdint.h>
int calculatearea(int a , int b);
int main()
{
int c = calculatearea(2,4);
printf("%d",c);
getchar();
return 0;
}
edit :
: screenshot of compiler error
From the above code we can see that you have declared the function int calculatearea(int a , int b); but have not written any definition for the same. and you are calling this function in the main. compiler is not finding the definition for the function calculatearea and giving error.
To solve this:
1) Write the definition for function calculatearea in the same file.
2) Make use of extern specifier with this function declaration and make sure that definition is present with the link library at the time of compilation.
3) As mentioned in the picture if the area.o have the definition of function calculatearea, then compile as below, this will generate a.out in linux:
gcc filename.c area.o

If a global variable having no storage-class is 'extern' by default, then why can't I access this variable? [duplicate]

This question already has answers here:
What is the difference between a definition and a declaration?
(27 answers)
Closed 5 years ago.
I have two .c files, one of them has the definition of x, and the other file is using x, as follows:
file1.c:
int x;
//other code...
main.c:
int main(void)
{
printf("%d", x);
}
Now, when I compile this code, I get the following compilation error message:
In function 'main':
error: 'x' undeclared (first use in this function)
So, if a global variable (in this case x) is 'extern' by default, then why can't main.c file see x?
When I now go to main.c and define x, so that main.c now looks like:
int x=9; //This line was added.
int main(void)
{
printf("%d",x);
}
And also initialize x in file1.c, the program doesn't compile and I get the following error message:
error: ld returned 1 exit status
So, if main.c can't see x that is in file1.c, then this time what is the problem?
Is this a linking error?
Note that when I add
extern int x;
in main.c, the problem disappears.
Each compilation unit (in this case your individual .c files) is compiled separately. The compiler needs to know the storage class of x in order to handle it, so your first error (undeclared) comes from the compiler not knowing what x is. The compiler does not need to know where x lives.
When you then link your compiled objects together, the linker resolves any external names (including x in main.c if you've marked it extern) and the final executable will then have all its variables in known places. If it finds 2 extern symbols with the same name, then it will fail, giving you your second error (error: ld returned 1 exit status).
You must declare you variable in main.c, so the compiler knows about it: extern int x. The compiler said it to you: error: 'x' undeclared
You added the second definition of x in main.c, the first definition you did in file1.c. The linker informed you about ambiguity between two definitions. You could read the error above the line error: ld returned 1 exit status

Error: L6218E: Undefined symbol three()

[Edit: The question is flawed, the file I described as "main.c" was actually "main.cpp" and that it why I was having an issue, calling a C function from a C++ file. The question is thus incorrect and doesn't have an answer, but if you have this undefined symbol issue, also think about checking you're not mixing C & C++.]
I'm using uVision 5 to develop a firmware, however I can't get the linker to find one of my functions.
main.c :
#include "Test.h"
int main()
{
return three();
}
Test.h :
#ifndef TEST_H
#define TEST_H
int three();
#endif
Test.c
#include "Test.h"
int three()
{
return 3;
}
All those files are at the root of my project, I know they get compiled as if I introduce a syntax error in them, compiler reports an error.
Also looking at the map file produced, I see that three() was removed:
Removing test.o(i.three), (4 bytes).
For testing purposes, I had --no_remove to linker command line, map file now contains:
0x0002ba76 0x00000004 Code RO 1 i.three test.o
So obviously, the linker is well aware of my function, and will or won't remove it depending on flags.
Regardless, it reports:
.\build\uvision5\test.axf: Error: L6218E: Undefined symbol three() (referred from main.o).
Not enough information to list image symbols.
Flawed question, it was actually a case of mixing C/C++, in which case you'll get a symbol missing if you call a C function from C++ without declaring it extern C.

Error: ‘AES_BLOCK_SIZE’ undeclared. Unable to compile OpenSSL with C in Linux

I have installed latest version of OpenSSL . I just try to compile and run the program OpenSSL_aes.
While compiling with gcc -Wall openssl_aes.c -lcrypto I got following error. I tried my best solve this problem , but unable to solve this compiler error.
openssl_aes.c: In function ‘aes_encrypt’:
openssl_aes.c:51:22: error: ‘AES_BLOCK_SIZE’ undeclared (first use in this function)
int c_len = *len + AES_BLOCK_SIZE, f_len = 0;
^
openssl_aes.c:51:22: note: each undeclared identifier is reported only once for each function it appears in
openssl_aes.c: In function ‘aes_decrypt’:
openssl_aes.c:75:45: error: ‘AES_BLOCK_SIZE’ undeclared (first use in this function)
unsigned char *plaintext = malloc(p_len + AES_BLOCK_SIZE);
^
Edit :
while I add #include<openssl/aes.h> as per # martin, the compilation problem is solved.
now, gcc -Wall openssl_aes.c -lcrypto is successfully compiled.
But, when I try to run the program ( to run i used - ./a.out ), I got following error
Segmentation fault (core dumped)
Can anyone help me to solve this and run my program? I just want to perform simple aes encryption/decryption using OpenSSL. I am using GCC under Fedora 19 .
Thanks in advance.
You are probably not including openssl/aes.h, as AES_BLOCK_SIZE is defined in there as: #define AES_BLOCK_SIZE 16. So make sure you have:
#include <openssl/aes.h>
in your file.

Resources