How to execute C++11 with makefile - linux

I have a problem when I execute commmand "make" in terminal ubuntu.
My code of makefile is:
all: temp p1
%: %.cc g++ -lm -lcrypt -O2 -std=c++11 -pipe $< -o $#
Of course, my files are temp.cc and p1.cc, but my problem is in p1.cc, where the code is:
#include <bits/stdc++.h>
using namespace std;
int main(){
vector<int> vec = {4,6,8,9,8,7,1,3,4,5,0,1};
for(auto i : vec)
cout<<i<<" ";
cout<<endl;
return 0;}
My error using 'make' is:
eabg97#EABG:~/P$ make
g++ p1.cc -o p1
p1.cc: In function ‘int main()’:
p1.cc:7:44: error: in C++98 ‘vec’ must be initialized by constructor, not by ‘{...}’
vector<int> vec = {4,6,8,9,8,7,1,3,4,5,0,1};
^
p1.cc:7:44: error: could not convert ‘{4, 6, 8, 9, 8, 7, 1, 3, 4, 5, 0, 1}’ from ‘<brace-enclosed initializer list>’ to ‘std::vector<int>’
p1.cc:9:11: error: ‘i’ does not name a type
for(auto i : vec)
^
p1.cc:11:2: error: expected ‘;’ before ‘cout’
cout<<endl;
^
p1.cc:12:2: error: expected primary-expression before ‘return’
return 0;
^
p1.cc:12:2: error: expected ‘)’ before ‘return’
make: *** [p1] Error 1
Using the next command lines, compile:
g++ --std=c++11 p1.cc -o p1
and executing is okay:
eabg97#EABG:~/P$ ./p1
4 6 8 9 8 7 1 3 4 5 0 1
Please help me, I don't understand why there is a problem, thanks for your support :)

This is wrong:
all: temp p1
%: %.cc g++ -lm -lcrypt -O2 -std=c++11 -pipe $< -o $#
You should either add a newline and an initial TAB, like this:
all: temp p1
%: %.cc
g++ -lm -lcrypt -O2 -std=c++11 -pipe $< -o $#
(the first char on the third line must be a TAB character) or you need to insert a semicolon like this:
all: temp p1
%: %.cc ; g++ -lm -lcrypt -O2 -std=c++11 -pipe $< -o $#
What is your makefile doing? First, that statement all in one line without any newline/TAB or semicolon is considered by make to be a single pattern rule with a target % and prerequisites %.cc, g++, -lm, -lcrypt, etc. And, since there's no recipe, you're basically deleting that pattern rule (which doesn't exist anyway) since a pattern rule with no recipe deletes the pattern rule. So that line is essentially a no-op and does nothing.
So what happens? Make has a bunch of built-in rules that it uses to create things if you don't tell it how to do so, and there's a built-in rule that knows how to create a program from a .cc file, so make uses that. But of course, that built-in rule doesn't have any of your customizations.
It's simpler to use make's built-in rule and use the standard make variables to control it:
CXX := g++
CXXFLAGS := -std=c++11 -pipe
LDLIBS := -lm -lcrypt
all: temp p1
That's all you need, if you don't want to write your own rule.

Related

Compile error on cygwin with strerror_r

I am getting a build error using make:
g++ -std=c++11 -DHAVE_CONFIG_H -I. -I../src/config -I. -I./obj -DBOOST_SP_USE_STD_ATOMIC -DBOOST_
AC_USE_STD_ATOMIC -pthread -I/usr/include -I./leveldb/include -I./leveldb/helpers/memenv -I./secp2
56k1/include -I./univalue/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -std=c99 -D_XOPEN_SOURCE=
500 -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wno-unused-parameter -MT libbitcoin_co
mmon_a-netbase.o -MD -MP -MF .deps/libbitcoin_common_a-netbase.Tpo -c -o libbitcoin_common_a-netbase
.o `test -f 'netbase.cpp' || echo './'`netbase.cpp
cc1plus: warning: command line option `-std=c99' is valid for C/ObjC but not for C++
In file included from /usr/include/boost/assert.hpp:58:0,
from /usr/include/boost/range/size.hpp:23,
from /usr/include/boost/range/functions.hpp:20,
from /usr/include/boost/range/iterator_range_core.hpp:38,
from /usr/include/boost/range/iterator_range.hpp:13,
from /usr/include/boost/range/as_literal.hpp:22,
from /usr/include/boost/algorithm/string/case_conv.hpp:19,
from netbase.cpp:25:
netbase.cpp: In function `bool LookupIntern(const char*, std::vector<CNetAddr>&, unsigned int, bool)
':
netbase.cpp:95:39: warning: comparison between signed and unsigned integer expressions [-Wsign-compa
re]
assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in));
~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
netbase.cpp:101:39: warning: comparison between signed and unsigned integer expressions [-Wsign-comp
are]
assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6));
~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
netbase.cpp: In function `std::string NetworkErrorString(int)':
netbase.cpp:720:41: error: `strerror_r' was not declared in this scope
if (strerror_r(err, buf, sizeof(buf)))
^
^
Evidently cygwin does support strerror_r as per https://cygwin.com/cygwin-api/compatibility.html#std-susv4
Code snippet where the code is breaking:
#ifdef STRERROR_R_CHAR_P /* GNU variant can return a pointer outside the passed buffer */
s = strerror_r(err, buf, sizeof(buf));
#else /* POSIX variant always returns message in buffer */
s = buf;
if (strerror_r(err, buf, sizeof(buf)))
buf[0] = 0;
#endif
Can someone guide me as to how I can fix this ?
TIA

undefined symbol:_ZTVN10__cxxabiv121__vmi_class_type_infoE error

When I run python eval.py, it comes to the error::
ImportError: /home/aa/EAST/lanms/adaptor.so: undefined
symbol:_ZTVN10__cxxabiv121__vmi_class_type_infoE
I uses $make clean && make but it is still give me the same error and with some warring during execute the make
This is the makefile::
CXXFLAGS = -I include -std=c++11 -O3 $(shell python3-config --cflags)
LDFLAGS = $(shell python3-config --ldflags)
DEPS = lanms.h $(shell find include -xtype f)
CXX_SOURCES = adaptor.cpp include/clipper/clipper.cpp
LIB_SO = adaptor.so
$(LIB_SO): $(CXX_SOURCES) $(DEPS)
$(CXX) -o $# $(CXXFLAGS) $(LDFLAGS) $(CXX_SOURCES) --shared -fPIC
clean:
rm -rf $(LIB_SO)
when I use make command it show these warning::
/usr/bin/gcc-7 -o adaptor.so -I include -std=c++11 -O3 -I/home/ashwaq/anaconda3/include/python3.5m -I/home/aa/anaconda3/include/python3.5m -Wno-unused-result -Wsign-compare -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O3 -pipe -flto -fuse-linker-plugin -ffat-lto-objects -DNDEBUG -fwrapv -O3 -Wall -Wstrict-prototypes -L/home/ashwaq/anaconda3/lib/python3.5/config-3.5m -L/home/ashwaq/anaconda3/lib -lpython3.5m -lpthread -ldl -lutil -lrt -lm -Xlinker -export-dynamic adaptor.cpp include/clipper/clipper.cpp --shared -fPIC
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
In file included from include/pybind11/pytypes.h:12:0,
from include/pybind11/cast.h:13,
from include/pybind11/attr.h:13,
from include/pybind11/pybind11.h:43,
from adaptor.cpp:1:
adaptor.cpp: In function ‘PyObject* PyInit_adaptor()’:
include/pybind11/common.h:232:34: warning: ‘PyObject* pybind11_init()’ is deprecated: PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE [-Wdeprecated-declarations]
return pybind11_init(); \
^
adaptor.cpp:53:1: note: in expansion of macro ‘PYBIND11_PLUGIN’
PYBIND11_PLUGIN(adaptor) {
^~~~~~~~~~~~~~~
include/pybind11/common.h:217:22: note: declared here
static PyObject *pybind11_init(); \
^
adaptor.cpp:53:1: note: in expansion of macro ‘PYBIND11_PLUGIN’
PYBIND11_PLUGIN(adaptor) {
^~~~~~~~~~~~~~~
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
include/clipper/clipper.cpp: In member function ‘void ClipperLib::Clipper::FixupFirstLefts3(ClipperLib::OutRec*, ClipperLib::OutRec*)’:
include/clipper/clipper.cpp:3665:13: warning: unused variable ‘firstLeft’ [-Wunused-variable]
OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
I use::
ubuntu-17.4
tensorflow-1.4.0
python-3.5
gcc-7.0.1
cuda-8.0

dylib dynamic library calling a dylib : Undefined symbols for architecture i386

Under mac os x with g++ from gcc-5.2 I am trying to do the following : create a dylib exporting a class defined by header tmp8bis_dylib.h and source tmp8bis_dylib.cpp, and then create another dylib out of a source file tmp8bis.cpp using and linking to the previous dylib. Header and sources are in the same directory. I compile as follows :
g++-5.2.0 -m32 -Wall -g -c ./tmp8bis_dylib.cpp
g++-5.2.0 -m32 -dynamiclib ./tmp8bis_dylib.o -o ./tmp8bis_dylib.dylib
g++-5.2.0 -m32 -Wall -g -c ./tmp8bis.cpp
g++-5.2.0 -m32 -dynamiclib ./tmp8bis.o -o ./tmp8bis.dylib
and get this :
Undefined symbols for architecture i386:
"complex::cmodule(double, double)", referenced from:
_mymodule in tmp8bis.o
"complex::complex(double, double)", referenced from:
_mymodule in tmp8bis.o
"complex::~complex()", referenced from:
_mymodule in tmp8bis.o
ld: symbol(s) not found for architecture i386
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
Obviously, I tried to pass various include and library paths with -I and -L flags respectively, with the very same result... Any idea ?
Files are below :
For tmp8bis_dylib.h :
#ifndef TMP_8_BIS_DYLIB_H
#define TMP_8_BIS_DYLIB_H
class complex
{
public:
double real;
double imag;
public:
complex();
complex(double x);
complex(double x,double y);
double cmodule(double x, double y);
~complex();
};
#endif
For tmp8bis_dylib.cpp :
#include "./tmp8bis_dylib.h"
#include <math.h>
extern "C"
{
complex::complex()
{
real = 0.0 ;
imag = 0.0 ;
}
complex::complex(double x)
{
real = x ;
imag = 0.0 ;
}
complex::complex(double x,double y)
{
real = x ;
imag = y ;
}
double complex::cmodule(double x, double y)
{
double res = sqrt(x*x+y*y);
return res ;
}
complex::~complex()
{
}
}
For tmp8bis.cpp :
#include <math.h>
#include "./tmp8bis_dylib.h"
extern "C"
{
double mymodule(double x, double y)
{
complex z(x,y);
double ret = z.cmodule(x,y);
return ret;
}
}
Precision. -m32 is because I need 32 bits dylib because the final dylib will be plugged into excel 2011's (for mac) VBA, which is 32 bits.
EDIT. Following Brett Hale's comment about Apple's advises about dylibs, I added
#define EXPORT __attribute__((visibility("default")))
after the #include's from tmp8bis.cpp, and EXPORT's for all its member functions, and compiled as follows :
g++-5.2.0 -m32 -Wall -g -c ./tmp8bis_dylib.cpp
g++-5.2.0 -m32 -dynamiclib ./tmp8bis_dylib.o -fvisibility=hidden -o ./tmp8bis_dylib.dylib
did a sudo cp ./tmp8bis_dylib.dylib /opt/lib/libtmp8bis_dylib.dylib and then compiled :
g++-5.2.0 -m32 -Wall -g -c ./tmp8bis.cpp
g++-5.2.0 -m32 -dynamiclib ./tmp8bis.o -o ./tmp8bis.dylib -L/opt/lib
and got the same result as before... Nor did
g++-5.2.0 -m32 -dynamiclib ./tmp8bis.o -o ./tmp8bis.dylib -ltmp8bis_dylib.dylib
make my day.
Without resorting to #define EXPORT __attribute__((visibility("default"))) or any -fvisibility=hidden
g++-5.2.0 -m32 -Wall -fpic -g -c ./tmp8bis_dylib.cpp
g++-5.2.0 -m32 -shared ./tmp8bis_dylib.o -o ./libtmp8bis_dylib.dylib
g++-5.2.0 -m32 -Wall -g -c ./tmp8bis.cpp
g++-5.2.0 -m32 -shared ./tmp8bis.o -o ./tmp8bis.dylib -L. -ltmp8bis_dylib
finally worked. I did not managed to succeed without -fpic, naming libtmp8bis_dylib.dylib and using -ltmp8bis_dylib.

Autotools: Final make command in wrong order

I use GNU Autotools in order to build/configure my mini application.
Here is my configure.ac:
AC_INIT([Tutorial Program], [1.0])
AM_INIT_AUTOMAKE
AC_PROG_CXX
AC_SUBST([GENERAL_INCD], ["-I../Src"])
AC_SUBST([GENERAL_LIBD], ["-L../../Lib"])
AC_SUBST([SOLCPP_LIBS], ["-lsolcpp -lcfsqp"])
AC_SUBST([FFTWPP_INCD], ["-I../fftw++-1.09"])
AC_SUBST([FFTWPP_LIBS], ["../fftw++-1.09/fftw++.o"])
PKG_CHECK_MODULES([GSL], [gsl])
PKG_CHECK_MODULES([FFTW3], [fftw3])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
And here is my Makefile.am:
bin_PROGRAMS = test1
test1_SOURCES = test1.cpp
test1_CPPFLAGS = $(GENERAL_INCD) $(FFTWPP_INCD) $(GSL_CFLAGS) $(FFTW3_CFLAGS)
test1_LDFLAGS= $(GENERAL_LIBD) $(FFTWPP_LIBS) $(SOLCPP_LIBS) $(GSL_LIBS) $(FFTW3_LIBS)
The problem is when I run ./configure and then make, it tries to do:
g++ -g -O2 -L../../Lib ../fftw++-1.09/fftw++.o -lsolcpp -lcfsqp -lgsl -lgslcblas -lm -lfftw3 -lm -o test1 test1-test1.o
test1-test1.o
Although the correct expected command is the following one:
g++ -O2 test1-test1.o -o test1 -L../../Lib -lsolcpp -lcfsqp ../fftw++-1.09/fftw++.o -lgsl -lgslcblas -lm -lfftw3 -lm
How to change configure.ac and Makefile.am ?
Thank you very much
It appears that you just want ../fftw++-1.09/fftw++.o to come after -lsolcpp -lcfsqp in which case you merely need to list FFTWPP_LIBS after SOLCPP_LIBS:
test1_LDFLAGS = $(GENERAL_LIBD) $(SOLCPP_LIBS) $(FFTWPP_LIBS) $(GSL_LIBS) $(FFTW3_LIBS)

Linking cuda object file

I have one .cu file that contains my cuda kernel, and a wrapper function that calls the kernel. I have a bunch of .c files as well, one of which contains the main function. One of these .c files calls the wrapper function from the .cu to invoke the kernel.
I compile these files as follows:
LIBS=-lcuda -lcudart
LIBDIR=-L/usr/local/cuda/lib64
CFLAGS = -g -c -Wall -Iinclude -Ioflib
NVCCFLAGS =-g -c -Iinclude -Ioflib
CFLAGSEXE =-g -O2 -Wall -Iinclude -Ioflib
CC=gcc
NVCC=nvcc
objects := $(patsubst oflib/%.c,oflib/%.o,$(wildcard oflib/*.c))
table-hash-gpu.o: table-hash.cu table-hash.h
$(NVCC) $(NVCCFLAGS) table-hash.cu -o table-hash-gpu.o
main: main.c $(objects) table-hash-gpu.o
$(CC) $(CFLAGSEXE) $(objects) table-hash-gpu.o -o udatapath udatapath.c $(LIBS) $(LIBDIR)
So far everything is fine. table-hash-gpu.cu calls a function from one of the .c files. When linking for main, I get the error that the function is not present. Can someone please tell me what is going on?
nvcc compiles both device and host code using the host C++ compiler, which implies name mangling. If you need to call a function compiled with a C compiler in C++, you must tell the C++ compiler that it uses C calling conventions. I presume that the errors you are seeing are analogous to this:
$ cat cfunc.c
float adder(float a, float b, float c)
{
return a + 2.f*b + 3.f*c;
}
$ cat cumain.cu
#include <cstdio>
float adder(float, float, float);
int main(void)
{
float result = adder(1.f, 2.f, 3.f);
printf("%f\n", result);
return 0;
}
$ gcc -m32 -c cfunc.c
$ nvcc -o app cumain.cu cfunc.o
Undefined symbols:
"adder(float, float, float)", referenced from:
_main in tmpxft_0000b928_00000000-13_cumain.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Here we have code compiled with nvcc (so the host C++ compiler) trying to call a C function and getting a link error, because the C++ code expects a mangled name for adder in the supplied object file. If the main is changed like this:
$ cat cumain.cu
#include <cstdio>
extern "C" float adder(float, float, float);
int main(void)
{
float result = adder(1.f, 2.f, 3.f);
printf("%f\n", result);
return 0;
}
$ nvcc -o app cumain.cu cfunc.o
$ ./app
14.000000
It works. Using extern "C" to qualify the declaration of the function to the C++ compiler, it will not use C++ mangling and linkage rules when referencing adder and the resulting code links correctly.

Resources