Why would my simple compilation fail? - c++

So I just install gcc from homebrew and I have a simple code:
#include <cmath>
#include <iostream>
#include <stdio.h>
int main()
{
const int size = 256;
double sinTable[size];
#pragma omp parallel for
for(int n=0; n<size; ++n)
sinTable[n] = std::sin(2 * M_PI * n / size);
#pragma omp parallel for
for(int n=0; n<10; ++n)
{
printf(" %d", n);
}
printf(".\n");
// the table is now initialized
}
However, when I compiled, I failed:
dhcp-18-189-47-44:openmp_code myname$ gcc-4.8 tmp2.cpp
Undefined symbols for architecture x86_64:
"std::ios_base::Init::Init()", referenced from:
__static_initialization_and_destruction_0(int, int) in ccFbBrPl.o
"std::ios_base::Init::~Init()", referenced from:
__static_initialization_and_destruction_0(int, int) in ccFbBrPl.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
However, if I change it to g++-4.8, then it is successful...
dhcp-18-189-47-44:openmp_code myname$ g++-4.8 tmp2.cpp -fopenmp
I am wondering why this would happen....

You are compiling C++ code with 'gcc' (why?), so you need to link to it the standard c++ library. Add -stdc++ to the build command. When compiling with g++ it knows to link with this library automatically.
EDIT
On the other hand, your code has nothing related to C++ standard libraries. You have #include <iostream> but you use nothing from it. I think (didn't check it though) that if you comment out this include, your original build with 'gcc' should pass.

You're asking why your C++ program fails to compile with a C compiler, but compiles properly with a C++ compiler?
Then this rhetorical question is my answer.
The C compiler doesn't do things like linking in its C++ runtime. You need that runtime. Your linker errors show that the C++ runtime is not being linked. Because you're using a C compiler.

Related

Fortran subroutines produce "Undefined symbols" error when linking to c++ program

I am writing a short program to test calling the fortran Stripack library from c++. The c++ and fortran files each compile successfully, but errors occur when linking.
The c++ code is as follows:
#include <iostream>
#include <cmath>
#ifdef __cplusplus
extern"C" {
#endif
void trmesh_(int&,float[],float[],float[],int[],int[],int[],int&,int[],int[],float[],int&);
void trlist2_(int&,int[],int[],int[],int&,int[][3],int&);
#ifdef __cplusplus
}
#endif
int main(){
// Variables for distributing points on sphere.
int polar = 16;
int azimuth = 32;
int n = polar*azimuth-azimuth+2;
float radius=1.0;
// Define variables needed by Stripack
float xs[n];
float ys[n];
float zs[n];
int list[6*(n-2)];
int lptr[6*(n-2)];
int lend[6*(n-2)];
int near[n];
int next[n];
float dist[n];
int ltri[2*n-4][3];
int lnew;
int ier;
int nt;
// Distribute n points on surface of unit sphere .
// xs, ys, zs store x, y, and z components pf each point position.
zs[0] = 1;
xs[0] = 0;
ys[0] = 0;
zs[n] = -1;
xs[n] = 0;
ys[n] = 0;
for (int ii=1; ii<polar; ii++){
for (int jj=0; jj<azimuth; jj++){
zs[(ii-1)*azimuth+jj+1] = radius*cos(ii*M_PI/polar);
xs[(ii-1)*azimuth+jj+1] = radius*sin(ii*M_PI/polar)*sin(jj*2*M_PI/azimuth);
ys[(ii-1)*azimuth+jj+1] = radius*sin(ii*M_PI/polar)*cos(jj*2*M_PI/azimuth);
}
}
// Call stripack subroutines to obtain list of triangles ltri
trmesh_(n,xs,ys,zs,list,lptr,lend,lnew,near,next,dist,ier);
trlist2_(n,list,lptr,lend,nt,ltri,ier);
// Output list of triangles
for (int ii =0; ii<n; ii++){
std::cout << ltri[ii][0] << " " << ltri[ii][1] << " " << ltri[ii][2] << std::endl;
}
}
I compile the files as follows:
ifort -c stripack.f90
clang++ -c -O0 -std=c++11 -c -o main.o main.cpp -g
clang++ -o main stripack.o main.o
The first two compilations work fine, but the last one produces the following results. It seems like the subroutines in the fortran file can't find standard fortran functions? I have tried with gfortran and the same problem occurs. Any suggestions as to what is going on would be greatly appreciated.
Undefined symbols for architecture x86_64:
"___libm_sse2_sincos", referenced from:
_trplot_ in stripack.o
_vrplot_ in stripack.o
"___svml_sincos2", referenced from:
_trans_ in stripack.o
"_for_date_and_time", referenced from:
_timestamp_ in stripack.o
"_for_stop_core", referenced from:
_trmesh_ in stripack.o
_addnod_ in stripack.o
"_for_trim", referenced from:
_timestamp_ in stripack.o
"_for_write_seq_fmt", referenced from:
_delnod_ in stripack.o
_edge_ in stripack.o
_timestamp_ in stripack.o
_trlprt_ in stripack.o
_trmesh_ in stripack.o
_addnod_ in stripack.o
_trplot_ in stripack.o
...
"_for_write_seq_fmt_xmit", referenced from:
_delnod_ in stripack.o
_edge_ in stripack.o
_timestamp_ in stripack.o
_trlprt_ in stripack.o
_trmesh_ in stripack.o
_addnod_ in stripack.o
_trplot_ in stripack.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 will demonstrate this is a link issue by example, you need do a little bit more research to solve the problem, as the information you provide is not complete.
!fortran code, named as x.f90
subroutine testFDLL(str, n) bind(c, name='testFDLL_as_C')
use ISO_C_BINDING
integer(c_int), value :: n
character(kind=c_char), intent(in) :: str(n)
write(6,*)" Hello FORTRAN : let us do something ...",str
return
end
The following C code is used for demonstration (you have got C++ mostly right already).
//c named as y.c
#include <stdio.h>
#include <string.h>
int main()
{
void testFDLL_as_C(char *str, int n);
char str[] = "Hello from C";
testFDLL_as_C(str, strlen(str));
return 0;
}
If you compile and link use the following
ifort -c x.f90
gcc y.c x.o -W -Wall
Depend on version of ifort and OS, should get error similar as the following
x.o: In function `testFDLL_as_C':
x.f90:(.text+0x42): undefined reference to `for_write_seq_lis'
x.f90:(.text+0x74): undefined reference to `for_write_seq_lis_xmit'
collect2: error: ld returned 1 exit status
You may noticed the undefined reference name pattern is similar with yours, if you link with
gcc y.c x.o -W -Wall -L/path/to/your/ifort_lib -lifcore -ldl
The problem should be solved. Depend on the FORTRAN feature you used, you may need link some more ifort library. This part need you do some research and figure out.

Undefined symbols for architecture x86_64 -> symbol(s) not found for architecture x86_64 [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 4 years ago.
I'm learning C++, I have gotten to the point that this works:
helloworld.cpp
#include <iostream>
using namespace std;
int main() {
cout << "Hi" << endl;
return 0;
}
I am using MacOS Mojave and for compilation I use the commands
>> g++ helloworld.cpp
>> ./a.out
This if working fine. Now I want to use header files. Therefore I've created the following files:
test.cpp
#include <iostream>
#include "add.h"
using namespace std;
int main() {
add(4,7);
return 0;
}
add.h
#pragma once
int add(int a, int b);
add.cpp
#include "add.h"
int add(int a, int b) {
return a + b;
}
and When I try to compile this I get:
>> g++ test.cpp
Undefined symbols for architecture x86_64:
"add(int, int)", referenced from:
_main in test-ebc106.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Does anyone have an idea on how to solve this?
g++ test.cpp add.cpp
Every cpp file needs to be compiled to separate .obj files

Linker error while linking DataFlowSanitizer to LLVM IR

I am using pre-built LLVM/Clang 3.8.0 binaries on Ubuntu 16.04.2, 64 bit. I tried to lift a minimal program to LLVM IR, then link the IR to DataFlowSanitizer libraries to produce executable code. In the second step, the process throws a bunch of linker errors.
#include <sanitizer/dfsan_interface.h>
#include <assert.h>
int main(void) {
int i = 1;
dfsan_label i_label = dfsan_create_label("i", 0);
dfsan_set_label(i_label, &i, sizeof(i));
return 0;
}
clang -c -emit-llvm -fsanitize=dataflow test2.c -o test2.bc
clang -fsanitize=dataflow test2.bc -o test2
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/Scrt1.o:
In function _start':(.text+0x20): undefined reference tomain'
/tmp/test2-c642ef.o: In function dfs$main':
test2.bc:(.text+0x96): undefined reference todfs$dfsan_create_label'
test2.bc:(.text+0xeb): undefined reference to dfs$dfsan_set_label'
/tmp/test2-c642ef.o: In functiondfs$dfsw$dfsan_create_label':
test2.bc:(.text+0x16e): undefined reference to
dfs$dfsan_create_label'
/tmp/test2-c642ef.o: In functiondfs$dfsw$dfsan_set_label':
test2.bc:(.text+0x1e4): undefined reference to `dfs$dfsan_set_label'
clang-3.8: error: linker command failed with exit code 1 (use -v to
see invocation)
Any idea what might I be doing wrong?

Usage of undefined extern variable with in the library is giving linker error in macOS

I am creating a dynamic library.
foo.h
extern unsigned int myoperator;
int operate(int a, int b);
foo.cpp
#include "foo.h"
int operate(int a, int b){
switch(myoperator){
case 0:
return a+b;
case 1:
return a-b;
default:
return a*b;
}
}
libfoo is built exceptionally well on linux gcc C++14, however its throwing a linker error in macOS clang C++14. The error is
Undefined symbols for architecture x86_64:
"_myoperator", referenced from:
operate(int, int) in foo.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The closest link to the issue I got on google is https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html
I am not sure if the answer is in it.
If the "real" definition of 'myoperator' variable is in another file which is part of the same project foo belongs to, I think it should be better if you put the line code
extern unsigned int myoperator;
in your cpp file

Can't find c++ libraries on unix

I've written a simple c++ program, test.cpp:
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
cout << s << endl;
return 0;
}
Why does runnning gcc test.cpp -o mytest give me these errors, and more?
Undefined symbols for architecture x86_64:
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string()", referenced from:
_main in cc8rGYVq.o
"std::cin", referenced from:
_main in cc8rGYVq.o
Don't use the executable named gcc to compile and link C++ programs; you must use g++. Not only does it select the appropriate compiler options, it also links with the right libraries for your language (which is the problem you're having here.)
"gcc" command compiles C code, in order to compile C++ code you should use "g++"