I want to link my project to a static library (msodbcsql11.lib), and I want to include it's header (msodbcsql.h) and another header file of a framework otlv4.h) using a simple makefile, but it looks like it can't find the library. Here is my makefile:
CC=g++
LDFLAGS=
CFLAGS=-c -Wall
SOURCES=main.cpp
LIBB = C:\temp\lib
LIBINCL = C:\temp\include
CFLAGS += -I$(LIBINCL)
LDFLAGS += -L$(LIBB)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=main
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
And here is my c++ code:
#include <iostream>
#define OTL_ODBC_MSSQL_2008 // Compile OTL 4/ODBC, MS SQL 2008
#include <otlv4.h>
int main(){
otl_connect db; //undefined reference errors
}
Here is the build when I declared otl_connect:
18:42:33 **** Incremental Build of configuration Default for project mak ****
make all
g++ -c -Wall -IC:\temp\include main.cpp -o main.o
g++ -LC:\temp\lib main.o -o main
main.o:main.cpp:(.text$_ZN8otl_connD1Ev[_ZN8otl_connD1Ev]+0x66): undefined reference to `SQLFreeHandle'
main.o:main.cpp:(.text$_ZN8otl_connD1Ev[_ZN8otl_connD1Ev]+0x66): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `SQLFreeHandle'
main.o:main.cpp:(.text$_ZN8otl_connD1Ev[_ZN8otl_connD1Ev]+0x9e): undefined reference to `SQLFreeHandle'
main.o:main.cpp:(.text$_ZN8otl_connD1Ev[_ZN8otl_connD1Ev]+0x9e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `SQLFreeHandle'
main.o:main.cpp:(.text$_ZN8otl_conn6logoffEv[_ZN8otl_conn6logoffEv]+0x54): undefined reference to `SQLDisconnect'
main.o:main.cpp:(.text$_ZN8otl_conn6logoffEv[_ZN8otl_conn6logoffEv]+0x54): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `SQLDisconnect'
main.o:main.cpp:(.text$_ZN8otl_conn5errorER7otl_exc[_ZN8otl_conn5errorER7otl_exc]+0x70): undefined reference to `SQLGetDiagRec'
main.o:main.cpp:(.text$_ZN8otl_conn5errorER7otl_exc[_ZN8otl_conn5errorER7otl_exc]+0x70): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `SQLGetDiagRec'
main.o:main.cpp:(.text$_ZN8otl_conn6commitEv[_ZN8otl_conn6commitEv]+0x23): undefined reference to `SQLEndTran'
main.o:main.cpp:(.text$_ZN8otl_conn6commitEv[_ZN8otl_conn6commitEv]+0x23): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `SQLEndTran'
collect2: error: ld returned 1 exit status
makefile:14: recipe for target 'main' failed
make: *** [main] Error 1
18:42:35 Build Finished (took 1s.993ms)
What is wrong with my makefile? What should I do?
edit: I updated based on #Jonathan Wakely's answer:
LIBB = C:\temp\lib
LIBFILE = msodbcsql11
LDFLAGS += -L$(LIBB) -l$(LIBFILE)
I'm still getting the same errors
Update: Updated makefile as suggested by #Jonathan Wakely, but still getting errors. BTW, I changed the file format of libmsodbcsql11.lib to libmsodbcsql11.a because the compiler can't detect the .lib version
CC=g++
LDFLAGS=
CFLAGS=-c -Wall
SOURCES=main.cpp
LIBB = C:\temp\lib
LIBFILE = msodbcsql11
LIBINCL = C:\temp\include
CFLAGS += -I$(LIBINCL)
OBJECTS=$(SOURCES:.cpp=.o)
LDFLAGS += -L$(LIBB) -l$(LIBFILE)
EXECUTABLE=main
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
The -L flag only tells the linker where to look for libraries, you need to use -l to tell it which library to link to.
This might be helpful...
Apparently the OTL library requires the odbc32.lib file to call ODBC functions. It's a little confusing because the microsoft ODBC driver have this msodbcsql11.lib, apparently it is not what's needed. Regardless the previous versions of my makefile did not call any library, so I accepted #Jonathan Wakely's answer.
Related
For context, I'm trying to compile source to a 32-bit executable for Windows using a Linux machine. I'm using the current mingw-w64 via apt-get. Here's the project I'm trying to compile ftp://ftp.thegpm.org/projects/tandem/source. More specifically the 17-02-01 zip files contain the source I'm interested in.
My first attempt was to just edit with the Makefile_ubuntu under the tandem-linux and swap out the gcc with the one provided by mingw and fix header reference issues that cropped up by adding #includes to .cpp files that threw errors. Super hacky. Can someone show me a brighter path?
Here's the makefile I'm using:
#makefile for c++ programs
#change the name of the executable to use for "any" project
EXECUTABLE = ../bin/tandem.exe
#EXECUTABLE = ../bin/p3.exe
LINKCC = $(CXX)
#CXXFLAGS denotes flags for the C++ compiler
CXX = /usr/bin/i686-w64-mingw32-g++-win32
#uncomment this line if you are using gcc 4.x
CXXFLAGS = -m32 -std=gnu++11
#CXXFLAGS = -w -O2 -DGCC4_3
#CXXFLAGS = -w -O2 -DGCC4_3 -DX_P3
#ubuntu 64 bit version
#LDFLAGS = -L/usr/lib/x86_64-linux-gnu/libexpat.a
LDFLAGS = -lpthread -lm -L/usr/lib/x86_64-linux-gnu/libexpat.a
#LDFLAGS = -lpthread -L/usr/lib -lm -lexpat
SRCS := $(wildcard *.cpp)
OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp))
DEPS := $(patsubst %.o,%.d,$(OBJS))
all: $(EXECUTABLE)
#define the components of the program, and how to link them
#these components are defined as dependencies; that is they must be up-to-date before the code is linked
$(EXECUTABLE): $(DEPS) $(OBJS)
$(LINKCC) $(CXXFLAGS) -o $(EXECUTABLE) $(OBJS) $(LDFLAGS)
#specify the dep files depend on the cpp files
%.d: %.cpp
$(CXX) -M $(CXXFLAGS) $< > $#
$(CXX) -M $(CXXFLAGS) $< | sed s/\\.o/.d/ > $#
clean:
-rm $(OBJS) $(EXECUTABLE) $(DEPS) *~
explain:
#echo "The following info represents the program:"
#echo "Final exec name: $(EXECUTABLE)"
#echo "Source files: $(SRCS)"
#echo "Object files: $(OBJS)"
#echo "Dep files: $(DEPS)"
depend: $(DEPS)
#echo "Deps are now up-to-date."
-include $(DEPS)
And here is the error(s):
sudo make -f Makefile_ubuntu
/usr/bin/i686-w64-mingw32-g++-win32 -m32 -std=gnu++11 -o ../bin/tandem.exe tandem.o p3mprocess.o saxmzdatahandler.o mspectrumcondition.o masscalc.o mprocess.o mreport.o mscore_tandem.o loadmspectrum.o mplugin.o msequenceserver.o saxtaxhandler.o msequencecollection.o mscore.o mrefine.o xmltaxonomy.o mbiomlreport.o saxtandeminputhandler.o saxhandler.o msequtilities.o base64.o saxmodhandler.o mtermmods.o xmlparameter.o saxsaphandler.o saxmzxmlhandler.o saxmzmlhandler.o mxxcleavage.o p3msequenceserver.o mzid_report.o saxbiomlhandler.o p3.o mpmods.o saxgamlhandler.o stdafx.o MSNumpress.o mpam.o -lpthread -lm -L/usr/lib/x86_64-linux-gnu/libexpat.a
saxhandler.o:saxhandler.cpp:(.text+0x100): undefined reference to `XML_ParserCreate'
saxhandler.o:saxhandler.cpp:(.text+0x11d): undefined reference to `XML_SetUserData'
saxhandler.o:saxhandler.cpp:(.text+0x13b): undefined reference to `XML_SetElementHandler'
saxhandler.o:saxhandler.cpp:(.text+0x151): undefined reference to `XML_SetCharacterDataHandler'
saxhandler.o:saxhandler.cpp:(.text+0x1cf): undefined reference to `XML_ParserFree'
saxhandler.o:saxhandler.cpp:(.text+0x344): undefined reference to `XML_Parse'
saxhandler.o:saxhandler.cpp:(.text+0x37f): undefined reference to `XML_Parse'
saxhandler.o:saxhandler.cpp:(.text+0x3bd): undefined reference to `XML_GetErrorCode'
saxhandler.o:saxhandler.cpp:(.text+0x3d4): undefined reference to `XML_GetCurrentLineNumber'
collect2: error: ld returned 1 exit status
Makefile_ubuntu:33: recipe for target '../bin/tandem.exe' failed
make: *** [../bin/tandem.exe] Error 1
You are (incorrectly) linking with /usr/lib/x86_64-linux-gnu/libexpat.a which is a Linux library (in ELF format). You need to get some Windows version of it.
BTW -L/usr/lib/x86_64-linux-gnu/libexpat.a is incorrect. Since -L should give a directory not a library to link
At last, recent versions of Windows might have WSL which could be useful to you (you'll compile a Linux, mostly statically linked, executable, and it might run on the command line on Windows).
Below is my makefile
#Makefile for beaglebone
#General tools
CC=gcc
CFLAGS = -g -Wall
RM = rm -fr
TARGET = beaglebone
# Source locations
BACNET_CORE = ../../src
BACNET_INCLUDE = ../../include
BACNET_HANDLER = ../../demo/handler
BACNET_OBJECT = ../../demo/object
BACNET_DEMO = ../../demo
# local files for this project
CSRC = main.c arcnet.c bip-init.c dlmstp.c dlmstp_linux.c ethernet.c rs485.c timer.c device.c
#common demo files needed
DEMOSRC = $(BACNET_DEMO)/handler/txbuf.c $(BACNET_DEMO)/handler/h_npdu.c $(BACNET_DEMO)/handler/s_iam.c $(BACNET_DEMO)/handler/noserv.c
# core BACnet stack files
CORESRC = $(BACNET_CORE)/crc.c $(BACNET_CORE)/npdu.c $(BACNET_CORE)/bacdcode.c $(BACNET_CORE)/bacint.c $(BACNET_CORE)/bacreal.c \
$(BACNET_CORE)/bacstr.c $(BACNET_CORE)/iam.c $(BACNET_CORE)/rp.c $(BACNET_CORE)/wp.c $(BACNET_CORE)/whois.c $(BACNET_CORE)/bacaddr.c \
$(BACNET_CORE)/abort.c $(BACNET_CORE)/reject.c $(BACNET_CORE)/bacerror.c $(BACNET_CORE)/bacapp.c
## Include Directories
INCLUDES = -I. -I$(BACNET_INCLUDE)
INCLUDES += -I$(BACNET_OBJECT)
INCLUDES += -I$(BACNET_HANDLER)
# Source to Object conversion
COBJ = $(CSRC:.c=.o)
DEMOOBJ = $(DEMOSRC:.c=.o)
COREOBJ = $(CORESRC:.c=.o)
OBJECTS = $(COBJ) $(DEMOOBJ) $(COREOBJ)
#Build and Link the objects
all: $(TARGET)
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $*.c -o $#
$(TARGET) : $(OBJECTS)
$(CC) $(CFLAGS) $(INCLUDES) $(OBJECTS) -o $(TARGET)
.PHONY: clean
clean:
$(RM) *.o *~ $(TARGET)
when issue make I get the .o files created and it does not creates an executable. I get the output as follows:
s_iam.c:(.text+0xed): undefined reference to `bip_get_my_address'
../../demo/handler/s_iam.o: In function `Send_I_Am_Unicast':
s_iam.c:(.text+0x16c): undefined reference to `bvlc_send_pdu'
../../demo/handler/noserv.o: In function `handler_unrecognized_service':
noserv.c:(.text+0x14): undefined reference to `bip_get_my_address'
noserv.c:(.text+0x6b): undefined reference to `bvlc_send_pdu'
../../src/bacapp.o: In function `bacapp_copy':
bacapp.c:(.text+0x7ac): undefined reference to `datetime_copy_date'
bacapp.c:(.text+0x7bb): undefined reference to `datetime_copy_time'
../../src/bacapp.o: In function `bacapp_snprintf_value':
bacapp.c:(.text+0xba4): undefined reference to `bactext_object_type_name'
bacapp.c:(.text+0xbbc): undefined reference to `bactext_event_state_name'
bacapp.c:(.text+0xbce): undefined reference to `bactext_engineering_unit_name'
bacapp.c:(.text+0xbe1): undefined reference to `bactext_binary_polarity_name'
bacapp.c:(.text+0xbf0): undefined reference to `bactext_binary_present_value_name'
bacapp.c:(.text+0xbfa): undefined reference to `bactext_reliability_name'
bacapp.c:(.text+0xc04): undefined reference to `bactext_device_status_name'
bacapp.c:(.text+0xc0e): undefined reference to `bactext_segmentation_name'
bacapp.c:(.text+0xc18): undefined reference to `bactext_node_type_name'
bacapp.c:(.text+0xc45): undefined reference to `bactext_day_of_week_name'
bacapp.c:(.text+0xc84): undefined reference to `bactext_month_name'
bacapp.c:(.text+0xe28): undefined reference to `bactext_object_type_name'
../../src/bacapp.o: In function `bacapp_parse_application_data':
bacapp.c:(.text+0x10bd): undefined reference to `datetime_set_date'
collect2: error: ld returned 1 exit status
make: *** [beaglebone] Error 1
Kindly tell me where I am going wrong and many thanks for your help and suggestions!!!
Regards,
Gibson
Looks like your object files are in a bit of a random order, so that later object files refer to symbol defined in earlier object files and this is why the link fails.
Try the following. Replace:
$(TARGET) : $(OBJECTS)
$(CC) $(CFLAGS) $(INCLUDES) $(OBJECTS) -o $(TARGET)
With:
$(TARGET) : $(OBJECTS)
$(CC) -o $# -Wl,--start-group $(OBJECTS) -Wl,--end-group
That is going to make ld to scan the object files for missing symbols a few times (like MSVC does).
I have project files and I need to use an external test file named TestSuite1.cpp that includes an external header file SignalMasker.h (Was given it and it's object file SignalMasker.o) and my main header file uthreads.h.
I'm still getting undefined refrences such as:
TestSuite1.cpp:63: error: undefined reference to 'SignalMasker::~SignalMasker()'
This means my Makefile isn't including the SignalMasker.o file that resides in the same directory.
This is my Makefile:
CC = g++
FLAGS = -Wall -g
OBJECTS = uthreads.o Thread.o Scheduler.o SchedulerStarter.o TestSuite1.o
.PHONY : clean
all: test1
test1: $(OBJECTS)
g++ $(FLAGS) $(OBJECTS) SignalMasker.o -L . -o test1
TestSuite1.o : TestSuite1.cpp SignalMasker.h uthreads.h
$(CC) -c $(FLAGS) TestSuite1.cpp
uthreads.o : uthreads.cpp uthreads.h SchedulerStarter.h Scheduler.h Thread.h
$(CC) -c $(FLAGS) uthreads.cpp
Scheduler.o : Scheduler.cpp Scheduler.h Thread.h
$(CC) -c $(FLAGS) Scheduler.cpp
SchedulerStarter.o : SchedulerStarter.cpp SchedulerStarter.h Scheduler.h
$(CC) -c $(FLAGS) SchedulerStarter.cpp
Thread.o : Thread.cpp Thread.h uthreads.h translateAdd.h
$(CC) -c $(FLAGS) Thread.cpp
clean:
rm -f $(OBJECTS) *~
And now I'm getting:
~/Desktop/tests$ make
g++ -Wall -g uthreads.o Thread.o Scheduler.o SchedulerStarter.o TestSuite1.o SignalMasker.o -L . -o test1
/usr/bin/ld: error: SignalMasker.o: incompatible target
TestSuite1.cpp:36: error: undefined reference to 'SignalMasker::SignalMasker(int)'
TestSuite1.cpp:63: error: undefined reference to 'SignalMasker::~SignalMasker()'
TestSuite1.cpp:63: error: undefined reference to 'SignalMasker::~SignalMasker()'
TestSuite1.cpp:68: error: undefined reference to 'SignalMasker::SignalMasker(int)'
TestSuite1.cpp:111: error: undefined reference to 'SignalMasker::~SignalMasker()'
TestSuite1.cpp:111: error: undefined reference to 'SignalMasker::~SignalMasker()'
collect2: ld returned 1 exit status
EDIT:
I'm now pondering with the idea that maybe incompatible target means they compiled it under 64bit. My machine is 32bit
you are missing rule to compile SignalMasker.cpp in your makefile. you have to write a rule, the same way you have written for
SchedulerStarter.o, Thread.o
SignalMasker.o : SignalMasker.cpp SignalMasker.h
$(CC) -c $(FLAGS) SignalMasker.cpp
This will ensure the SignalMasker.o is generated with the same compilation flags that you build other objects. It will eliminate incompatibility issues in case of 32-bit/ 64-bit variants.
if you are copying this SignalMasker.o from elsewhere, check the compilation flags used for generating the object. Use the same flags in your makefile.
I have been searching everywhere for a solution to my problem:
I cannot run a .cpp file using CUDA. I think this is a module error since I get the following error:
g++ -L/usr/local/cuda/lib64 -L~/NVIDIA_GPU_Computing_SDK/shared/lib/linux -L~/NVIDIA_GPU_Computing_SDK/C/common/lib/linux -L~/NVIDIA_GPU_Computing_SDK/C/lib -lcutil -lcudpp -lcuda -lcudart -lcurand -o my_file my_file.o
/usr/bin/ld: cannot find -lcutil
/usr/bin/ld: cannot find -lcudpp
My makefile looks like this:
EXECUTABLE := my_file
SDKPATH := ~/NVIDIA_GPU_Computing_SDK
CUDAPATH := /usr/local/cuda
LDFLAGS := -L$(CUDAPATH)/lib64 -L$(SDKPATH)/shared/lib/linux -L$(SDKPATH)/C/common/lib/linux -L$(SDKPATH)/C/lib -lcutil -lcudpp -lcuda -lcudart -lcurand
CXFLAGS := -I$(CUDAPATH)/include -I$(SDKPATH)/shared/inc -I$(SDKPATH)/C/common/inc
CXX := g++
NVCC := $(CUDAPATH)/bin/nvcc
$(EXECUTABLE): my_file.o
$(CXX) $(LDFLAGS) -o $(EXECUTABLE) my_file.o
my_file.o: my_file.cu
$(NVCC) $(CXFLAGS) -c my_file.cu
When I, instead try to run the file manually I get the following output:
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
my_file.o: In function `__cudaUnregisterBinaryUtil()':
tmpxft_00000e8f_00000000-1_my_file.cudafe1.cpp:(.text+0xf): undefined reference to `__cudaUnregisterFatBinary'
my_file.o: In function `__sti____cudaRegisterAll_59_tmpxft_00000e8f_00000000_4_my_file_cpp1_ii_71dc03a4()':
tmpxft_00000e8f_00000000-1_my_file.cudafe1.cpp:(.text+0x1f): undefined reference to `__cudaRegisterFatBinary'
collect2: ld returned 1 exit status
I'm a total noob when it comes to linux.
Can anyone please shed some light on this situation.
Regards
You have an ordering problem in the linking phase of your build. Because the libraries you specify are provided before the files that require them, they get discarded. If you change your makefile to something like:
LDFLAGS := -L$(CUDAPATH)/lib64 -L$(SDKPATH)/shared/lib/linux -L$(SDKPATH)/C/common/lib/linux
LIBS := -lcutil -lcudpp -lcuda -lcudart -lcurand
....
$(EXECUTABLE): my_file.o
$(CXX) $(LDFLAGS) -o $(EXECUTABLE) my_file.o $(LIBS)
you should find the problem goes away.
I have been struggling to compile and link a C++ application that uses Boost libraries under a Ubuntu Server 11.01 64-bit edition.
At first not suceeding with prepackaged Boost libraries, I decided to compile it on my own. Boost compiles with no problem, but when I try to compile an application, linker starts spewing out errors as though no libraries were included.
builtinFunctions.o: In function `__static_initialization_and_destruction_0(int, int)':
builtinFunctions.cpp:(.text+0xcaab): undefined reference to `boost::system::generic_category()'
builtinFunctions.cpp:(.text+0xcab7): undefined reference to `boost::system::generic_category()'
builtinFunctions.cpp:(.text+0xcac3): undefined reference to `boost::system::system_category()'
builtinFunctions.o: In function `boost::system::error_code::error_code()':
builtinFunctions.cpp:(.text._ZN5boost6system10error_codeC2Ev[_ZN5boost6system10error_codeC5Ev]+0x17): undefined reference to `boost::system::system_category()'
builtinFunctions.o: In function `boost::filesystem3::exists(boost::filesystem3::path const&)':
...
This is a Makefile that I use:
CC=g++
CFLAGS=-std=c++0x -c -Wall -I . -I ./boost_1_48_0/ -DBOOST_THREAD_USE_LIB
all: project
project: builtinFunctions.o main.o operators.o conversionUtils.o
$(CC) -L./boost_1_48_0/stage/lib/ \
-lpthread -lboost_date_time-gcc46-mt-s-1_48 -lboost_program_options-gcc46-mt-s-1_48 \
-lboost_filesystem-gcc46-mt-s-1_48 -lboost_system-gcc46-mt-s-1_48 builtinFunctions.o \
main.o operators.o conversionUtils.o -o project
main.o: main.cpp
$(CC) $(CFLAGS) main.cpp
operators.o: operators.cpp
$(CC) $(CFLAGS) operators.cpp
conversionUtils.o: conversionUtils.cpp
$(CC) $(CFLAGS) conversionUtils.cpp
builtinFunctions.o: builtinFunctions.cpp
$(CC) $(CFLAGS) builtinFunctions.cpp
clean:
rm -rf *o project
Anything else I could try besides an earlier version of GCC? Thank you.
The order of libraries on link line matters, and yours is wrong.