Very basic: Why won't my makefile work with common suffix - c++

objects = hello.o name.o printing.o
exename = himake
$(exename): $(objects)
$(CC) -o $(exename) $(objects)
%.o: %.cpp
$(CC) -c $^
I am trying to use common suffixes so I do not need to compile 3 files into .o first. This is supposed to do all three with the % wildcard.
It works fine when I do it the long way but not this.
Running the above makefile gives me this error below:
[alex#pcc Dir]$ make
cc -o himake hello.o name.o printing.o
hello.o: In function `__static_initialization_and_destruction_0(int, int)':
hello.cpp:(.text+0x23): undefined reference to `std::ios_base::Init::Init()'
hello.o: In function `__tcf_0':
hello.cpp:(.text+0x66): undefined reference to `std::ios_base::Init::~Init()'
and more that I did not include
Files:
hello.cpp:
// hello.cpp
// standard library
#include <iostream>
#include <string>
using namespace std;
// user defined header files
#include "name.h"
#include "printing.h"
int main ()
{
string name;
name = getName(); // getName is in name.h
printHello(name); // printHello is in print.h
return 0;
}
name.cpp
// name.cpp
// user defined header files
#include "name.h"
#include "printing.h"
string getName()
{
string name;
printGreeting(); // printGreeting is from print.h
getline(cin, name);
return name;
}
name.h
// name.h
#include <iostream>
using namespace std;
string getName();
printing.cpp
// printing.cpp
// user defined include files
#include "printing.h"
void printGreeting(void)
{
cout << "Your name: ";
return;
}
void printHello (string name)
{
cout << "Hi, " << name << endl;
return;
}
printing.h
// printing.h
#include <iostream>
using namespace std;
void printGreeting();
void printHello(string);

Because you use the C compiler frontend program, and not the C++ frontend program.
Change $(CC) to $(CXX).

Related

Moving helper function to header file

In the beginning I had:
main.cpp
#include "something.h"
#include "util.h"
int main() {
sth::something();
utl::little_thing();
}
somehing.h
#ifndef SOMETHING_H
#define SOMETHING_H
namespace sth {
void something();
}
#endif
somehing.cpp
#include "something.h"
#include <string>
#include <iostream>
namespace sth {
void print_me(std::string txt) {
std::cout << txt << std::endl;
}
void something() {
std::cout << "this is something" << std::endl;
print_me("optional");
}
}
util.h
#ifndef UTIL_H
#define UTIL_H
namespace utl {
void little_thing();
}
#endif
util.cpp
#include "util.h"
#include <iostream>
#include <string>
namespace utl {
void little_thing() {
std::cout << "this is little thing" << std::endl;
}
}
Then I though it will be better to have print_me(std::string txt) out of sth namespace. And I put it on utl, declaration on .h file and definition on .cpp file.
At that point the lazy side of me said - would it be better to have it all in one file as was beofore. And I tried:
util.h
#ifndef UTIL_H
#define UTIL_H
#include <string>
#include <iostream>
namespace utl {
void little_thing();
void print_me(std::string txt) {
std::cout << txt << std::endl;
}
}
#endif
something.cpp
#include "something.h"
#include "util.h"
#include <string>
#include <iostream>
namespace sth {
void something() {
std::cout << "this is something" << std::endl;
utl::print_me("optional");
}
}
So I got:
c++ -std=gnu++14 -g -Wall -O3 -c -o main.o main.cpp
c++ -std=gnu++14 -g -Wall -O3 -c -o util.o util.cpp
c++ -std=gnu++14 -g -Wall -O3 -c -o something.o something.cpp
c++ main.o util.o something.o -o main
duplicate symbol __ZN3utl8print_meENSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE in:
main.o
util.o
duplicate symbol __ZN3utl8print_meENSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE in:
main.o
something.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
Which makes sense to me, since util.h is included in main.cpp and something.cpp there are duplicate symbols, right?
Question, is it possible to be as lazy to have it all in the header? Or no way, have to split decalration and definition? I don't care (in this case) to hide the implementation in the .cpp, I just want to move it out of sth.
Maybe move the definition of print_me down to util.cpp and only leave a declaration of it in the util.h file.
Else you get a copy of it in every object file, and then the linker gets confused as they all have the same name (symbol).

Linking shared libraries with executables

I have a small doubt in the compilation of a c++ code along with a shared library.
So I have two files main.cpp and sample.cpp.
main.cpp
#include <iostream>
using namespace std;
#include "sample.h"
myStruct obj;
void populateData() {
obj.s = "hello world";
}
myStruct giveData() {
cout << "Inside main: " << obj.s << endl;
return obj;
}
int main() {
populateData();
}
sample.h
#ifndef SAMPLE_H
#define SAMPLE_H
#include <string>
struct myStruct {
std::string s;
void populateData();
};
myStruct giveData();
#endif
sample.cpp
#include "sample.h"
#include <iostream>
#include <boost/python.hpp>
using namespace std;
void myStruct :: populateData() {
cout << giveData().s;
}
BOOST_PYTHON_MODULE(boosts) {
using namespace boost::python;
class_<myStruct>("struct")
.add_property("s", &myStruct::s)
.def("populateData", &myStruct::populateData)
;
}
I compile the program using
g++ -c -fPIC sample.cpp
g++ -c -fPIC main.cpp
g++ -shared -Wl,-soname,boosts.so -o boosts.so sample.o main.o -lpython2.7 -lboost_python
g++ -o main main.o
./main
Now, when I run the main, it populates the string inside the obj. But when I run a python script, that imports the boosts.so, the obj.s is empty.
I am guessing it is because the library boosts.so is not properly linked with the executable main.
How do I fix this?

Undefined reference to my function

I have some trouble with building the part of my project. Here it is:
utility.h:
#ifndef UTILITY_H
#define UTILITY_H
#include <boost/array.hpp>
#include <boost/shared_ptr.hpp>
#include <fstream>
#include <iostream>
#include <openssl/md5.h>
#include <string>
namespace utility {
typedef boost::array<unsigned char, MD5_DIGEST_LENGTH> md5sum;
typedef boost::shared_ptr<md5sum> md5sum_ptr;
...
md5sum_ptr calculate_md5(const std::string& full_path);
};
#endif //UTILITY_H
utility.cpp:
#include "utility.h"
using namespace utility;
...
md5sum_ptr calculate_md5(const std::string& full_path) {
md5sum_ptr md5(new md5sum);
std::ifstream in(full_path);
std::string content;
in >> content;
MD5((unsigned char*)content.data(), content.size(), md5->data());
return md5;
}
cdaemon.cpp
void CTCPConnection::handle_read_filename(ECommand command, EDataType datatype,
const boost::system::error_code& ec) {
...
case ECommand::GET_MD5:
_send_container<md5sum>(*(calculate_md5(filename)));
async_write(m_socket, m_writebuf,
boost::bind(&CTCPConnection::handle_write_response, shared_from_this(),
placeholders::error));
break;
...
}
}
Makefile:
CC=g++
override CFLAGS+=-c -std=c++11 -Wall -Wextra -Werror
override LFLAGS+=-lboost_log -lpthread -lboost_system -lboost_thread -lcrypto
server: servermain.o cdaemon.o
$(CC) ../build/datatype.o ../build/utility.o build/servermain.o build/cdaemon.o -o build/frtpdaemon $(LFLAGS)
servermain.o: main.cpp
$(CC) $(CFLAGS) main.cpp -o build/servermain.o
cdaemon.o: cdaemon.cpp
$(CC) $(CFLAGS) -DBOOST_LOG_DYN_LINK cdaemon.cpp -o build/cdaemon.o
When I try to build server, I get linker error:
build/cdaemon.o: In function `CTCPConnection::handle_read_filename(utility::ECommand, utility::EDataType, boost::system::error_code const&)':
cdaemon.cpp:(.text+0x127c): undefined reference to `utility::calculate_md5(std::string const&)'
I have already tried to google the solution, but all what I could find were suggestions to change the order of ../build/utility.o and build/cdaemon.o. That didn't help me.
You don't define the function you have declared in the header. A using directive is insufficient when defining functions in a namespace. You'll either need to open the namespace before defining your function or qualify the function with the namespace, e.g.:
utility::md5sum_ptr utility::calculate_md5(const std::string& full_path) {
...
}

undefined reference to `vtable for implementation' error

I wrote some c++ files and after compiling with out make file it works fine . But when using make file it pop out some errors . My codes are :
include directory files :
application.h
#ifndef APPLICATION_H
#define APPLICATION_H
#include "employee.h"
#include "employee_data.h"
#include "employee.h"
...some defintions here...
#endif
employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include "employee_data.h"
#endif
employee_data.h
#ifndef EMPLOYEE_DATA_H
#define EMPLOYEE_DATA_H
typedef struct
{
int emp_id;
char *name,
*dept,
*book,
*time;
}employeedata;
...some codes here...
#endif
library.h
#ifndef LIBRARY_H
#define LIBRARY_H
#include "employee_data.h"
#include "application.h"
using namespace std;
class Library
{
public:
virtual int addE() = 0;
virtual int deleteE() = 0;
virtual int issue() = 0 ;
virtual int returnB() = 0;
virtual int employee() = 0;
};
class implementation : public Library
{
private:
employeedata *emp; /*structure object*/
public:
int addE();
int deleteE();
int issue();
int returnB();
int employee();
};
#endif
main.h
#ifndef MAIN_H
#define MAIN_H
#include "library.h"
class message
{
public:
void errormessage(int);
};
#endif
and my src directory conatins .cpp files . It includes
main.cpp
#include "main.h"
#include "library.h"
#include "employee_data.h"
#include "application.h"
int main()
{
message msg;
/* codes here..../*
}
library_function.cpp
#include "library.h"
#include "employee.h"
#include "main.h"
#include "application.h"
#include "employee_data.h"
int implementation :: addE()
{
}
etc..
error_function.cpp
#include "main.h"
void message :: errormessage(int errno)
{
}
employee_functions.cpp
#include "employee.h"
#include "main.h"
..some code...
display.cpp
#include "employee_data.h"
#include "application.h"
..some code..
thread.cpp
#include "employee.h"
#include "application.h"
...some code..
and my make file is :
CC=g++
FLAGS=-o
CFLAGES=-c -Wall
THREAD=-lpthread
INCLUDE=../include/
SRC=../src/
OBJ=../obj/
OUTPUT=../bin/
$(OUTPUT)vkp:$(OBJ)main.o $(OBJ)library_functions.o $(OBJ)employee_functions.o $(OBJ)display.o $(OBJ)error_function.o $(OBJ)thread.o
$(CC) $(FLAGS) vkp $(OBJ)main.o $(OBJ)library_functions.o $(OBJ)employee_functions.o $(OBJ)display.o $(OBJ)error_function.o $(OBJ)thread.o $(THREAD)
mv vkp $(OUTPUT)
$(OBJ)main.o:$(SRC)main.cpp $(INCLUDE)main.h $(INCLUDE)employee_data.h $(INCLUDE)application.h
$(CC) $(CFLAGS) $(SRC)main.cpp -I $(INCLUDE)
mv main.o $(OBJ)
$(OBJ)library_functions.o:$(SRC)library_functions.cpp $(INCLUDE)library.h $(INCLUDE)employee.h $(INCLUDE)main.h $(INCLUDE)application.h $(INCLUDE)employee_data.h
$(CC) $(CFLAGS) $(SRC)library_functions.cpp -I $(INCLUDE)
mv main.o $(OBJ)
$(OBJ)employee_functions.o:$(SRC)employee_functions.cpp $(INCLUDE)employee.h $(INCLUDE)main.h
$(CC) $(CFLAGS) $(SRC)employee_functions.cpp -I $(INCLUDE)
mv main.o $(OBJ)
$(OBJ)display.o:$(SRC)display.cpp $(INCLUDE)employee_data.h $(INCLUDE)application.h
$(CC) $(CFLAGS) $(SRC)display.cpp -I $(INCLUDE)
mv main.o $(OBJ)
$(OBJ)error_function.o :$(SRC)error_function.cpp $(INCLUDE)main.h
$(CC) $(CFLAGS) $(SRC)error_function.cpp -I $(INCLUDE)
mv main.o $(OBJ)
$(OBJ)thread.o:$(SRC)thread.cpp $(INCLUDE)employee.h $(INCLUDE)application.h
$(CC) $(CFLAGS) $(SRC)thread.cpp -I $(INCLUDE)
mv main.o $(OBJ)
After runing make i got eroor like :
g++ ../src/main.cpp -I ../include/
/tmp/cc09snhj.o: In function `main':
main.cpp:(.text+0x568): undefined reference to `message::errormessage(int)'
main.cpp:(.text+0x5fb): undefined reference to `message::errormessage(int)'
main.cpp:(.text+0x6c5): undefined reference to `message::errormessage(int)'
main.cpp:(.text+0x758): undefined reference to `message::errormessage(int)'
main.cpp:(.text+0x7f3): undefined reference to `message::errormessage(int)'
/tmp/cc09snhj.o: In function `implementation::implementation()':
main.cpp:(.text._ZN14implementationC2Ev[_ZN14implementationC5Ev]+0x1f): undefined reference to `vtable for implementation'
collect2: ld returned 1 exit status
make: *** [../obj/main.o] Error 1
what is wrong on my code ? any problem in make file ? I think the problem is linking the header files . Is this correct way to link header files ? Please help me to get my make file work .
I think you just misspelled CFLAGS in CFLAGES=-c -Wall
I'm guessing this is the case since
g++ ../src/main.cpp -I ../include/
does not have the -c option

Undefined reference to a user defined function

I have seen the standard Undefined Reference to thread from this site but I do not believe it solves my problem. I am not putting header guards on my .cpp files, but still get an undefined reference to a user defined function. Here are my files:
(1) pth_funs.h
// hello from thread <pid>
void* hello(void* ptr);
(2) pth_funs.cpp
#include <stdio.h>
void* hello(void *ptr)
{
char *message;
int pid = (long) ptr;
printf("Hello from thread %i\n", pid);
}
(3) structs.h
#ifndef STRUCTS_H
#define STRUCTS_H
struct grd_str {
long nx;
long ny;
long natoms;
char** atnames;
double* xs;
double* ys;
double** fs;
double** xyzs;
};
#endif
(4) fio.h
#ifndef FIO_H
#define FIO_H
#include <iostream>
#include <string.h>
#include "structs.h"
void read_grd(std::string, grd_str);
#endif
(5) fio.cpp
#include <string.h>
#include "structs.h"
#include "fio.h"
void read_grd( std::string fname, grd_str &grd)
{
grd.nx = 10;
grd.ny = 10;
}
(6) and finally, xdriver.cpp
#include <iostream> // needed for cout, endl, etc
using namespace std; // needed for cout, endl, etc
#include <pthread.h> // needed for pthreads
#include <string.h> // string handling
#include "pth_funs.h" // pthread function headers
#include "structs.h"
#include "fio.h"
int main(int argc, char** argv)
{
// thread stuff
int nthreads = 4;
pthread_t rank[4];
int iret[4];
// file stuff
string base_dir = "D:\\cygwin64\\home\\Robert\\code\\C\\form_reconstruction\\data\\";
string fname;
// topology stuff
int nx, ny;
double* xs;
double* ys;
double** fs;
grd_str grd;
for(long tid = 0; tid < nthreads; tid++)
{ iret[tid] = pthread_create( &rank[tid], NULL, hello, (void*) tid); }
fname = base_dir;
fname.append("adf\\adf.6.grd");
cout << "Filename: " << fname << endl;
read_grd(fname, grd);
}
I am compiling this using a Makefile which is as follows:
cc=g++
exe=create_grd.exe
flags=-pthread
hds= pth_funs.h fio.h structs.h
objs= pth_funs.o fio.o
all: create_grd.exe
create_grd.exe: xdriver.cpp $(hds) $(objs)
$(cc) -o $(exe) $(objs) xdriver.cpp
pth_funs.o: pth_funs.cpp pth_funs.h
$(cc) -c pth_funs.cpp $(flags)
fio.o: fio.cpp fio.h
$(cc) -c fio.cpp $(flags)
clean:
rm -rf *.o
However, upon compilation I get
g++ -c pth_funs.cpp -lpthread
g++ -c fio.cpp -lpthread
g++ -o create_grd.exe pth_funs.o fio.o xdriver.cpp -lpthread
/tmp/ccdaBayB.o: In function `main':
xdriver.cpp:(.text+0x16f): undefined reference to `read_grd(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, grd_str)'
collect2: ld returned 1 exit status
make: *** [create_grd.exe] Error 1
but I have no idea why my main routine can't find read_grd since I believe I am properly defining it and including it. What am I doing wrong?
Your declaration and definition of read_grd do not have matching arguments. One takes a grd_str as its second argument, the other takes a grd_str&. Since xdriver.cpp includes fio.h, it sees and attempts to use the former function, but the linker can't find a definition for it anywhere. Chances are you want to change your declaration in fio.h to:
void read_grd(std::string, grd_str&);
Now the definition for this function is provided by fio.cpp.