makefile error lib/Scrt1.o undefined reference to `main' - c++

I glanced tons of similar topic, but I couldn't recognize solution
I tried mine and many variations. Even below the simplest code compiling doesn't work. I think skipping little thing...
Could you help me?
# Make file for test.c file dependencies external C libraries
CC = g++
C = gcc
FLAGS = -Wextra -g
INCLUDES = -lm
test: randomArray.o test.o
$(CC) $(FLAGS) $(INCLUDES) randomArray.o -o test
test.o: randomArray.o
$(C) $(FLAGS) $(INCLUDES) -c test.cpp
randomArray.o: randomArray.c
$(C) $(FLAGS) $(INCLUDES) -c randomArray.c
Error message
make
g++ -Wextra -g -lm randomArray.o -o test
/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../lib/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [makefile:9: test] Error 1
#include <iostream>
#include "randomArray.h"
using namespace std;
int main(int argc, char const *argv[])
{
int *bit=randomArray(64);
for (int i = 0; i < 64; i++)
{
cout<<bit[i]<< "\n";
}
return 0;
}

You forgot to link in test.o:
test: randomArray.o test.o
$(CC) $(FLAGS) $(INCLUDES) randomArray.o test.o -o test
Also note that test.o: randomArray.o is probably wrong. It says test.o depends on randomArray.o, which it doesn't. It depends on test.cpp.
test.o: test.cpp
$(CC) $(FLAGS) $(INCLUDES) -c test.cpp

Related

Makefile for linking an extern global

I'm trying to use the g_struct variable that's defined in struct.cpp and declared in struct.hpp inside the test.cpp, but the linking fails. Why is that?
// test.cpp
#include "struct.hpp"
int main(void)
{
g_struct.a = 1;
return 0;
}
// struct.cpp
#include "struct.hpp"
Struct g_struct;
// struct.hpp
#pragma once
struct Struct {
int a;
};
extern Struct g_struct;
# Makefile
CC = g++
all: struct.o test
test: test.cpp
$(CC) -o test test.cpp
struct.o: struct.cpp
$(CC) -c -o struct.o struct.cpp
.PHONY: clean
clean:
rm -f *.o test
Linking error:
$ make
g++ -c -o struct.o struct.cpp
g++ -o test test.cpp
/tmp/ccgSoJhd.o: In function `main':
test.cpp:(.text+0xd): undefined reference to `g_struct'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'test' failed
make: *** [test] Error 1
If I link without the -c flag, I get:
$ make
g++ -o struct.o struct.cpp
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:9: recipe for target 'struct.o' failed
make: *** [struct.o] Error 1
You have to link struct.o, which has Struct g_struct;.
test: test.cpp
$(CC) -o test test.cpp struct.o

c++ Makefile compiling-gflags

I am having trouble compiling using a makefile and including gflags. I have not done Makefiles in a while. The compile error I am getting is related to gflags
This is my makefile:
CXX = g++
CPPFlags = -g -Wall -std=c++11
LDLIBS = -lgflags
pa1: Main.cpp PA1.o Node.o
$(CXX) $(CPPFlags) $(LDFLAGS) Main.cpp Node.o PA1.o -o PA1
PA1.o:PA1.h PA1.cpp
$(CXX) $(CPPFlags) -c PA1.cpp -o PA1.o
Node.o:Node.h Node.cpp
$(CXX) $(CPPFlags) -c Node.cpp -o Node.o
This is my main.cpp
#include "PA1.h"
#include <string>
#include <iostream>
#include <fstream>
#include <string>
#include <gflags/gflags.h>
DEFINE_string(root, "0,0", "Root");
int main(int argc, char *argv[])
{
gflags::ParseCommandLineFlags(&argc, &argv, true);
PA1 run= PA1(argv[2]);
std::string rc=FLAGS_root;
int r= rc[0];
int c= rc[2];
if(run.ReadMaze()==-1)
{
return -1;
}
run.SolveMaze(r,c);
return 0;
}
edit:
This is the error message
g++ -g -Wall -std=c++11 Main.cpp Node.o PA1.o -o PA1
/tmp/ccIdQf46.o: In function `main':
/home/peteryan/Documents/Main.cpp:10: undefined reference to
`google::ParseCommandLineFlags(int*, char***, bool)'
/tmp/ccIdQf46.o: In function `__static_initialization_and_destruction_0(int,
int)':
/home/peteryan/Documents/Main.cpp:7: undefined reference to
`google::FlagRegisterer::FlagRegisterer(char const*, char const*, char
const*, char const*, void*, void*)'
collect2: error: ld returned 1 exit status
Makefile:5: recipe for target 'pa1' failed
make: *** [pa1] Error 1
The linker does not appear to be linking with with -lgflags and your Makefile is likely the cause. You should put your LDLIBS at the end of your build arguments. This generic Makefile will compile all the .cpp sources and link all the object files in the same directory. It also should track your header file dependencies. Notice the LDLIBS at the end of the build directive. Give it a try for your program.
program_name := PA1
CXX := g++
CXXFLAGS := —g -Wall std=c++11
LDLIBS := -lgflags
source_files := $(wildcard *.cpp)
objects := ${source_files:.cpp=.o}
all: $(program_name)
$(program_name): $(objects)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $(program_name) $(objects) $(LDLIBS)
depend: .depend
.depend: $(source_files)
rm -f ./.depend
$(CXX) $(CXXFLAGS) -MM $^>>./.depend;
clean:
rm -f $(objects)
distclean: clean
rm -f *~ .depend
include .depend

mac build has undefined symbol where linux build did not for same code

We have gcc 4.2 for mac, and gcc 4.4 for linux. When I build the same code, I get the following undefinded symbol:
"MyClassNameSpecific1::MyClassNameSpecific1(int, int, int, className::class1 const&, className::class2 const&, int, int)", referenced from:
MyOtherClassName::mContainer() in MyOtherClassName.o
ld: symbol(s) not found for architecture x86_64
The code looks like this for MyClassName.h:
class MyClassNameSpecific1;
class MyClassNameSpecific2;
class MyClassNameSpecific1
{
public:
MyClassNameSpecific1(const string &param1);
virtual ~MyClassNameSpecific1() {}
}
class MyClassNameSpecific2: public classU::UData
{
public:
MyClassNameSpecific2(int width, int height, int breadth, const className::class1 &dType, const className::class2 &layout, int tWidth, int tHeight);
};
The MyClassName.cpp has this:
#include "MyClassName.h"
MyClassNameSpecific1::MyClassNameSpecific1(const string &param1) : classU::UData()
{
//does things here
}
MyClassNameSpecific2::MyClassNameSpecific2(int width, int height, int breadth, const className::class1 &dType, const className::class2 &layout, int tWidth, int tHeight) : classU::UData()
{
//does things here
}
I'm not sure what could cause the undef in one but not the other. Is anyone aware of a difference in gcc for this kind of situation? My makefile has all: MyClassName then other classes. I don't see any differences in the parameter signatures between .h and .cpp file for MyClassNameSpecific2.
I tried making sure I used the complete className::class1 in both the .h and .cpp files, but it still had the same undef. Also, I tried adding class MyClassNameSpecific2, where it only had class MyClassNameSpecific1 at the top of the MyClassName.h file, but it didn't change the undef. I tried googling the problem, but nothing pertinent turned up. Maybe there's another thing I could have searched for, but I'm not sure. I left out #includes for the little class definitions in my .h and .cpp file.
That would be great if anyone had something to try, even if it's a different nomenclature for the parameters that I didn't think of.
Added makefile:
.SUFFIXES: .cpp
DEP_DIR = ../dependencies
CC = g++
OS := $(shell uname -s)
ifeq ($(OS),Darwin)
#set LIB_DIR
LIB_DIR1=darwin64_gcc42/lib
LIB_DIR2=darwin64_gcc44/lib
else
LIB_DIR=linux64_gcc44/lib
endif
INCDIRS = -I. -I../include \
-I$(DEP_DIR)/className/include \
-I$(DEP_DIR)/classNameOther/include
#C++FLAGS = -c -fPIC -g -O2 -DLINUX -D_DEBUG -D_FILE_OFFSET_BITS=64 -m64 -Wall
C++FLAGS = -c -fPIC -O2 -DLINUX -DNDEBUG -D_FILE_OFFSET_BITS=64 -m64 -Wall
ifeq ($(OS),Darwin)
LDFLAGS = -m64 -pthread -ldl -shared -L../$(LIB_DIR1)/release \
-L$(DEP_DIR)/className/$(LIB_DIR1) \
-L$(DEP_DIR)/classNameOther/$(LIB_DIR2)/release
else
LDFLAGS = -m64 -pthread -ldl -shared -L../$(LIB_DIR)/release \
-L$(DEP_DIR)/className/$(LIB_DIR) \
-L$(DEP_DIR)/classNameOther/$(LIB_DIR)/release
endif
LDLIBS = -llittleClass -lclassName -lclassNameOther -lclassNameOthermalloc
all: MyClassName MyOtherClassName AnotherClass2 AnotherClass3 AnotherClass4 AMoreOverallClass
AMoreOverallClass: AMoreOverallClass.o
$(CC) AMoreOverallClass.o $(LDFLAGS) -o $# $(LDLIBS)
...
.cpp.o:
$(CC) $(C++FLAGS) $(INCDIRS) $< -o $#
clean:
rm -rf *.o all
Here is make output at command line:
mcle#engmacvi01(577)% make
g++ -c -fPIC -O2 -DLINUX -DNDEBUG -D_FILE_OFFSET_BITS=64 -m64 -Wall -I. -I../include -I../dependencies/className/include -I../dependencies/classNameOther/include MyClassName.cpp -o MyClassName.o
g++ MyClassName.o -m64 -pthread -ldl -shared -L../darwin64_gcc42/lib/release -L../dependencies/className/darwin64_gcc42/lib -L../dependencies/classNameOther/darwin64_gcc44/lib/release -o MyClassName-ludm -lclassName -lclassNameOther -lclassNameOthermalloc
g++ -c -fPIC -O2 -DLINUX -DNDEBUG -D_FILE_OFFSET_BITS=64 -m64 -Wall -I. -I../include -I../dependencies/className/include -I../dependencies/classNameOther/include AnotherClass.cpp -o AnotherClass.o
g++ AnotherClass.o -m64 -pthread -ldl -shared -L../darwin64_gcc42/lib/release -L../dependencies/className/darwin64_gcc42/lib -L../dependencies/classNameOther/darwin64_gcc44/lib/release -o AnotherClass -llittleClass -lclassName -lclassNameOther -lclassNameOthermalloc
Undefined symbols for architecture x86_64:
"MyClassNameSpecific1::MyClassNameSpecific1(int, int, int, className::class1 const&, className::class2 const&, int, int)", referenced from:
AnotherClass::mContainer() in AnotherClass.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [AnotherClass] Error 1
Also, MyOtherClassName.cpp:
UReturnClass &MyOtherClassName::mContainer()
{
if (!m_mContainerPtr)
{
m_mContainerPtr = new UReturnClass();
UMPtr md = new MyClassNameSpecific2(m_width, m_height, m_bands, m_dataType, m_dataLayout, m_tileWidth, m_tileHeight);
m_mContainerPtr->setMdata(md);
}
return *m_mContainerPtr;
}
MyOtherClassName.h:
className::class1 m_dType;
className::class2 m_dLayout;
The fix for this was to change the makefile so that it built it all in one step instead of separate steps for each class, since they were trying to link separately to get the .o file for each one, before putting it all together at the end. I'm not sure why the linux build was fine doing this separately and the mac build was not. Class names changed to protect the innocent.
SRCS=UMetaPlugin.cpp UDataPlugin.cpp UForPlugin.cpp UFacPlugin.cpp UMTransPlugin.cpp UPlugin.cpp
objects=$(patsubst %.cpp,%.o,$(SRCS))
all: $(appn)
$(appn): $(objects)
$(CC) $(LDFLAGS) -o $# $(objects) $(LDLIBS)
.cpp.o:
$(CC) $(C++FLAGS) $(INCDIRS) $< -o $#

Undefined reference in main Makefile

I did a sample project in linux but i am getting error while running main Makefile
Project Info:
project/database folder having files database.h , database.cpp , bulid-database ,Makefile
database.h
/*data base file*/
#include<iostream>
using namespace std;
class mydatabase
{
public:
mydatabase(int a , int b);
int sum(){return m_a +m_b;}
int diff(){return m_a -m_b;}
int mul(){return m_a *m_b;}
float div(){return m_a /m_b;}
int reminder(){return m_a %m_b;}
private:
int m_a , m_b;
};
database.cpp
#include "database.h"
mydatabase::mydatabase(int a ,int b):m_a(a) , m_b(b)
{
}
bulid-database
make
if [ -f libdatabase.a ];
then
echo "Database-Library Build Success"
cp libdatabase.a ../LIBs/
else
echo "databse-Library Build Failure"
fi
Makefile
HEADERFILES = $(wildcard *.h)
CPPFILES = $(wildcard *.cpp)
OBJFILES = $(patsubst %.cpp,%.o ,$(wildcard *.cpp))
$(OBJFILES): %.o : %.cpp $(HEADERFILES)
g++ -c -o $# $<
ar ruv libdatabase.a $#
ranlib libdatabase.a
project/Main folder having files main.cpp , Makefile
main.cpp
#include "database.h"
#include <iostream>
int main()
{
mydatabase *obj = new mydatabase(10 ,5);
std::cout<<"sum is"<<obj->sum()<<endl;
std::cout<<"diff is"<<obj->diff()<<endl;
std::cout<<"mul is"<<obj->mul()<<endl;
std::cout<<"div is"<<obj->div()<<endl;
std::cout<<"reminder is"<<obj->reminder()<<endl;
getchar();
return 0;
}
Makefile
CC = g++
INCPATH = -I. \
-I.. \
-I../database
LIBPATH = -L../LIBs
LDFLAGS = ${LIBPATH}/libdatabase.a
CFLAGS = ${INCPATH}
testdate:main.o
$(CC) $(CFLAGS) -o testdate main.o $(LDFLAGS)
main.o:main.cpp
$(CC) $(CFLAGS) -c -o main.o main.cpp
ISSUE: database make file is working fine but main Makefile i am having some issue like
Error: main.o: In function main':
main.cpp:(.text+0x92): undefined reference tomydatabase::mydatabase(int, int)'
collect2: ld returned 1 exit status
This line is wrong:
$(CC) $(CFLAGS) -o testdate $(LDFLAGS) main.o
because the library should be specificed AFTER the object main.o on the line. This is due to the way the linker handles the objects. Look at this example:
gcc -o test someobject.o library.a
The linker will:
look up all undefined references of someobject.o and store them
then it opens library.a and resolves the undefined references via library.a
then it closes library.a
If the object and the library are in the other way around, then the linker opens library.a, sees no undefined references in its table and closes it. Then it tries and compiles someobject.o and the undefined references are never satisfied
EDIT:
This is a well-known caveat of GCC, a more detailed stack-overflow explanation can be seen here, and options --start-group and --end-group can help resolve cases where A depends on B, and B depends on A.
It's your Makefile. You want:
libdatabase.a
or
-ldatabase
at the end of your main compile line

Getting Undefined Reference to Perl on C++

Well, first of all, sorry about my bad english!
I'm new to linux, g++ and perl, and I'm getting some problems here.
I have a code in G++ which calls a perl .pl file to return a information. Right now, I'm just returning 1 or 0 from the perl .pl file for tests and to understand how does it works. But the problem is that I'm getting this from the $make:
sathlervbn Spam C # make clean;make
rm -f *.o
g++ -Wall -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/lib/perl/5.14/CORE -c -o filedir.o filedir.cpp
g++ -Wall -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/lib/perl/5.14/CORE -c -o main.o main.cpp
main.cpp: In function ‘int main(int, char**, char**)’:
main.cpp:112:41: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
main.cpp:112:41: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
g++ -L/usr/lib -Wall -Wl,-E -fstack-protector -L/usr/local/lib -L/usr/lib/perl/5.14/CORE - lperl -ldl -lm -lpthread -lc -lcrypt -o main filedir.o main.o
main.o: In function `getInfoPerl(std::string)':
main.cpp:(.text+0x1a): undefined reference to `Perl_push_scope'
main.cpp:(.text+0x33): undefined reference to `Perl_save_int'
main.cpp:(.text+0x73): undefined reference to `Perl_markstack_grow'
main.cpp:(.text+0xcd): undefined reference to `Perl_stack_grow'
main.cpp:(.text+0xfa): undefined reference to `Perl_newSVpv'
main.cpp:(.text+0x10d): undefined reference to `Perl_sv_2mortal'
main.cpp:(.text+0x13b): undefined reference to `Perl_call_pv'
main.cpp:(.text+0x18f): undefined reference to `Perl_sv_2iv_flags'
main.cpp:(.text+0x1bd): undefined reference to `Perl_free_tmps'
main.cpp:(.text+0x1ca): undefined reference to `Perl_pop_scope'
main.o: In function `main':
main.cpp:(.text+0x206): undefined reference to `Perl_sys_init3'
main.cpp:(.text+0x20b): undefined reference to `perl_alloc'
main.cpp:(.text+0x21d): undefined reference to `perl_construct'
main.cpp:(.text+0x265): undefined reference to `perl_parse'
main.cpp:(.text+0x272): undefined reference to `perl_run'
main.cpp:(.text+0x2fd): undefined reference to `perl_destruct'
main.cpp:(.text+0x30a): undefined reference to `perl_free'
main.cpp:(.text+0x30f): undefined reference to `Perl_sys_term'
collect2: error: ld returned 1 exit status
make: *** [main] Error 1
The main.cpp code is:
#include <EXTERN.h>
#include <perl.h>
#include <iostream>
#include <cstdio>
#include "filedir.h"
using namespace std;
PerlInterpreter *my_perl;
int getInfoPerl(string email){
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVpv(email.c_str(),0)));
PUTBACK;
call_pv("spamTeste", G_SCALAR);
SPAGAIN;
int resultado = POPi;
PUTBACK;
FREETMPS;
LEAVE;
return resultado;
}
int main(int argc, char **argv, char **env) {
char *my_argv[] = { " ", "spamPerl.pl" };
PERL_SYS_INIT3 (&argc, &argv, &env);
my_perl = perl_alloc();
perl_construct ( my_perl );
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL);
perl_run(my_perl);
cout << "Resultado " << getInfoPerl("email/email.txt") << endl;
perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
foobar bla bla bla another part from the code: doesn't matter.
}
Here is the makefile:
#CC= /usr/bin/g++
CPP = g++
CPPFLAGS = -Wall $(shell perl -MExtUtils::Embed -e ccopts)
#LD= /usr/bin/g++
LD = g++
LFLAGS = -Wall $(shell perl -MExtUtils::Embed -e ldopts)
#LFLAGS = -Wall -Wl,-E -fstack-protector -L/usr/local/lib -L/usr/lib/perl/5.14/CORE -lperl -ldl -lm -lpthread -lc -lcrypt
MAINOBJS = filedir.o main.o
EMAILS = main
EXECS = $(EMAILS)
#Regra Implicita:
.c.o:
$(CPP) $(CPPFLAGS) -c $<
all: emails
emails: $(EMAILS)
main: $(MAINOBJS)
$(LD) -L/usr/lib $(LFLAGS) -o $# $(MAINOBJS)
clean:
rm -f *.o
What I did? I've tried installing libperl-dev package, update the perl, and nothing solved.
I really need to fix this! Can someone help me?
UPDATE:
Changed the Header from main.cpp to:
#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#ifdef __cplusplus
}
#endif
#include <iostream>
#include <cstdio>
#include "filedir.h"
Didn't work...
The answer previous is right, it is cause by the sequence of gcc parameters. I test a sample code provided by the official perlembed tutorial:
http://perldoc.perl.org/perlembed.html
if the compile option is
cc -o interp interp.c perl -MExtUtils::Embed -e ccopts -e ldopts
as provided by the tutorial, it is right.
But any other sequence is wrong, for example:
cc interp.c -o interp perl -MExtUtils::Embed -e ccopts -e ldopts
cc perl -MExtUtils::Embed -e ccopts -e ldopts interp.c -o interp
so make sure in your Makefile -o goes the first and source file goes the second.
The problem was in the makefile:
#CC= /usr/bin/g++
CPP = g++
CPPFLAGS = -Wall $(shell perl -MExtUtils::Embed -e ccopts)
#LD= /usr/bin/g++
LD = g++
LFLAGS = -Wall $(shell perl -MExtUtils::Embed -e ldopts)
#LFLAGS = -Wall -Wl,-E -fstack-protector -L/usr/local/lib -L/usr/lib/perl/5.14/CORE -lperl -ldl -lm -lpthread -lc -lcrypt
MAINOBJS = filedir.o main.o
EMAILS = main
EXECS = $(EMAILS)
#Regra Implicita:
.c.o:
$(CPP) $(CPPFLAGS) -c $<
all: emails
emails: $(EMAILS)
main: $(MAINOBJS)
$(LD) -L/usr/lib $(LFLAGS) -o $# $(MAINOBJS)
clean:
rm -f *.o
As you can see, in this line, the code:
main: $(MAINOBJS)
$(LD) -L/usr/lib $(LFLAGS) -o $# $(MAINOBJS)
Should have the $(LFLAGS) after the $(MAINOBJS), so it should be:
main: $(MAINOBJS)
$(LD) -L/usr/lib -o $# $(MAINOBJS) $(LFLAGS)
Now, the linker is working perfectly. I'm sorry, but I can't say exactly why this is necessary, I've just discovered.