You got to love linker errors *sarcasm*. Any way, I am developing a psp game using the psp port of allegro which came with pspsdk. And after I fixed all the other undefined references this one stumps me. The full error message and makefile and code below:
Error details
1>------ Build started: Project: PSP Pong, Configuration: Debug Win32 ------
1> psp-g++ -I. -IC:/pspsdk/psp/sdk/include -O2 -G0 -Wall -I. -IC:/pspsdk/psp/sdk/include -O2 -G0 -Wall -fno-exceptions -fno-rtti -D_PSP_FW_VERSION=150 -c -o main.o main.cpp
1> psp-gcc -I. -IC:/pspsdk/psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=150 -L. -LC:/pspsdk/psp/sdk/lib main.o -lalleg -lpspgu -lpspirkeyb -lm -lpsppower -lpspaudio -lpsprtc -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -o main.elf
1> c:/pspsdk/bin/../lib/gcc/psp/4.3.5/../../../../psp/lib/crt0.o: In function `_main':
1> ../../../../pspsdk/src/startup/crt0.c (86) : undefined reference to `main'
1> C:\pspsdk\bin\make: *** [main.elf] Error 1
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
MakeFile
TARGET = main
OBJS = main.o
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = PSP Pong
LIBS = -lalleg -lpspgu -lpspirkeyb -lm -lpsppower -lpspaudio -lpsprtc
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
main.cpp
#include <allegro.h>
int main()
{
allegro_init();
install_mouse();
set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT,480,272,0,0);
clear_bitmap(screen);
while (!(mouse_b & 2))
{
poll_mouse();
putpixel(screen,mouse_x,mouse_y,0xFFFFFFFF);
vsync();
}
clear_bitmap(screen);
return 0;
}
END_OF_MAIN();
P.S I think the linker is not talking about the main function in main.cpp but some other main but I have no clue so any advice, corrections, any thing to help me solve this will be appreciated.
Just before including allegro, try adding this define:
#define ALLEGRO_NO_MAGIC_MAIN
Source:
http://allegro-psp.webcindario.com/
Check out the source of crt0.c
It has a definition of main that it can't see because of the name mangling "magic" that END_OF_MAIN() does.
http://www.jbox.dk/sanos/source/lib/crt0.c.html
Try putting
#define ALLEGRO_NO_MAGIC_MAIN
at the start of things.
Try changing your main function definition to:
extern "C"
int main(int argc, char * argv[])
See if that helps things.
Related
I am writing a c++/CUDA library with multiple calls to kernels.
EDIT: I think the original post was a little long, so I have created a better example. Original post below.
Here is the project simplified to a minimal example. It will not compile, and gives the following error:
nvcc -Xcompiler -fPIC -x cu -c -dc -o myclass.o myclass.cpp
nvcc -Xcompiler -fPIC --lib myclass.o kernel.cu -o libhelpme.a -I.
ptxas fatal : Unresolved extern function '_ZN7myclassC1Ei'
makefile:8: recipe for target 'lib' failed
make: *** [lib] Error 255
All documentation on this topic points towards compiling an executable or an object file; I want to do neither of these, rather a static library specifically. How do I do this?
The code:
makefile
program: class lib
nvcc -o program main.cc -I. -L. -lhelpme
class:
nvcc -Xcompiler -fPIC -x cu -c -dc -o myclass.o myclass.cpp
lib: class
nvcc -Xcompiler -fPIC --lib myclass.o kernel.cu -o libhelpme.a -I.
clean:
rm *.o *.a program
main.cc
#include "stdio.h"
#include <iostream>
#include "kernel.h"
int main()
{
std::cout << "hello world" << std::endl;
wrapper();
return 0;
}
myclass.h
#ifdef __CUDACC__
#define COMMON __host__ __device__
#else
#define COMMON
#endif
#ifndef M
#define M
class myclass
{
public:
int x;
COMMON myclass(int y);
COMMON void increment();
};
#endif
myclass.cpp
#include "myclass.h"
#ifdef __CUDACC__
#define COMMON __host__ __device__
#else
#define COMMON
#endif
COMMON myclass::myclass(int y)
{
x = y;
}
COMMON void myclass::increment()
{
x += 1;
}
kernel.h
extern void wrapper();
kernel.cu
#include "stdio.h"
#include <iostream>
#include "myclass.h"
class myotherclass
{
public:
int x;
COMMON myotherclass(int y) {x = y;}
COMMON void decrement() {x -= 1;}
};
__global__ void dokernel()
{
myotherclass p(8); //This compiles just fine.
myclass q(7); //This will not compile
}
void wrapper()
{
std::cout << "hello from wrapper\n";
myclass q(1);
myotherclass s(4);
std::cout << "x = " << s.x << "\n";
s.decrement();
std::cout << "x = " << s.x << "\n";
dokernel<<<1,1>>>();
}
I am slowly becoming convinced that this is impossible...
ORIGINAL POST: I have a number of c++ source/header files, e.g. vec.cpp and vec.h being compiled to object files, e.g. vec.o
Here is an example: vec.h
class vec
{
public:
realnum x,y,z;
__host__ __device__ vec(float _x, float _y, float _z);
}
vec.cpp
__host__ __device__ vec::vec(float _x, float _y, float _z) {x = _x; y = _y; z = _z;}
Here is my full makefile (still in the making):
CC=nvcc
CFLAGS = -Wall -g -O3
HOME_DIR = $(shell pwd)
SRC_DIR := ${HOME_DIR}/../src
OBJ_DIR := ${HOME_DIR}/../lib
LIB_DIR := ${HOME_DIR}/../lib
KER_DIR := ${HOME_DIR}/../kernel
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
LPROPS := -L${LIB_DIR} -lcuprops
LMAIN := -L${LIB_DIR} -lsharc
LRDR := -L${LIB_DIR} -lcurdr
INCL_PROPS := -I${SRC_DIR} -I${KER_DIR}
program: $(LIB_DIR)/libcurdr.so ${LIB_DIR}/libsharc.so $(LIB_DIR)/libcuprops.so $(OBJ_FILES)
${CC} -o $# main.cc -I${SRC_DIR} ${LPROPS} ${LMAIN} ${LRDR}
${LIB_DIR}/libsharc.so: $(OBJ_FILES) $(LIB_DIR)/libcuprops.so
${CC} -Xcompiler -fPIC --shared ${OBJ_FILES} -o $(LIB_DIR)/libsharc.so ${INCL_PROPS}
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
${CC} -Xcompiler -fPIC -dc -o $# $< ${INCL_PROPS}
$(LIB_DIR)/libcuprops.so:
${CC} -Xcompiler -fPIC --shared -o $(LIB_DIR)/libcuprops.so ${KER_DIR}/nvidia_properties.cu ${INCL_PROPS}
$(LIB_DIR)/libcurdr.so: $(OBJ_FILES)
${CC} -Xcompiler -fPIC --shared ${OBJ_FILES} ${KER_DIR}/gpu_rdr.cu -o $(LIB_DIR)/libcurdr.so ${INCL_PROPS}
clean:
rm ${LIB_DIR}/*
When I make I get the following:
ptxas fatal : Unresolved extern function '_ZN3vecC1Eddd'
I have a kernel where I try to initialize a vector:
__global__ void SOME_KERNEL()
{
int row = blockIdx.y*blockDim.y + threadIdx.y;
int col = blockIdx.x*blockDim.x + threadIdx.x;
if (row < dev_height && col < dev_width)
{
vec t(0,0,0); //Compiles nicely when I comment out this line!
}
}
I have read about separate compiling and linking where it is claimed that the typical project architecture (that I believe that I am using) is compatible with separate compiling and linking via the following:
objects = main.o particle.o v3.o
all: $(objects)
nvcc -arch=sm_20 $(objects) -o app
%.o: %.cpp
nvcc -x cu -arch=sm_20 -I. -dc $< -o $#
clean:
rm -f *.o app
Note the use of the "-dc" flag, which is consistent with this answer.
At this point I have tried so many things that I am completely lost. So, how can I compile this project?
In the case that it is helpful, here is the full output from make:
nvcc -Xcompiler -fPIC -dc -o /home/wvn/dirs/projects/sharc/build/../lib/mat33.o /home/wvn/dirs/projects/sharc/build/../src/mat33.cpp -I/home/wvn/dirs/projects/sharc/build/../src -I/home/wvn/dirs/projects/sharc/build/../kernel
nvcc -Xcompiler -fPIC -dc -o /home/wvn/dirs/projects/sharc/build/../lib/vec.o /home/wvn/dirs/projects/sharc/build/../src/vec.cpp -I/home/wvn/dirs/projects/sharc/build/../src -I/home/wvn/dirs/projects/sharc/build/../kernel
nvcc -Xcompiler -fPIC -dc -o /home/wvn/dirs/projects/sharc/build/../lib/sharc.o /home/wvn/dirs/projects/sharc/build/../src/sharc.cpp -I/home/wvn/dirs/projects/sharc/build/../src -I/home/wvn/dirs/projects/sharc/build/../kernel
nvcc -Xcompiler -fPIC -dc -o /home/wvn/dirs/projects/sharc/build/../lib/boundingbox.o /home/wvn/dirs/projects/sharc/build/../src/boundingbox.cpp -I/home/wvn/dirs/projects/sharc/build/../src -I/home/wvn/dirs/projects/sharc/build/../kernel
nvcc -Xcompiler -fPIC --shared /home/wvn/dirs/projects/sharc/build/../lib/mat33.o /home/wvn/dirs/projects/sharc/build/../lib/vec.o /home/wvn/dirs/projects/sharc/build/../lib/sharc.o /home/wvn/dirs/projects/sharc/build/../lib/boundingbox.o /home/wvn/dirs/projects/sharc/build/../kernel/gpu_rdr.cu -o /home/wvn/dirs/projects/sharc/build/../lib/libcurdr.so -I/home/wvn/dirs/projects/sharc/build/../src -I/home/wvn/dirs/projects/sharc/build/../kernel
ptxas fatal : Unresolved extern function '_ZN3vecC1Eddd'
makefile:32: recipe for target '/home/wvn/dirs/projects/sharc/build/../lib/libcurdr.so' failed
make: *** [/home/wvn/dirs/projects/sharc/build/../lib/libcurdr.so] Error 255
Referring to the UPDATED post, not the ORIGINAL post.
As indicated in the comments, one of the things needed was to add -x cu when you are compiling files that end in .cpp but contain CUDA constructs or device code. You've already added that in the proper place.
Your discussion around your COMMON macro has no bearing on this. They serve separate purposes. The macro is not a substitute for -x cu.
The other missing thing is that you need to instruct nvcc at the static library generation point that relocatable device code and device linking is needed. You do this by adding -rdc=true to the compile command line. Your Makefile could be modified like this:
lib: class
nvcc -Xcompiler -fPIC -rdc=true --lib myclass.o kernel.cu -o libhelpme.a -I.
This is needed because you have device code in one compilation unit (kernel.cu) that is calling device code in another compilation unit (myclass.cpp).
With that change, your UPDATED post/project compiles without issue for me and also runs without error.
$ make clean
rm *.o *.a program
$ make
nvcc -Xcompiler -fPIC -x cu -c -dc -o myclass.o myclass.cpp
nvcc -Xcompiler -fPIC -rdc=true --lib myclass.o kernel.cu -o libhelpme.a -I.
nvcc -o program main.cc -I. -L. -lhelpme
$ cuda-memcheck ./program
========= CUDA-MEMCHECK
hello world
hello from wrapper
x = 4
x = 3
========= ERROR SUMMARY: 0 errors
$
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
I have a library from a camera manufacturer, and in the demo code provided, a function called metadata_init() works fine, in my code though, I get an undefined reference error.
The make output from the demo code:
/opt/linaro-multilib-2013.09-gcc4.8/bin/arm-linux-gnueabihf-gcc -lm -g -L"/home/aro/Downloads" -o hicore demoS2.c -lpthread -lyuvlib -lrt
and thats it, the build succeeds fine, I will have a working ./hicore application in there.
My project is a little bit more complicated, and I compile using eclipse.
The console output is:
11:33:23 **** Build of configuration Camera-R4-Debug for project Camera ****
make all
Building file: ../src/Camera.cpp
Invoking: Cross G++ Compiler
arm-linux-gnueabihf-g++ -I/opt/Camerasdk/R4/include -I"/cameraBuilds/Wrapper/include" -I"/opt/ExternalLibraries/curl/Camera/R4/include" -I"/opt/ExternalLibraries/libxml2/Camera/R4/include" -I"/opt/ExternalLibraries/OpenCV24/Camera/R4/include" -I"/home/aro/cameraBuilds/Camera" -I/opt/InternalLibraries/include -I/opt/InternalLibraries/include_linux -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Camera.d" -MT"src/Camera.o" -o "src/Camera.o" "../src/Camera.cpp"
../src/Camera.cpp: In function ‘int metadata_construct_http_message(char*, METADATA_HTTP_MESSAGE_TYPE, void*, int*)’:
../src/Camera.cpp:379:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
"</svg>\r\n";
^
../src/Camera.cpp: In function ‘int main()’:
../src/Camera.cpp:426:97: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
(void)metadata_init("stream.cgi", strlen("stream.cgi"), metadata_construct_http_message);
^
Finished building: ../src/Camera.cpp
Building file: ../src/CameraFrameGrabber.cpp
Invoking: Cross G++ Compiler
arm-linux-gnueabihf-g++ -I/opt/Camerasdk/R4/include -I"/cameraBuilds/Wrapper/include" -I"/opt/ExternalLibraries/curl/Camera/R4/include" -I"/opt/ExternalLibraries/libxml2/Camera/R4/include" -I"/opt/ExternalLibraries/OpenCV24/Camera/R4/include" -I"/home/aro/cameraBuilds/Camera" -I/opt/InternalLibraries/include -I/opt/InternalLibraries/include_linux -I/opt/InternalLibraries/ipslib/include -I/opt/InternalLibraries/ipsstream/include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/CameraFrameGrabber.d" -MT"src/CameraFrameGrabber.o" -o "src/CameraFrameGrabber.o" "../src/CameraFrameGrabber.cpp"
Finished building: ../src/CameraFrameGrabber.cpp
Building file: ../src/CameraLogger.cpp
Invoking: Cross G++ Compiler
arm-linux-gnueabihf-g++ -I/opt/Camerasdk/R4/include -I"/home/aro/cameraBuilds/Wrapper/include" -I"/opt/ExternalLibraries/curl/Camera/R4/include" -I"/opt/ExternalLibraries/libxml2/Camera/R4/include" -I"/opt/ExternalLibraries/OpenCV24/Camera/R4/include" -I"/home/aro/cameraBuilds/Camera" -I/opt/InternalLibraries/include -I/opt/InternalLibraries/include_linux -I/opt/InternalLibraries/ipslib/include -I/opt/InternalLibraries/ipsstream/include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/CameraLogger.d" -MT"src/CameraLogger.o" -o "src/CameraLogger.o" "../src/CameraLogger.cpp"
Finished building: ../src/CameraLogger.cpp
Building file: ../src/CameraParameter.cpp
Invoking: Cross G++ Compiler
arm-linux-gnueabihf-g++ -I/opt/Camerasdk/R4/include -I"/home/aro/cameraBuilds/Wrapper/include" -I"/opt/ExternalLibraries/curl/Camera/R4/include" -I"/opt/ExternalLibraries/libxml2/Camera/R4/include" -I"/opt/ExternalLibraries/OpenCV24/Camera/R4/include" -I"/home/aro/cameraBuilds/Camera" -I/opt/InternalLibraries/include -I/opt/InternalLibraries/include_linux -I/opt/InternalLibraries/ipslib/include -I/opt/InternalLibraries/ipsstream/include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/CameraParameter.d" -MT"src/CameraParameter.o" -o "src/CameraParameter.o" "../src/CameraParameter.cpp"
Finished building: ../src/CameraParameter.cpp
Building target: Camera
Invoking: Cross G++ Linker
arm-linux-gnueabihf-g++ -L/opt/Camerasdk/R4/lib -L"/cameraBuilds/Wrapper/Camera-R4-Debug" -L"/opt/ExternalLibraries/curl/Camera/R4/lib" -L"/opt/ExternalLibraries/libxml2/Camera/R4/lib" -L"/opt/ExternalLibraries/OpenCV24/Camera/R4/lib" -L"/opt/DetectionModules/Camera/R4/lib" -L/home/aro/Downloads -o "Camera" ./src/Camera.o ./src/CameraFrameGrabber.o ./src/CameraLogger.o ./src/CameraParameter.o -lWrapper -lxml2 -lopencv_highgui -lopencv_imgproc -lopencv_core -lpthread -lyuvlib -lrt -llibjasper -llibjpeg -llibpng -llibtiff -lzlib -lcurl
./src/Camera.o: In function `main':
/home/aro/cameraBuilds/Camera/Camera-R4-Debug/../src/Camera.cpp:426: undefined reference to `metadata_init(char*, int, int (*)(char*, METADATA_HTTP_MESSAGE_TYPE, void*, int*))'
collect2: error: ld returned 1 exit status
make: *** [Camera] Error 1
11:33:24 Build Finished (took 1s.212ms)
The code itself is the very same thing, I just copied it over.
Metadata.h:
#ifndef _HIK_METADATA_H_
#define _HIK_METADATA_H_
const int max_http_body_len = 100 * 1024;
typedef enum
{
CMD_ADD_TYPE = 1,
CMD_OTHER,
} METADATA_CTRL_TYPE;
typedef struct
{
int length;
int fd;
METADATA_CTRL_TYPE cmd_type;
} METADATA_HEADER;
typedef struct
{
char option[128];
int share_socket;
} METADATA_ADD_CFG;
typedef enum
{
HTTP_HEADER_TYPE = 1,
HTTP_BODY_TYPE,
} METADATA_HTTP_MESSAGE_TYPE;
typedef struct
{
char boundary[64];
char http_content_type[64];
char multipart_content_type[64];
} METADATA_MULTIPART_TYPE;
typedef int (*p_metadata_construct_http_msg_callback_f)(char *p_option, METADATA_HTTP_MESSAGE_TYPE cmd_type, void *p_data, int *p_data_len);
int metadata_init(char *p_metadata_url, int url_len, p_metadata_construct_http_msg_callback_f p_callback_f);
#endif
In Camera.cpp:
#include "Metadata.h"
int metadata_construct_http_message(char *p_option, METADATA_HTTP_MESSAGE_TYPE cmd_type, void *p_data, int *p_data_len)
{
// Removed for SO
return 0;
}
int main()
{
(void)metadata_init("stream.cgi", strlen("stream.cgi"), metadata_construct_http_message);
...
}
What causes this, and how can I debug this issue to narrow down how to fix it?
It think the problem could be that metadata_init is a C function, but you use it from a C++ code.
In case of this, extern "C" must be used in the header file, like this:
#ifdef __cplusplus
extern "C" {
#endif
// embed the whole contents of the header file here, I just put the function here for brevity
int metadata_init(char *p_metadata_url, int url_len, p_metadata_construct_http_msg_callback_f p_callback_f);
#ifdef __cplusplus
}
#endif
It is because of name mangling rules. Names are mangled differently in C and C++. With extern "C", you tell the compiler that the names inside should be used with "C" mangling.
C++ has to do a complex name mangling compared to C, because it has to embed almost all signature information to a name (all parameters type), while in C, the mangled name usually is the same as the function name, or there is a _ prepended.
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 ¶m1);
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 ¶m1) : 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 $#
I have an old source which I need to integrate in my project in Eclipse (in Ubuntu 12.04).
The old source code works perfectly on its own. But the only problem with it is - I have just one .cpp file (which contains the main) and all others are .h files which contains the definitions and declarations. I fixed this by creating a source file for each header file and copying the function definitions in these files and left the declarations in the header files.
I added these files using eclipse so those files actually are getting compiled.
Note that, I have added this source code into "src/segment". Here is my directory listing. These files also show up in the eclipse project. My main function is in "HelloOpenCV2.cpp"
[eeuser#roadrunner src]$ ls
CameraPoseFromFundamentalMatrix.d InterestPoints.o
CameraPoseFromFundamentalMatrix.o LinesAndComponents.d
GLViz.d LinesAndComponents.o
GLViz.o MorphologicalManip.d
GraphImageSegmentation.d MorphologicalManip.o
GraphImageSegmentation.o MultiviewColorConsistency.d
HelloOpenCV2.d MultiviewColorConsistency.o
HelloOpenCV2.o segment
HomographyWarp.d StereoCamDepth.d
HomographyWarp.o StereoCamDepth.o
ImageManipulations.d subdir.mk
ImageManipulations.o VideoProc.d
InterestPoints.d VideoProc.o
[eeuser#roadrunner src]$ ls segment/
convolve.d filter.d imconv.d segment-graph.d subdir.mk
convolve.o filter.o imconv.o segment-graph.o
disjoint-set.d image.d imutil.d segment-image.d
disjoint-set.o image.o imutil.o segment-image.o
Here is my compilation log as generated by eclipse.
18:54:21 **** Build of configuration Debug for project HelloOpenCV2 ****
make all
Building file: ../src/segment/convolve.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/segment/convolve.d" -MT"src/segment/convolve.d" -o "src/segment/convolve.o" "../src/segment/convolve.cpp"
Finished building: ../src/segment/convolve.cpp
Building file: ../src/segment/disjoint-set.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/segment/disjoint-set.d" -MT"src/segment/disjoint-set.d" -o "src/segment/disjoint-set.o" "../src/segment/disjoint-set.cpp"
Finished building: ../src/segment/disjoint-set.cpp
Building file: ../src/segment/filter.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/segment/filter.d" -MT"src/segment/filter.d" -o "src/segment/filter.o" "../src/segment/filter.cpp"
Finished building: ../src/segment/filter.cpp
Building file: ../src/segment/image.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/segment/image.d" -MT"src/segment/image.d" -o "src/segment/image.o" "../src/segment/image.cpp"
Finished building: ../src/segment/image.cpp
Building file: ../src/segment/imconv.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/segment/imconv.d" -MT"src/segment/imconv.d" -o "src/segment/imconv.o" "../src/segment/imconv.cpp"
Finished building: ../src/segment/imconv.cpp
Building file: ../src/segment/imutil.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/segment/imutil.d" -MT"src/segment/imutil.d" -o "src/segment/imutil.o" "../src/segment/imutil.cpp"
Finished building: ../src/segment/imutil.cpp
Building file: ../src/segment/segment-graph.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/segment/segment-graph.d" -MT"src/segment/segment-graph.d" -o "src/segment/segment-graph.o" "../src/segment/segment-graph.cpp"
Finished building: ../src/segment/segment-graph.cpp
Building file: ../src/segment/segment-image.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/segment/segment-image.d" -MT"src/segment/segment-image.d" -o "src/segment/segment-image.o" "../src/segment/segment-image.cpp"
Finished building: ../src/segment/segment-image.cpp
Building file: ../src/CameraPoseFromFundamentalMatrix.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/CameraPoseFromFundamentalMatrix.d" -MT"src/CameraPoseFromFundamentalMatrix.d" -o "src/CameraPoseFromFundamentalMatrix.o" "../src/CameraPoseFromFundamentalMatrix.cpp"
Finished building: ../src/CameraPoseFromFundamentalMatrix.cpp
Building file: ../src/GLViz.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/GLViz.d" -MT"src/GLViz.d" -o "src/GLViz.o" "../src/GLViz.cpp"
Finished building: ../src/GLViz.cpp
Building file: ../src/GraphImageSegmentation.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/GraphImageSegmentation.d" -MT"src/GraphImageSegmentation.d" -o "src/GraphImageSegmentation.o" "../src/GraphImageSegmentation.cpp"
Finished building: ../src/GraphImageSegmentation.cpp
Building file: ../src/HelloOpenCV2.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/HelloOpenCV2.d" -MT"src/HelloOpenCV2.d" -o "src/HelloOpenCV2.o" "../src/HelloOpenCV2.cpp"
Finished building: ../src/HelloOpenCV2.cpp
Building file: ../src/HomographyWarp.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/HomographyWarp.d" -MT"src/HomographyWarp.d" -o "src/HomographyWarp.o" "../src/HomographyWarp.cpp"
Finished building: ../src/HomographyWarp.cpp
Building file: ../src/ImageManipulations.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/ImageManipulations.d" -MT"src/ImageManipulations.d" -o "src/ImageManipulations.o" "../src/ImageManipulations.cpp"
Finished building: ../src/ImageManipulations.cpp
Building file: ../src/InterestPoints.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/InterestPoints.d" -MT"src/InterestPoints.d" -o "src/InterestPoints.o" "../src/InterestPoints.cpp"
Finished building: ../src/InterestPoints.cpp
Building file: ../src/LinesAndComponents.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/LinesAndComponents.d" -MT"src/LinesAndComponents.d" -o "src/LinesAndComponents.o" "../src/LinesAndComponents.cpp"
Finished building: ../src/LinesAndComponents.cpp
Building file: ../src/MorphologicalManip.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/MorphologicalManip.d" -MT"src/MorphologicalManip.d" -o "src/MorphologicalManip.o" "../src/MorphologicalManip.cpp"
Finished building: ../src/MorphologicalManip.cpp
Building file: ../src/MultiviewColorConsistency.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/MultiviewColorConsistency.d" -MT"src/MultiviewColorConsistency.d" -o "src/MultiviewColorConsistency.o" "../src/MultiviewColorConsistency.cpp"
Finished building: ../src/MultiviewColorConsistency.cpp
Building file: ../src/StereoCamDepth.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/StereoCamDepth.d" -MT"src/StereoCamDepth.d" -o "src/StereoCamDepth.o" "../src/StereoCamDepth.cpp"
Finished building: ../src/StereoCamDepth.cpp
Building file: ../src/VideoProc.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/opencv -I/usr/local/include -O0 -g3 -w -c -fmessage-length=0 -MMD -MP -MF"src/VideoProc.d" -MT"src/VideoProc.d" -o "src/VideoProc.o" "../src/VideoProc.cpp"
Finished building: ../src/VideoProc.cpp
Building target: HelloOpenCV2
Invoking: GCC C++ Linker
g++ -L/usr/local/lib -o "HelloOpenCV2" ./src/segment/convolve.o ./src/segment/disjoint-set.o ./src/segment/filter.o ./src/segment/image.o ./src/segment/imconv.o ./src/segment/imutil.o ./src/segment/segment-graph.o ./src/segment/segment-image.o ./src/CameraPoseFromFundamentalMatrix.o ./src/GLViz.o ./src/GraphImageSegmentation.o ./src/HelloOpenCV2.o ./src/HomographyWarp.o ./src/ImageManipulations.o ./src/InterestPoints.o ./src/LinesAndComponents.o ./src/MorphologicalManip.o ./src/MultiviewColorConsistency.o ./src/StereoCamDepth.o ./src/VideoProc.o -lopencv_core -lGL -lGLU -lglut -lopencv_stitching -lopencv_contrib -lopencv_nonfree -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_flann -lopencv_imgproc -lopencv_highgui
../src/segment/filter.cpp:39: error: undefined reference to 'image<float>::image(int, int, bool)'
../src/segment/filter.cpp:40: error: undefined reference to 'image<float>::image(int, int, bool)'
../src/segment/filter.cpp:41: error: undefined reference to 'convolve_even(image<float>*, image<float>*, std::vector<float, std::allocator<float> >&)'
../src/segment/filter.cpp:42: error: undefined reference to 'convolve_even(image<float>*, image<float>*, std::vector<float, std::allocator<float> >&)'
../src/segment/filter.cpp:44: error: undefined reference to 'image<float>::~image()'
../src/segment/filter.cpp:52: error: undefined reference to 'imageUCHARtoFLOAT(image<unsigned char>*)'
../src/segment/filter.cpp:54: error: undefined reference to 'image<float>::~image()'
../src/segment/filter.cpp:63: error: undefined reference to 'image<float>::image(int, int, bool)'
../src/segment/imconv.cpp:15: error: undefined reference to 'image<unsigned char>::image(int, int, bool)'
../src/segment/imconv.cpp:31: error: undefined reference to 'image<rgb>::image(int, int, bool)'
../src/segment/imconv.cpp:46: error: undefined reference to 'image<float>::image(int, int, bool)'
../src/segment/imconv.cpp:73: error: undefined reference to 'image<unsigned char>::image(int, int, bool)'
../src/segment/imconv.cpp:90: error: undefined reference to 'void min_max<float>(image<float>*, float*, float*)'
../src/segment/imconv.cpp:97: error: undefined reference to 'image<long>::image(int, int, bool)'
../src/segment/imconv.cpp:110: error: undefined reference to 'image<unsigned char>::image(int, int, bool)'
../src/segment/imconv.cpp:127: error: undefined reference to 'void min_max<long>(image<long>*, long*, long*)'
../src/segment/imconv.cpp:135: error: undefined reference to 'image<unsigned char>::image(int, int, bool)'
../src/segment/imconv.cpp:152: error: undefined reference to 'void min_max<short>(image<short>*, short*, short*)'
../src/segment/segment-image.cpp:62: error: undefined reference to 'smooth(image<float>*, float)'
../src/segment/segment-image.cpp:63: error: undefined reference to 'smooth(image<float>*, float)'
../src/segment/segment-image.cpp:64: error: undefined reference to 'smooth(image<float>*, float)'
../src/segment/segment-image.cpp:65: error: undefined reference to 'image<float>::~image()'
../src/segment/segment-image.cpp:66: error: undefined reference to 'image<float>::~image()'
../src/segment/segment-image.cpp:120: error: undefined reference to 'image<rgb>::image(int, int, bool)'
../src/segment/segment-image.cpp:121: error: undefined reference to 'image<int>::image(int, int, bool)'
../src/segment/pnmfile.h:166: error: undefined reference to 'image<rgb>::image(int, int, bool)'
../src/segment/pnmfile.h:166: error: undefined reference to 'image<rgb>::image(int, int, bool)'
collect2: ld returned 1 exit status
make: *** [HelloOpenCV2] Error 1
18:54:30 Build Finished (took 8s.826ms)
I can also confirm that .o (object) files for each of the source files are generated. However, I do not understand how to fix the undefined reference error.
Would like to add that the file image.cpp / image.h contain a class definition. I have not added these 2 files as add->class have added them as add->source and add->header
Just applied "nm" command on image.o. Got an empty response. Although image.o is a 24 byte file.
image.h contains the template class declaration and image.cpp contains class function definition.
Image is a template class. The header and source for it are as -
/*
* image.h
*
* Created on: 25 Oct, 2014
* Author: eeuser
*/
#ifndef IMAGE_H_
#define IMAGE_H_
#include <cstring>
/* use imRef to access image data. */
#define imRef(im, x, y) (im->access[y][x])
/* use imPtr to get pointer to image data. */
#define imPtr(im, x, y) &(im->access[y][x])
template <class T>
class image {
public:
/* create an image */
image(int width, int height, bool init = true);
/* delete an image */
~image();
/* init an image */
void init(const T &val);
/* copy an image */
image<T> *copy() const;
/* get the width of an image. */
int width() const { return w; }
/* get the height of an image. */
int height() const { return h; }
/* image data. */
T *data;
/* row pointers. */
T **access;
private:
int w, h;
};
#endif /* IMAGE_H_ */
The source:
/*
* image.cpp
*
* Created on: 25 Oct, 2014
* Author: eeuser
*/
#include "image.h"
template <class T>
image<T>::image(int width, int height, bool init) {
w = width;
h = height;
data = new T[w * h]; // allocate space for image data
access = new T*[h]; // allocate space for row pointers
// initialize row pointers
for (int i = 0; i < h; i++)
access[i] = data + (i * w);
if (init)
memset(data, 0, w * h * sizeof(T));
}
template <class T>
image<T>::~image() {
delete [] data;
delete [] access;
}
template <class T>
void image<T>::init(const T &val) {
T *ptr = imPtr(this, 0, 0);
T *end = imPtr(this, w-1, h-1);
while (ptr <= end)
*ptr++ = val;
}
template <class T>
image<T> *image<T>::copy() const {
image<T> *im = new image<T>(w, h, false);
memcpy(im->data, data, w * h * sizeof(T));
return im;
}
I turned on the extra warning flags in g++ (-Wextra). It complained about a bunch of static functions I had. I just changed those to normal functions. I guess this is ok, since those functions were not associated with a class.
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.