I am developing a library called libspellcheck, and a program that uses it to check spelling called spellcheck. Here is my directory structure:
libspellcheck
-> doc
-> man
-> libspellcheck (libspellcheck source)
-> spellcheck (spellcheck source)
I wanted to use a configure script instead of a plain Makefile as I had been using. Everything goes okay until I try compiling spellcheck:
Making all in libspellcheck
make[1]: Entering directory `/home/iandun/libspellcheck-devel/libspellcheck/libspellcheck'
g++ -DHAVE_CONFIG_H -I. -g -O2 -MT checker.o -MD -MP -MF .deps/checker.Tpo -c -o checker.o checker.cpp
mv -f .deps/checker.Tpo .deps/checker.Po
g++ -DHAVE_CONFIG_H -I. -g -O2 -MT SpellCorrector.o -MD -MP -MF .deps/SpellCorrector.Tpo -c -o SpellCorrector.o SpellCorrector.cpp
mv -f .deps/SpellCorrector.Tpo .deps/SpellCorrector.Po
rm -f libspellcheck.a
ar cru libspellcheck.a checker.o SpellCorrector.o
ranlib libspellcheck.a
make[1]: Leaving directory `/home/iandun/libspellcheck-devel/libspellcheck/libspellcheck'
Making all in spellcheck
make[1]: Entering directory `/home/iandun/libspellcheck-devel/libspellcheck/spellcheck'
g++ -DHAVE_CONFIG_H -I. -g -O2 -MT spellcheck.o -MD -MP -MF .deps/spellcheck.Tpo -c -o spellcheck.o spellcheck.cpp
spellcheck.cpp: In function 'int main(int, char**)':
spellcheck.cpp:111:21: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
char *dictionary = "/etc/english.dict"; //Default Dictionary
^
spellcheck.cpp:164:14: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
dictionary = "/etc/english.dict";
^
mv -f .deps/spellcheck.Tpo .deps/spellcheck.Po
g++ -DHAVE_CONFIG_H -I. -g -O2 -MT meta.o -MD -MP -MF .deps/meta.Tpo -c -o meta.o meta.cpp
mv -f .deps/meta.Tpo .deps/meta.Po
g++ -g -O2 "../libspellcheck/libspellcheck.a" -o spellcheck spellcheck.o meta.o
spellcheck.o: In function `correctMisspelled(std::string, std::string)':
/home/iandun/libspellcheck-devel/libspellcheck/spellcheck/spellcheck.cpp:29: undefined reference to `correctSpelling(std::string, std::string)'
spellcheck.o: In function `doFileCheck(char*, char*, char*, spelling)':
/home/iandun/libspellcheck-devel/libspellcheck/spellcheck/spellcheck.cpp:61: undefined reference to `check_spelling_file(char*, char*, std::string)'
spellcheck.o: In function `main':
/home/iandun/libspellcheck-devel/libspellcheck/spellcheck/spellcheck.cpp:193: undefined reference to `add_word(char*, char*)'
/home/iandun/libspellcheck-devel/libspellcheck/spellcheck/spellcheck.cpp:224: undefined reference to `check_spelling_string(char*, std::string, std::string)'
meta.o: In function `do_about_msg()':
/home/iandun/libspellcheck-devel/libspellcheck/spellcheck/meta.cpp:29: undefined reference to `lib_version()'
collect2: error: ld returned 1 exit status
make[1]: *** [spellcheck] Error 1
make[1]: Leaving directory `/home/iandun/libspellcheck-devel/libspellcheck/spellcheck'
make: *** [all-recursive] Error 1
I put a reference to libspellcheck.a in my Makefile.am file in the spellcheck directory:
CFLAGS = -m32 -Wall
LDFLAGS = "../libspellcheck/libspellcheck.a"
bin_PROGRAMS = spellcheck
spellcheck_SOURCES = spellcheck.cpp meta.cpp
And also changed my references to the spellcheck header file:
#include "../libspellcheck/spellcheck.h"
Here is my Makefile.am in the libspellcheck folder:
CFLAGS = -m32 -Wall
LDFLAGS =
lib_LIBRARIES = libspellcheck.a
libspellcheck_a_SOURCES = checker.cpp SpellCorrector.cpp
include_HEADERS = spellcheck.h SpellCorrector.h
Here is my Makefile.am in the main folder:
AUTOMAKE_OPTIONS = foreign
SUBDIRS = libspellcheck spellcheck man
And my configure.ac:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT(libspellcheck, 1.25, corinthianmonthly#hotmail.com)
AC_OUTPUT(Makefile libspellcheck/Makefile spellcheck/Makefile man/Makefile)
AC_CONFIG_SRCDIR([])
AC_CONFIG_HEADERS([])
AM_INIT_AUTOMAKE
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_CXX
AC_PROG_RANLIB
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h,iostream,fstream,string,stdio.h,sstream,cctype,algorithm,boost/algorithm/string.hpp])
# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_TYPE_SIZE_T
# Checks for library functions.
AC_OUTPUT
What am I doing wrong?
CFLAGS = -m32 -Wall
LDFLAGS = "../libspellcheck/libspellcheck.a"
First, these are user flags. Use the AM_* forms instead.
Second, LDFLAGS is for flags. It is put near the start of the command line. But, for linking, order matters, so you want to use LDADD instead. There are a few ways to do this but perhaps the best is to use the per-target variable:
spellcheck_LDADD = ../libspellcheck/libspellcheck.a
You don't need those quotes.
Related
Structure:
-myProject
-Makefile.am
-configure.ac
-src
-Makefile.am
-main.c
-test.c
-test.h
When I try to compile, I've got the error Undefinded reference to a function from test.c.
Makefile.am:
AUTOMAKE_OPTIONS = foreign
SUBDIRS=src
src/Makefile.am:
bin_PROGRAMS = TEST
AM_CXXFLAGS =-Wall -Wno-psabi -w -pthread -I/usr/local/include
AM_CFLAGS =-Wall -w
#Sources
TEST_SOURCES = test.c main.cpp
TEST_LDADD = #LDFLAGS# -lmosquitto
TEST_LDFLAGS =-lmosquitto
It seem's, that it's not possible to linkt the two sources. Can anybody help me??
ERROR:
make all-recursive
make[1]: Entering directory '/media/sf_Shared/Software/executables/TEST'
Making all in src
make[2]: Entering directory '/media/sf_Shared/Software/executables/TEST/src'
g++ -DHAVE_CONFIG_H -I. -I.. -Wall -Wno-psabi -w -pthread -I/usr/local/include -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.cpp
mv -f .deps/main.Tpo .deps/main.Po
g++ -Wall -Wno-psabi -w -pthread -I/usr/local/include -g -O2 -lmosquitto -o TEST test.o main.o -lmosquitto
/usr/bin/ld: main.o: in function `main':
/media/sf_Shared/Software/executables/TEST/src/main.cpp:564: undefined reference to `open_ports(unsigned int, unsigned int)'
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:366: TEST] Error 1
make[2]: Leaving directory '/media/sf_Shared/Software/executables/TEST/src'
make[1]: *** [Makefile:359: all-recursive] Error 1
make[1]: Leaving directory '/media/sf_Shared/Software/executables/TEST'
make: *** [Makefile:300: all] Error 2
I'm including in the main.cpp the test.h. There is the function open_ports declared(u_int32_t open_ports(u_int32_t a, u_int32_t b);), which is implemented in test.c
This is not an automake issue ā you are doing the right thing (or at least close to) in the Makefile.am.
The problem is that your symbol is declared without extern "C", but defined only in C, so when the C++ compiler takes your main.cpp, it expects to find a mangled symbols (which encodes the signature of the function, that is the number and types of parameters), rather than a plain (C) one.
You can tell that this is the case because it's looking for open_ports(unsigned int, unsigned int) ā rather than just open_ports.
The easiest solution is to change your main.cpp to say:
extern "C" {
#include "test.h"
}
That declares that the test.h header only includes C declarations, which will then generate the right symbol lookup for what you define in test.c.
I am working on the project which has to include the CPLEX tool at some point.
More in detail, I have the following classes implemented
(i.e. the corresponding files): Random.cpp, Instance.cpp, Timer.cpp. Solution.cpp which are included into Hybrid_ea.cpp which also have to include cplex library.
Finally, the project has been executed by running Algorithm.cpp (the main() function defined here).
I want to run the project on Linux platform, creating Makefile which looks like:
TARGET = Algorithm
CXXFLAGS = -ansi -O3
GENOBJS = Random.o
#CPLOBJS = Timer.o Random.o Instance.o Hybrid_ea.o
GREOBJS = Timer.o Random.o Instance.o Solution.o Hybrid_ea.o
SYSTEM = x86-64_linux
LIBFORMAT = static_pic
CPLEXDIR = /home/root/Desktop/projects/software/cplex-12.5/cplex
CONCERTDIR = /home/root/Desktop/projects/software/cplex-12.5/concert
CCC = g++
CCOPT = -m64 -O -fPIC -fexceptions -DNDEBUG -DIL_STD -std=c++11 -fpermissive -w
CPLEXBINDIR = $(CPLEXDIR)/bin/$(BINDIST)
CPLEXLIBDIR = $(CPLEXDIR)/lib/$(SYSTEM)/$(LIBFORMAT)
CONCERTLIBDIR = $(CONCERTDIR)/lib/$(SYSTEM)/$(LIBFORMAT)
CCLNFLAGS = -L$(CPLEXLIBDIR) -lilocplex -lcplex -L$(CONCERTLIBDIR) -lconcert -lm -pthread
CLNFLAGS = -L$(CPLEXLIBDIR) -lcplex -lm -pthread
CONCERTINCDIR = $(CONCERTDIR)/include
CPLEXINCDIR = $(CPLEXDIR)/include
CCFLAGS = $(CCOPT) -I$(CPLEXINCDIR) -I$(CONCERTINCDIR)
all: ${TARGET}
Algorithm: Algorithm.o $(GREOBJS)
$(CCC) $(CCFLAGS) Algorithm.o $(GREOBJS) -o Algorithm $(CCLNFLAGS)
Algorithm.o: Algorithm.cpp
$(CCC) -c $(CCFLAGS) Algorithm.cpp -o Algorithm.o
clean:
#rm -f *~ *.o ${TARGET} core
The linking process is somehow wrong. I checked, my CPLEX version is the right one since the others, simpler projects can be executed;
The full output given when trying to compile the project:
g++ -c -m64 -O -fPIC -fexceptions -DNDEBUG -DIL_STD -std=c++11 -fpermissive -w -I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/cplex/include -I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/concert/include Algorithm.cpp -o Algorithm.o
g++ -ansi -O3 -c -o Timer.o Timer.cc
g++ -ansi -O3 -c -o Random.o Random.cc
g++ -ansi -O3 -c -o Instance.o Instance.cpp
g++ -ansi -O3 -c -o Solution.o Solution.cpp
g++ -ansi -O3 -c -o hybrid_ea.o hybrid_ea.cpp
In file included from hybrid_ea.cpp:22:0:
hybrid_ea.h:39:10: fatal error: ilcplex/ilocplex.h: No such file or directory
#include <ilcplex/ilocplex.h>
^~~~~~~~~~~~~~~~~~~~
compilation terminated.
<builtin>: recipe for target 'hybrid_ea.o' failed
make: *** [hybrid_ea.o] Error 1
Any help would be appreciated.
Only the file Algorithm.cpp is compiled with appropriate options for finding the CPLEX include files:
-I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/cplex/include
-I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/concert/include
As hybrid_ea.h also tries to include some CPLEX header files, the compilation of hybrid_ea.cpp should also have the options above.
If the makefile that you posted in your question is complete, then I suspect that the issue is the following: you didn't define a specific command to compile any .cc or .cpp file, except for Algorithm.cpp. Therefore, all other files are compiled using a default command g++ -ansi -O3 -c -o [file].o [file].cpp. And this default command doesn't have the include directives for the location of the CPLEX libraries.
As explained in ftp://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_10.html, these files are compiled using make's implicit rules. The implicit rule for C++ files is to use $(CXX) -c $(CPPFLAGS) $(CXXFLAGS). Notice how this rule uses CPPFLAGS and CXXFLAGS rather than the variable CCFLAGS that you defined at the end of your makefile to include the proper include directives.
So changing the end of your makefile to the following should work:
CPPFLAGS = $(CCOPT) -I$(CPLEXINCDIR) -I$(CONCERTINCDIR)
all: ${TARGET}
Algorithm: Algorithm.o $(GREOBJS)
$(CCC) $(CCFLAGS) Algorithm.o $(GREOBJS) -o Algorithm $(CCLNFLAGS)
clean:
#rm -f *~ *.o ${TARGET} core
Once you define the variable CPPFLAGS, it will be used automatically to compile any .cpp file that you have in your project.
I'm trying to compile a C++ program that utilizes sqlite3. I'm using this makefile:
CXX = g++
CC = gcc
CFLAGS = -c -O2
CXXFLAGS = -Wall -O3 -std=c++11
SQLFLAGS = -DSQLITE_THREADSAFE=0
OUTPUTBIN = bot
OUTPUTDIR = ./bin/
MKDIR = mkdir -p $(OUTPUTDIR)
OBJECTC = sqlite3.o
CSOURCES = sqlite3.c
CXXSOURCES = main.cpp bot.cpp
all: project
project: createdir sql compilecpp
createdir:
$(MKDIR)
sql:
$(CC) $(CSOURCES) $(SQLFLAGS) $(CFLAGS) -o $(OUTPUTDIR)$(OBJECTC)
compilecpp:
$(CXX) $(OUTPUTDIR)$(OBJECTC) $(CXXSOURCES) $(CXXFLAGS) -o $(OUTPUTDIR)$(OUTPUTBIN)
But outputs these errors:
akf#akf-v5 ~/Documents/Proletarian/c++ $ make
mkdir -p ./bin/
gcc sqlite3.c -DSQLITE_THREADSAFE=0 -c -O2 -o ./bin/sqlite3.o
g++ ./bin/sqlite3.o main.cpp bot.cpp -Wall -O3 -std=c++11 -o ./bin/bot
./bin/sqlite3.o: In function `unixDlError':
sqlite3.c:(.text+0x170f4): undefined reference to `dlerror'
./bin/sqlite3.o: In function `unixDlClose':
sqlite3.c:(.text+0x5de9): undefined reference to `dlclose'
./bin/sqlite3.o: In function `unixDlSym':
sqlite3.c:(.text+0x5e01): undefined reference to `dlsym'
./bin/sqlite3.o: In function `unixDlOpen':
sqlite3.c:(.text+0x5e21): undefined reference to `dlopen'
collect2: error: ld returned 1 exit status
make: *** [compilecpp] Error 1
I'm extremely confused as to what's causing this. I can see that sqlite3 is a C program, but I didn't think it would cause any issues.
The error messages tell that dlerror, dlclose, dlsym and dlopenare used but can't be found. Those functions are part of the dynamic link loader. You have to link the dynamic linker, too. Add -ldl to your link flags. See also dlopen manpage for your system.
A bit late, but - the simplest possible Makefile:
all: sqlite3
sqlite3: sqlite3.o shell.o
gcc sqlite3.o shell.o -lpthread -ldl -o sqlite3
sqlite3.o: sqlite3.c sqlite3.h
gcc -c sqlite3.c -lpthread -ldl -o sqlite3.o
shell.o: shell.c
gcc -c shell.c -lpthread -o shell.o
clean:
rm *.o
rm sqlite3
I'm working on Ubuntu 12.10 with gcc version 4.7.2.
I'm trying to make the following makefile:
CC = g++
CCFLAGS = -fPIC -O3 -Wall -ffast-math -msse -msse2 -fopenmp
LINKFLAGS = -shared -Wl -fopenmp -lgomp
INPUT = im2col.cpp fastpool.cpp local_response_normalization.cpp neuron.cpp
TARGET = libcpputil.so
# If we are going to use MKL, we include additional flags
MKL_FLAGS = -D DECAF_USE_MKL
MKL_LINK_FLAGS = -lmkl_rt
all: $(INPUT)
$(CC) -c $(CCFLAGS) $(INPUT)
$(CC) $(LINKFLAGS) -o $(TARGET) *.o
all_mkl: $(INPUT)
$(CC) -c $(CCFLAGS) $(MKL_FLAGS) $(INPUT)
$(CC) $(LINKFLAGS) $(MKL_LINK_FLAGS) -o $(TARGET) *.o
speedtest_lrn: speedtest_lrn.cpp local_response_normalization.cpp
$(CC) $(CCFLAGS) -lgomp -o speedtest_lrn speedtest_lrn.cpp local_response_normalization.cpp
clean:
rm *.so
rm *.o
But somehow g++ doesn't recognize the option -wl. Here's the error that I'm getting:
make -C layers/cpp/
make[1]: Entering directory `/home/ubuntu/decaf-release-master/decaf/layers/cpp'
g++ -c -fPIC -O3 -Wall -ffast-math -msse -msse2 -fopenmp im2col.cpp fastpool.cpp local_response_normalization.cpp neuron.cpp
g++ -shared -Wl -fopenmp -lgomp -o libcpputil.so *.o
g++: error: unrecognized command line option ā-Wlā
make[1]: *** [all] Error 1
make[1]: Leaving directory `/home/ubuntu/decaf-release-master/decaf/layers/cpp'
make: *** [all] Error 2
Failed to build the C libraries; exiting
EDIT: When I try to remove the "-wl" I get:
ubuntu#ubuntu-VirtualBox:~/decaf-release-master$ python setup.py
make -C layers/cpp/
make[1]: Entering directory `/home/ubuntu/decaf-release-master/decaf/layers/cpp'
g++ -c -fPIC -O3 -Wall -ffast-math -msse -msse2 -fopenmp im2col.cpp fastpool.cpp local_response_normalization.cpp neuron.cpp
g++ -shared -fopenmp -lgomp -o libcpputil.so *.o
make[1]: Leaving directory `/home/ubuntu/decaf-release-master/decaf/layers/cpp'
usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
or: setup.py --help [cmd1 cmd2 ...]
or: setup.py --help-commands
or: setup.py cmd --help
error: no commands supplied
It somehow worked when I tried it on Ubuntu 12.04 and gcc 4.7.7.
Can someone please explain what's the problem and how can I fix it?
Thanks,
Gil.
From the manual:
-Wl,option
Pass option as an option to the linker. If option contains commas, it is split into multiple options at the commas. You can use this
syntax to pass an argument to the option. For example,
-Wl,-Map,output.map passes -Map output.map to the linker. When using the GNU linker, you can also get the same effect with
-Wl,-Map=output.map.
so, you miss the options for -Wl.
I have a project that is a library that links against libresolv,
It works fine on recent distros: Ubuntu 10.x Fedora 13, Mandriva
2010.1 but on Centos 5.x I get the following errors
glibc installed is: glibc-2.5-18.el5_1.1
g++ -DHAVE_CONFIG_H -I. -I./include -I/usr/include/postgresql -O3
-ansi -Wall -Wno-deprecated -D_FORTIFY_SOURCE=0 -MT testUpLog.o -MD
-MP -MF .deps/testUpLog.Tpo -c -o testUpLog.o testUpLog.cc
mv -f .deps/testUpLog.Tpo .deps/testUpLog.Po
/bin/sh ./libtool --tag=CXX --mode=link g++ -O3 -ansi -Wall
-Wno-deprecated -D_FORTIFY_SOURCE=0 -L/usr/lib64 -L/lib64
-L/usr/lib64/mysql -o testUpLog testUpLog.o libUpTools.la -lpq
-lmysqlclient -lssl -lpthread
libtool: link: g++ -O3 -ansi -Wall -Wno-deprecated -D_FORTIFY_SOURCE=0
-o .libs/testUpLog testUpLog.o -L/usr/lib64 -L/lib64
-L/usr/lib64/mysql ./.libs/libUpTools.so -lpq -lmysqlclient -lssl
-lpthread
./.libs/libUpTools.so: undefined reference to `__ns_name_uncompress'
./.libs/libUpTools.so: undefined reference to `__ns_initparse'
./.libs/libUpTools.so: undefined reference to `__ns_parserr'
collect2: ld returned 1 exit status
make[1]: *** [testUpLog] Error 1
make[1]: Leaving directory `/tmp/UpTools-8.5.3'
make: *** [check-am] Error 2
library.la file contains:
dlname='libUpTools.so.0'
library_names='libUpTools.so.0.0.0 libUpTools.so.0 libUpTools.so'
old_library='libUpTools.a'
inherited_linker_flags=''
dependency_libs=' -L/usr/lib64 -L/lib64 -L/usr/lib64/mysql -lpq
-lmysqlclient -lssl -lpthread'
weak_library_names=''
current=0
age=0
revision=0
installed=no
shouldnotlink=no
dlopen=''
dlpreopen=''
libdir='/usr/lib'
You can read configure.ac on
http://pastebin.com/hs5q21Rq
Thanks in advance
If libUpTools uses functions lib libresolv, you need to say so:
libUpTools_la_LIBADD = -lresolv (of course -lresolv may be replaced by variables determined by configure etc.)
That way, -lresolv will end up in the .la file and also in the .so file (if you chose to build it) that you can run ldd on for verification.