Missing FFTW libraries - fortran

I'm trying to compile a code written in fortran90/95 and I'm getting this error:
user:~> make
ifort -O3 -lmpi -L/opt/local/intel/fftw/lib -I/opt/local/intel/fftw/include - I/opt/sgi/mpt/mpt-2.03/include -L/opt/sgi/mpt/mpt-2.03/lib -o /test module_param.o incompact3d.o mesure.o schemas.o derive.o spectral.o tools.o filtre.o parametre.o forcage.o navier.o convdiff.o viv.o slfft3d_shift.o poisson.o
slfft3d_shift.o: In function 'slfft3d_shift_':
slfft3d_shift.f90:(.text+0x587e): undefined reference to 'rfftw3d_f77_mpi_create_plan_'
slfft3d_shift.f90:(.text+0x58a3): undefined reference to 'rfftwnd_f77_mpi_local_sizes_'
slfft3d_shift.f90:(.text+0x58cd): undefined reference to 'rfftwnd_f77_mpi_'
slfft3d_shift.f90:(.text+0x58d9): undefined reference to 'rfftwnd_f77_mpi_destroy_plan_'
slfft3d_shift.f90:(.text+0x91ca): undefined reference to 'rfftw3d_f77_mpi_create_plan_'
slfft3d_shift.f90:(.text+0x91ef): undefined reference to 'rfftwnd_f77_mpi_local_sizes_'
slfft3d_shift.f90:(.text+0x9219): undefined reference to 'rfftwnd_f77_mpi_'
slfft3d_shift.f90:(.text+0x9225): undefined reference to 'rfftwnd_f77_mpi_destroy_plan_'
slfft3d_shift.f90:(.text+0x111e7): undefined reference to 'rfftwnd_f77_one_real_to_complex_'
make: *** [/test] Error 1
Here's the Makefile:
FC = ifort
OPTFC = -O3 -lmpi -L/opt/local/intel/fftw/lib -I/opt/local/intel/fftw/include - I/opt/sgi/mpt/mpt-2.03/include -L/opt/sgi/mpt/mpt-2.03/lib/test : module_param.o incompact3d.o mesure.o schemas.o derive.o spectral.o tools.o poisson.o filtre.o parametre.o slfft3d_shift.o forcage.o navier.o convdiff.o viv.o
$(FC) $(OPTFC) -o /test module_param.o incompact3d.o mesure.o schemas.o derive.o spectral.o tools.o filtre.o parametre.o forcage.o navier.o convdiff.o viv.o slfft3d_shift.o poisson.o
module_param.o : module_param.f90
$(FC) $(OPTFC) -c module_param.f90 incompact3d.o : incompact3d.f90
$(FC) $(OPTFC) -c incompact3d.f90 mesure.o : mesure.f90
$(FC) $(OPTFC) -c mesure.f90 spectral.o : spectral.f90
$(FC) $(OPTFC) -c spectral.f90 schemas.o : schemas.f90
$(FC) $(OPTFC) -c schemas.f90 derive.o : derive.f90
$(FC) $(OPTFC) -c derive.f90 tools.o : tools.f90
$(FC) $(OPTFC) -c tools.f90 forcage.o : forcage.f90
$(FC) $(OPTFC) -c forcage.f90 navier.o : navier.f90
$(FC) $(OPTFC) -c navier.f90 filtre.o : filtre.f90
$(FC) $(OPTFC) -c filtre.f90 parametre.o : parametre.f90
$(FC) $(OPTFC) -c parametre.f90 convdiff.o : convdiff.f90
$(FC) $(OPTFC) -c convdiff.f90 poisson.o : poisson.f90
$(FC) $(OPTFC) -c poisson.f90 slfft3d_shift.o : slfft3d_shift.f90
$(FC) $(OPTFC) -c slfft3d_shift.f90 viv.o : viv.f90
$(FC) $(OPTFC) -c viv.f90
When I include the libraries required in the Makefile I get the following message:
user:~/test> make
ifort -O3 -lmpi -I/opt/local/intel/fftw/include -L/opt/local/gnu/fftw - I/opt/sgi/mpt/mpt-2.03/include -L/opt/sgi/mpt/mpt-2.03/lib -I/opt/fftw/2.1.5.1/cnos/include -L/opt/intel/composerxe-2011.0.084/mkl/include/fftw/fftw_f77.i -L/opt/fftw/2.1.5.1/cnos/lib -I/opt/local/intel/fftw -I/opt/fftw/3.1.1/cnos/include -L/opt/fftw/3.1.1/cnos/lib - I/usr/local/packages/nag/p3dfft-single/2.3/include -L/usr/local/packages/nag/p3dfft- single/2.3/lib -o /home/u/guitar88/bin/teste module_param.o incompact3d.o mesure.o schemas.o derive.o spectral.o tools.o filtre.o \
parametre.o forcage.o navier.o convdiff.o viv.o slfft3d_shift.o poisson.o -lm -L/opt/local/intel/fftw/lib -lsrfftw_mpi \
-lsrfftw -lsfftw_mpi -lsfftw
ld: cannot find -lsrfftw_mpi
make: *** [/test] Error 1
I'm using ifort compiler and I'm on a supercomputer environment working with MPI. Please, any clue of what is going on? Cheers.

Pls attend that the linker tries to link against f77 mpi libs, whereas your source suffixes, e.g. of that "slfft3d_shift.f90" would imply you call f90 routines.
on a supercomputer environment working with MPI
...you often have a system-specific convention which compiler to call by which wrapper; consult your system admin or the system faq on that.
Generally - it is quite uncommon trying to compile MPI apps without using MPI wrappers like "mpif90", "mpif90.mpich", "mpif90.openmpi" or similar.

Related

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

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

Undefined constructor in inherited templated singleton class c++

I ran into a problem today, using a tool I have made some times ago : a Singleton templated class.
template <class C>
class Singleton {
/*! \class Singleton
* \brief Singleton Template
*/
public:
/*!
* \brief Public access interface
* \return Singleton instance
*/
static C *getInstance (){
// Create new instance if not initialised
if (_singleton == NULL){
_singleton = new C;
}
return (static_cast<C*> (_singleton));
}
/*!
* \brief Public access destructor
*/
static void kill(){
// Clean Singleton object and free memory
if (_singleton != NULL){
delete _singleton;
_singleton = NULL;
}
}
protected:
/*!
* \brief Empty constructor
*/
Singleton() = default;
/*!
* \brief Destructor
*/
virtual ~Singleton() = default;
private:
static C *_singleton; /*!< Unique instance */
};
template <class C>
C *Singleton<C>::_singleton = NULL;
The problem arise when i try to call TextureManager::getInstance() on the (very basic) inherited class which is the following :
class TextureManager : public Singleton<TextureManager> {
friend class Singleton<TextureManager>;
/*! \class TextureManager
* \brief Textures Container
*/
public:
protected:
/*!
* \brief Empty constructor
*/
TextureManager();
/*!
* \brief Destructor
*/
~TextureManager() override;
private:
};
During compilation, the linker shows me an error that i understand but I do not really understand the reason :
build/main.o: In function `Singleton<TextureManager>::getInstance()':
main.cpp (.text._ZN9SingletonI14TextureManagerE11getInstanceEv[_ZN9SingletonI14TextureManagerE11getInstanceEv]+0x24): undefined reference to `TextureManager::TextureManager()'
It seems that it can't find the definition of the constructor which is in TextureManager.cpp
TextureManager::TextureManager() = default;
TextureManager::~TextureManager() = default;
This code worked on an older project I compiled using premake so my guess is that my current makefile is rubbish but i can't find why...
INCLUDE = -I/usr/X11R6/include/
LIBDIR = -L/usr/X11R6/lib
SRCDIR := sources
BUILDDIR := build
TARGET := bin/game
SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
FLAGS = -std=c++11 -Wall
CC = g++
CFLAGS = $(FLAGS) $(INCLUDE)
LIBS = -lglut -lGL -lGLU -lGLEW -lm
$(TARGET): $(OBJECTS)
#echo "Linking..."
#echo "$(CC) $(CFLAGS) $^ -o $# $(LIBDIR) $< $(LIBS)"; $(CC) $(CFLAGS) -o $# $(LIBDIR) $< $(LIBS)
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
#mkdir -p $(#D)
#echo "$(CC) $(CFLAGS) -o $# $(LIBDIR) $< $(LIBS)"; $(CC) $(CFLAGS) -c -o $# $(LIBDIR) $< $(LIBS)
clean:
#echo "Cleaning..."
#echo "$(RM) -r $(BUILDDIR) $(TARGET)"; $(RM) -r $(BUILDDIR) $(TARGET)
.PHONY: clean
Now stuck for hours,
all my hopes are on you :p
Edit : full make output
g++ -std=c++11 -Wall -I/usr/X11R6/include/ -o build/main.o -L/usr/X11R6/lib sources/main.cpp -lglut -lGL -lGLU -lGLEW -lm
g++ -std=c++11 -Wall -I/usr/X11R6/include/ -o build/Tools/ThreadManager.o -L/usr/X11R6/lib sources/Tools/ThreadManager.cpp -lglut -lGL -lGLU -lGLEW -lm
g++ -std=c++11 -Wall -I/usr/X11R6/include/ -o build/Graphics/GraphicalEngine.o -L/usr/X11R6/lib sources/Graphics/GraphicalEngine.cpp -lglut -lGL -lGLU -lGLEW -lm
g++ -std=c++11 -Wall -I/usr/X11R6/include/ -o build/Graphics/TextureManager.o -L/usr/X11R6/lib sources/Graphics/TextureManager.cpp -lglut -lGL -lGLU -lGLEW -lm
Linking...
g++ -std=c++11 -Wall -I/usr/X11R6/include/ build/main.o build/Tools/ThreadManager.o build/Graphics/GraphicalEngine.o build/Graphics/TextureManager.o -o bin/game -L/usr/X11R6/lib build/main.o -lglut -lGL -lGLU -lGLEW -lm
build/main.o: In function `Singleton<TextureManager>::getInstance()':
main.cpp:(.text._ZN9SingletonI14TextureManagerE11getInstanceEv[_ZN9SingletonI14TextureManagerE11getInstanceEv]+0x24): undefined reference to `TextureManager::TextureManager()'
collect2: error: ld returned 1 exit status
makefile:18: recipe for target 'bin/game' failed
make: *** [bin/game] Error 1
The problem is that you are only using the first dependency in the $(TARGET) rule:
$(CC) $(CFLAGS) -o $# $(LIBDIR) $< $(LIBS)
# ^^
My comment was actually wrong because you have a different command between the #echo and the actual command:
#echo "$(CC) $(CFLAGS) $^ -o $# $(LIBDIR) $< $(LIBS)"
# ^^ ^^
I do not see a point in adding this echo line here, I would do as follow:
$(TARGET): $(OBJECTS)
#echo "Linking..."
$(CC) $(CFLAGS) $^ -o $# $(LIBDIR) $(LIBS)
# ^^
Had you done so, you would have seen your error sooner I think.

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 $#

CFLAGS=-std=c++11 -O3 -Wall -pedantic not being recognized in makefile

I have a makefile where I compile a number of cpp files to make different executables.
CFLAGS=-std=c++11 -O3 -Wall -pedantic
CC=g++1
LDFLAGS=
all: auto_variables explict_kw for_each functor member_initializer member_initializer2 reference ref_ptr smart_pointers vector
auto_variables : auto_variables.o
$(CC) $(CFLAGS) auto_variables.o $(LDFLAGS) -o $#
explict_kw : explict_kw.o
$(CC) $(CFLAGS) explict_kw.o $(LDFLAGS) -o $#
for_each : for_each o
$(CC) $(CFLAGS) for_each.o $(LDFLAGS) -o $#
functor : functor.o
$(CC) $(CFLAGS) functor.o $(LDFLAGS) -o $#
member_initializer : member_initializer.o
$(CC) $(CFLAGS) member_initializer.o $(LDFLAGS) -o $#
member_initializer2 : member_initializer2.o
$(CC) $(CFLAGS) member_initializer2.o $(LDFLAGS) -o $#
reference : reference.o
$(CC) $(CFLAGS) reference.o $(LDFLAGS) -o $#
ref_ptr : ref_ptr.o
$(CC) $(CFLAGS) ref_ptr.o $(LDFLAGS) -o $#
smart_pointers : smart_pointers.o
$(CC) $(CFLAGS) smart_pointers.o $(LDFLAGS) -o $#
vector : vector.o
$(CC) $(CFLAGS) vector.o $(LDFLAGS) -o $#
clean:
rm -rf auto_variables explict_kw for_each functor member_initializer member_initializer2 reference ref_ptr smart_pointers vector
rm -rf *.o
I have specified -std=c++11 as CFLAGS but when I type make it doesn't seem to take that option.
g++ -c -o auto_variables.o auto_variables.cpp
auto_variables.cpp:8:27: error: ISO C++ forbids declaration of ‘sum’ with no type [-fpermissive]
auto sum(int x, int y) -> int
^
auto_variables.cpp:8:27: error: top-level declaration of ‘sum’ specifies ‘auto’
auto_variables.cpp:8:27: error: trailing return type only available with -std=c++11 or -std=gnu++11
auto_variables.cpp: In function ‘int main()’:
auto_variables.cpp:16:8: error: ‘var_1’ does not name a type
auto var_1 = 5;
^
auto_variables.cpp:18:8: error: ‘var_2’ does not name a type
auto var_2 = 'c';
^
auto_variables.cpp:20:16: error: ‘var_1’ was not declared in this scope
std::cout << var_1 << std::endl;
^
auto_variables.cpp:21:16: error: ‘var_2’ was not declared in this scope
std::cout << var_2 << std::endl;
^
auto_variables.cpp:23:8: error: ‘fun_sum’ does not name a type
auto fun_sum = [](int a, int b)
^
auto_variables.cpp:46:8: error: ‘itr’ does not name a type
auto itr = mapofStrs.begin();
^
auto_variables.cpp:47:9: error: ‘itr’ was not declared in this scope
while(itr != mapofStrs.end())
^
<builtin>: recipe for target 'auto_variables.o' failed
make: *** [auto_variables.o] Error 1
Why is this happening.
I suggest using CXXFLAGS instead of CFLAGS.
CFLAGS is for C flags while CXXFLAGS is for C++ flags.
CXXFLAGS=-std=c++11 -O3 -Wall -pedantic
Also, it's not clear to me what you meant by:
CC=g++1
Is that a typo? I suspect you meant to use
CC=g++
Keeping with the previous change, you should change that to:
CXX=g++
Then, change all the places where you are using $(CC) $(CFLAS) to $(CXX) $(CXXFLAGS).
This is happening because you are misusing Make.
For C++, use the correct variables, as documented on the GNU Make page: CXXFLAGS.
CXXFLAGS=-std=c++11 -O3 -Wall -pedantic
You shouldn't need to set anything else at least at first.
This will make sure that you are using the correct implicit rules. If this doesn't help, make a Minimal, complete, and verifiable example which shows the code, too.

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.