Linking error linking static library in Makefile for extern - c++

I am attempting to write a makefile for the Cell Broadband Engine (PS3), which will link an external library.
The Makefile is as follows:
PROJ=apple_sort_ppu
PCC=ppu-g++
CFLAGS=-Wall
LIBS= -lX11 -lspe2 -lpthread
objects = apple_sort_ppu.o lodepng.o ThreadPool.o SPUTask.o
#Imports is for linking the extern spu program library to SPUTask.o. Currently not linking correctly
IMPORTS := spu/lib_process_spu_a.a $(LIBS)
all: $(PROJ)
apple_sort_ppu: $(objects)
$(PCC) $(objects) -o $(LIBS)
apple_sort_ppu.o: apple_sort_ppu.cpp
$(PCC) $(CFLAGS) -c apple_sort_ppu.cpp $(LIBS)
lodepng.o: lodepng.cpp lodepng.h
$(PCC) $(CFLAGS) -c lodepng.cpp
SPUTask.o: SPUTask.cpp SPUTask.h $(IMPORTS) ThreadPool.o
$(PCC) $(CFLAGS) -c SPUTask.cpp
ThreadPool.o: ThreadPool.cpp ThreadPool.h
$(PCC) $(CFLAGS) -c ThreadPool.cpp $(LIBS)
clean:
rm $(objects) *.d
include $(CELL_TOP)/buildutils/make.footer
When I run make on this file, I get :
No rule to make spu/lib_process_spu_a.a, needed by SPUTask.o. STOP
I have confirmed that the library exists in the correct directory. My experience of Makefiles is extremely limited, so I don't really understand what is going on here.
The file causing the problem in the makefile is SPUTask.h, with the header code:
#pragma once
#include "ThreadPool.h"
#include <libspe2.h>
extern spe_program_handle_t process_spu_a;//Program handle
class SPUTask : public Task
{
public:
SPUTask(int i_id = 0);
virtual ~SPUTask(){;}
virtual void execute();
virtual bool hasReturnData(){return false;}
virtual int getTaskID(){return m_id;}
void setData(unsigned char* pData, int pSize);
void setContext(spe_context_ptr_t pContext){mContext = pContext;}
private:
unsigned char* mData __attribute__((aligned(128)));
int m_id;
int mDataSize;
spe_context_ptr_t mContext;
};
process_spu_a has already been compiled into lib_process_spu_a.a in the /spu subdirectory.
Any help would be greatly appreciated.

Related

Undefined reference when compiling a C and C++ file with same header

To make this short, I have a CPP and C code, and my CPP code is trying to reference functions from the C code with a header file. Whenever I run the make command, I end up getting "undefined reference" errors. Here are my codes:
cpp_code.cpp:
extern "C"{
#include "header_code.h";
}
int main(){
cout << "Hello" << endl;
return 0;
}
c_code.c:
#include "header_code.h"
int main(){
printf("Hello");
return 0;
}
void initalize(){
printf("Initilized");
}
header_code.h:
extern void initalize();
makefile:
CXX = g++
CXXFLAGS = -std=c++11
CC = gcc
DEPS = header_code.h
CFLAGS = -I
OBJS = cpp_code.o c_code.o
c: $(OBJS)
$(CXX) -o $# $^ $(CXXFLAGS)
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $<
%.o : %.c $(DEPS)
$(CC) -c $(CFLAGS) $<
Whenever running make it always gives me problems. Can anyone please help me? Thank you for your time reading all of this!
[basic.start.main]
A program that declares a variable main at global scope, or that declares a function main at global scope attached to a named module, or that declares the name main with C language linkage (in any namespace) is ill-formed.
So, as a C++ program, it's ill-formed. Remove the C main function.
Other problems:
In the makefile you have
CFLAGS = -I
and whatever comes after that when compiling will be treated as a directory to search for header files in. In your makefile, that's the source file. Correction:
CFLAGS =
or
CFLAGS = -I.
Your header file is missing a header guard and header files that are supposed to be used by both C and C++ code usually contain the extern "C" part themselves to not burden C++ users to add it.
cpp_code.cpp
#include "header_code.h"
#include <iostream>
int main() {
initalize(); // call the C function
std::cout << "Hello" << std::endl;
}
c_code.c
#include "header_code.h"
#include <stdio.h>
void initalize(){
printf("Initilized");
}
header_code.h
#ifndef HEADER_CODE_H_
#define HEADER_CODE_H_
#ifdef __cplusplus
extern "C" {
#endif
extern void initalize();
#ifdef __cplusplus
}
#endif
#endif
makefile
CXX = g++
CXXFLAGS = -std=c++11
CC = gcc
DEPS = header_code.h
CFLAGS = -I.
OBJS = cpp_code.o c_code.o
c: $(OBJS)
$(CXX) -o $# $^ $(CXXFLAGS)
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $<
%.o : %.c $(DEPS)
$(CC) -c $(CFLAGS) $<

Linked error/Makefile

I am sure this is stupid but i get this linker error
undefined reference to insert_record ,which is a function declared in Operations.hpp,implemented in Operations.cpp and used in main, and i can't find what is wrong in this makefile.
Maybe a pair of rested eyes can spot the problem.
It seems that operations isn't linked although the object is being created.
OBJS = main.o Operations.o CDR.o TBucketList.o RBucketList.o DateTime.o HashTable.o
CC = g++
CXXFLAGS = -W -Wall -Wno-unused -pedantic -c -g
LDFLAGS = -W -Wall -Wno-unused -pedantic -g
werhaus: $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o werhaus
main.o : CDR.hpp Operations.hpp HashTable.hpp
$(CC) $(CXXFLAGS) main.cpp
Operations.o : Operations.hpp HashTable.hpp
$(CC) $(CXXFLAGS) Operations.cpp
TBucketList.o : TBucketList.hpp RBucketList.hpp
$(CC) $(CXXFLAGS) TBucketList.cpp
RBucketList.o : RBucketList.hpp
$(CC) $(CXXFLAGS) RBucketList.cpp
HashTable.o : HashTable.hpp TBucketList.hpp
$(CC) $(CXXFLAGS) HashTable.cpp
CDR.o : CDR.hpp DateTime.hpp
$(CC) $(CXXFLAGS) CDR.cpp
DateTime.o : DateTime.hpp
$(CC) $(CXXFLAGS) DateTime.cpp
clean:
\rm *.o werhaus
Update:
main.cpp :
insert_record(originator_number, aCDR, destination_number, hashtable1, hashtable2, BucketSize);
Operations.hpp:
void insert_record(const char*, CDR*, const char*, const Hashtable*, const Hashtable*, int);
Operations.cpp:
void insert_record(const char* originator_number, CDR* aCDR, const char* destination_number, Hashtable* hashtable1, Hashtable* hashtable2, int Bsize)
All seem fine in main..
There does not seem to be an error in your Makefile. As #G.M. noted, the dependencies of .o to corresponding .cpp are missing, these need to be added.
It can be that insert_record declaration in Operations.hpp does not match the definition in Operations.cpp and you end up with two functions insert_record. Check that the function declaration and definitions match: same return type and argument types, both in the same namespace.
I think you should better use something like this:
NAME= werhaus
CXX= g++ # Use CXX for C++
CXXFLAGS= -W -Wall -Wno-unused -pedantic -g
LDFLAGS= -g # No need for warning flags at linking
SRC= main.cpp \
Operations.cpp \
CDR.cpp \
TBucketList.cpp \
RBucketList.cpp \
DateTime.cpp \
HashTable.cpp
OBJS= $(SRC:.cpp=.o)
$(NAME): $(OBJS)
$(CXX) $(LDFLAGS) $(OBJS) -o $(NAME)
all: $(NAME)
%.o: %.cpp
$(CXX) -o $# -c $< $(CXXFLAGS)
clean:
rm -f $(OBJ)
fclean: clean
rm -f $(NAME)
re: fclean all
.PHONY: all clean fclean re
This type of makefile will avoid you a lot of errors.
Also, you don't need to put hpp files as dependencies.
Good luck.
In Operations.hpp you have a declaration with signature:
void insert_record(
const char*, CDR*,
const char*,
const Hashtable*,
const Hashtable*,
int)
In Operations.cpp you define a function with the different signature:
void insert_record(
const char* CDR*,
const char*,
Hashtable*,
Hashtable*,
int)
So the declaration in Operations.hpp is not in fact implemented in Operations.cpp
and is undefined.

C++ undefined reference with static library

I got 'undefined reference' when compile code with a static library. I have searched a lot of answer which told to use extern "C" or correct the order of parameter when compiling, but those doesn't solve my problem.
I have these :
compiler.hpp
#ifndef COMPILER_H
#define COMPILER_H
int buildTree();
#endif
compile.cpp
#include <compiler.hpp>
int buildTree() {
Package package = new Package();
}
And a lot of another source code, then I build them to lib.a by building them into .o files with -c flag and :
ar rvs lib.a $(OBJS)
My Main.cpp:
#include <compiler.hpp>
int main() {
buildTree();
}
Finally, I build executable file :
LIBS = lib.a
main: main.cpp
$(CPP) $(CPPFLAGS) $(LIBDIR) $^ $(LIBS) -o $#
But g++ complier throws this Error :
undefined reference to `buildTree()'

LTO and virtual destructor weirdness c++

I'm having issues when compiling/Linking with LTO enabled with GCC 4.8.1. I get undefined references to symbols in a DLL even though they seem to be present. The strange thing is, without LTO enabled it compiles and links successfully. LTO seems to struggle when there is a virtual destructor that hasn't been defined in the derived class.
Removing the DECLSPEC makes it compile and work with LTO enabled.
Dependency walker shows the symbols are there. The link time optimizer just can't seem to find them.
Declaring any type of destructor in derived class Test makes it work.
Removing LTO optimization also makes it work successfully, I'm wondering why this is an issue.
Test is a shared library, Main links to the shared library.
Test.h
#include <string>
#ifdef SOURCE
#define DECL __declspec(dllexport)
#warning Exporting!
#else
#define DECL __declspec(dllimport)
#warning Importing!
#endif
class DECL TestBase
{
public:
TestBase(const std::string testing);
virtual ~TestBase();
std::string getTesting();
private:
std::string _testing;
};
class DECL Test : public TestBase
{
public:
Test(const std::string testing);
//~Test(); //removing causes a linker error with LTO! Fine without LTO.
};
Test.cpp
#include "Test.h"
TestBase::TestBase(const std::string testing)
{
_testing = testing;
}
TestBase::~TestBase()
{
}
std::string TestBase::getTesting()
{
return _testing;
}
Test::Test(const std::string testing) :
TestBase(testing)
{
}
/*Test::~Test() //removing causes a linker error with LTO! Fine without LTO.
{
}*/
Main.cpp
#include "Test.h"
#include <iostream>
int main()
{
Test test("testing!");
std::cout << test.getTesting() << std::endl;
return 0;
}
Excuse my messy makefile..
CC=g++
LD=g++
LIBCFLAGS= -O3 -march=pentium4 -mfpmath=sse -flto -fuse-linker-plugin
LIBEXTRA= -c -DSOURCE
LIBLDFLAGS= ${LIBCFLAGS} -shared
LIBSOURCES=Test.cpp
LIBRARY=Test.dll
EXECFLAGS= -O3 -march=pentium4 -mfpmath=sse -flto -fuse-linker-plugin
EXTRA= -c
EXELDFLAGS= ${EXECFLAGS} -L. -lTest
SOURCES=Main.cpp
EXECUTABLE=main
LIBOBJECTS=$(LIBSOURCES:.cpp=.o)
OBJECTS=$(SOURCES:.cpp=.o)
all: $(SOURCES) $(LIBRARY) $(EXECUTABLE)
$(LIBRARY): $(LIBOBJECTS)
$(LD) $(LIBLDFLAGS) $(LIBOBJECTS) -o $#
$(EXECUTABLE): $(OBJECTS)
$(LD) $(EXELDFLAGS) $(OBJECTS) -o $#
$(OBJECTS): CFLAGS := $(EXECFLAGS) $(EXTRA)
$(LIBOBJECTS): CFLAGS := $(LIBCFLAGS) $(LIBEXTRA)
.cpp.o:
#echo "... Making: $#"
$(CC) $(CFLAGS) $< -o $#
clean:
- del /f /q *.o
- del /f /q *.dll
- del /f /q *.exe

Static methods declared but not defined error c++

I have a static method in class as follows in file Convert.h
class Convert
{
public :
static string convertIntToStr(unsigned int integer);
};
In Convert.cpp
string
Convert::convertIntToStr(unsigned int integer)
{
ostringstream ostr;
ostr << integer;
return ostr.str();
}
I use this in some other class method in another .cpp file as Convert::convertIntToStr, but I get linking error, which says undefined reference to Convert::convertIntToStr(unsigned int). Could you please let me know what could be wrong?
With multiple cpp file, you have to link the compiled object file into executable. In IDE like eclipse CDT or Visual stdio, It has been done for you.
To compile and link by yourself, with gcc for example, write Makefile:
CC=g++
CPPFLAGS=-fPIC -Wall -g -O2
all:executable
executable: convert.o other.o
$(CC) $(CPPFLAGS) -o $# $^
convert.o: convert.cpp
$(RC) $^
other.o: other.cpp
$(CC) -o $# -c $^
.PHONY:clean
clean:
rm *.o executable