Reputation: 3848
I am having makefile problems, see below
// make
....
6-linux-gnu/4.7/crtend.o /usr/lib/gcc/i486-linux-gnu/4.7/../../../i386-linux-gnu/crtn.o
read_printer_status.o: In function `pal_printer::printer_status()':
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:123: undefined reference to `openUSBDevice(long, long, char const*)'
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:135: undefined reference to `openUSBDevice(long, long, char const*)'
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:149: undefined reference to `GetPrinterStatus(unsigned char*, unsigned long, unsigned long*)'
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:156: undefined reference to `closeUSBDevice()'
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:179: undefined reference to `closeUSBDevice()'
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:185: undefined reference to `closeUSBDevice()'
collect2: error: ld returned 1 exit status
make: *** [printer2] Error 1
// make -n
root@pc223:/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src# make -n
g++ -g -Wall -m32 -v -I../include -c printer2.cc -o printer2.o
g++ -g -Wall -m32 -v -I../include -c read_printer_status.cc -o read_printer_status.o
g++ -g -Wall -m32 -v -I../include -c printer2_user.cc -o printer2_user.o
g++ -g -Wall -m32 -v -I../include -o printer2 printer2.o read_printer_status.o printer2_user.o -L../lib -lCeSmLm
My makefile. I am using a shared library.so, some header files, and .cc files
# Compiler
# for c code: CC = gcc; for c++ code: CC = g++; locate g++
CC = g++
# Compiler flags:
# -g adds debugging information to the executable file
# -Wall turns on most, but not all, compiler warnings
# -m32 compiles for 32 bit OS
# -v verbose displays more compiler debugging information
CFLAGS = -g -Wall -m32 -v
# define any directories containing header files other than /usr/include
INCLUDE = -I../include
# define library paths in addition to /usr/lib
# if I wanted to include libraries not in /usr/lib I'd specify
# their path using -Lpath, something like:
LFLAGS= -L../lib
# define any libraries to link into executable:
# if I want to link in libraries (libx.so or libx.a) I use the -lname
# without lib in front or an extension
LIBS = -lCeSmLm
# define the C source files
SRCS = printer2.cc read_printer_status.cc printer2_user.cc
# define the C object files
#
# This uses Suffix Replacement within a macro:
# $(name:string1=string2)
# For each word in 'name' replace 'string1' with 'string2'
# Below we are replacing the suffix .c of all words in the macro SRCS
# with the .o suffix
#
OBJS = $(SRCS:.cc=.o)
# define the executable file
EXE = printer2
#
# The following part of the makefile is generic; it can be used to
# build any executable just by changing the definitions above and by
# deleting dependencies appended to the file from 'make depend'
#
.PHONY: depend clean
all: $(EXE)
$(EXE): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDE) -o $(EXE) $(OBJS) $(LFLAGS) $(LIBS)
# this is a suffix replacement rule for building .o's from .c's
# it uses automatic variables $<: the name of the prerequisite of
# the rule(a .c file) and $@: the name of the target of the rule (a .o file)
# (see the gnu make manual section about automatic variables)
.cc.o:
$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
clean:
$(RM) *.o *~ $(EXE)
depend: $(SRCS)
makedepend $(INCLUDE) $^
CeSmLm.h is below
// Custom Engineering SPA
// USB "interface 0" C library for communication with Custom printers
#ifndef _COM_USB_IF0_CUSTOM_H
#define _COM_USB_IF0_CUSTOM_H 1
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <sys/time.h>
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned short BOOL;
// ---------- 'PUBLIC' FUNCTIONS ----------:
/* This function initialized and opens the USB printer status connection , with the specified parameters.
Parameters:
- Vendor ID (int)
- Product ID (int)
- Serial Number (constant string)
Usage example: InitDeviceIf0(0xdd4, 0x01A8, ,TG2480H Num.: 0");
Note:
- 1st parameter = -1 : all Vendor IDs will be accepted (be careful!!!) ***
- 2nd parameter = -1 : all Product IDs will be accepted
- 3rd parameter = NULL or 'empty string' : all Serial Numbers will be accepted
Return values:
- SUCCESS
- ERR_NO_INIT
- ERR_OPEN_DEVICE
- ERR_ALREADY_OPENED
- ERR_PARAMINIT_NOT_VALID
*/
DWORD openUSBDevice(long,long,const char*);
/*
This function the printer status
Parameters:
- buffer to store data in
- size of the provided buffer
- return parameter, where the function will store actually read data size
Return values:
- ERR_NOT_OPENED
- ERR_IOCTL_SEND
- ERR_IOCTL_PIPE
- ERR_IOCTL_OVERFLOW
- ERR_IOCTL_LOW_LEVEL
- ERR_IOCTL_GENERAL
- ERR_IOCTL_TIMEOUT
- ERR_READ_BUFFER_FULL
- ERR_READING_USB
- SUCCESs
*/
DWORD GetPrinterStatus(unsigned char* bufferRecv,const DWORD dwSize,DWORD* dwRead);
/* This function closes the printer USB status device.
Return values:
- ERR_NOT_OPENED
- ERR_CLOSE
- SUCCESS
*/
DWORD closeUSBDevice();
#endif
Is it a linking problem with the object files, or header, or library? I am not sure.
Upvotes: 0
Views: 1293
Reputation: 1
"Is it a linking problem with the object files, or header, or library? I am not sure."
It's a clash of c and c++ symbol names actually (thus a combined problem of all these you mentioned).
// USB "interface 0" C library for communication with Custom printers
This comment obviously indicates that this library is pure c and the function symbol names in the linked library won't be mangled as c++ does.
If you include this header with a .cpp
c++ translation unit and use g++
(vs gcc
) to compile it, the declarations made in the included header file will be mangled by the c++ compiler to reflect their parameter signatures in the symbol names, that will be used by the linker actually.
That's because c++ allows to overload functions by just giving them different sets of parameters (the signature). c doesn't support such feature, you have to make function name symbols distinct yourself.
That library you're using isn't aware of c++, modern c headers will take that into account for compatibility with c++ by putting a
extern "C" {
}
block around all of the function declarations.
Well, you can fix this by putting that block yourself just to enclose the #include
statement
extern "C" {
#include "CeSmLm.h"
}
See this already existing answer also explaining what's said above. You should consider researching the answers in this post 1st, whenever hitting an undefined reference
linker error.
Upvotes: 3