I'm attempting to make 3 separate programs mem_1.exe, mem_2.exe and mem_3.exe. I need to make them 32 bit when I compile them and the error message does not seem to be reflecting what I am writing. Below is my makefile.
mem_1: memlayout.o mem_1.o
gcc -o mem_1 memlayout.c mem_1.c -ldl -m32
mem_2: memlayout.o mem_2.o
gcc -o mem_2 memlayout.c mem_2.c -m32 -ldl
mem_3: memlayout.o mem_3.o
gcc -o mem_3 memlayout.c mem_3.c -m32 -ldl
mem_1.o: mem_1.c
gcc -c -o mem_1 mem_1.c -m32
mem_2.o: mem_2.c
gcc -c -o mem_2 mem_2.c -m32
mem_3.o: mem_3.c
gcc -c -o mem_3 mem_3.c -m32
memlayout.o: memlayout.c
gcc -c -o memlayout memlayout.c -m32
clean:
rm -f mem_1.o mem_2.o mem_3.o memlayout.o *~
Everytime I attempt to run this makefile I get this error message
cc -c -o memlayout.o memlayout.c
cc -c -o mem_1.o mem_1.c
gcc -o mem_1.exe mem_1.o memlayout.o -m32 -ldl
/usr/bin/ld: i386:x86-64 architecture of input file `mem_1.o' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `memlayout.o' is incompatible with i386 output
Which doesn't seem to make sense since I am using the -m32 flag to make it a 32 bit. Can anyone explain what I'm doing wrong?
I'd advise thinking of your makefile as code (since it is) and follow the standard advice to avoid repeating yourself.
It looks like you also have the flags a bit wrong. -m32 is a compiler flag. -ldl is a linker flag. If you're going to build for 32 bits, you need to tell both the compiler and the linker to built 32-bit files. No guarantee, but I think you want something on this general order:
CFLAGS = -m32
LFLAGS = -melf_i386 -ldl
mem_1: mem_1.o memlayout.o
$(LD) $(LFLAGS) -o mem_1 mem_1.o memlayout.o
mem_2: mem_2.o memlayout.o
$(LD) $(LFLAGS) -o mem_2 mem_2.o memlayout.o
mem_3: mem_3.o memlayout.o
$(LD) $(LFLAGS) -o mem_3 mem_3.o memlayout.o
# You probably don't really need this--`make` will usually have it built-in:
.c.o:
$(CC) -c $(CFLAGS) $<
Note: I'm old, so this is a sort of old-fashioned Makefile. Gnu recommends doing things a bit differently, but this should still work.
Related
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.
Is there any guide how to configure the .yml file on the Travis to get the LLVM >= 3.8?
This is the part of the Makefile that I'm using to compile my program:
all: program
OBJS = obj1.o obj2.o obj3.o obj4.o
CPPFL = `llvm-config --cppflags` -std=c++11
LDFL = `llvm-config --ldflags` -lpthread -ldl -lz -lncurses -rdynamic
LIBS = `llvm-config --libs`
program: $(OBJS)
g++ -o $# $(OBJS) $(LIBS) $(LDFL)
%.o: %.cpp
g++ -c $(CPPFL) -o $# $<
Thanks in advance.
This is still an open issue.
The most relevant examples I could find to help are this and this.
So yeah, you basically need to set up the specific toolchain yourself on the Travis VM.
PS: I could have added this as a comment, but not enough rep :S
I have a makefile as follows:
# Makefile for VocabLearn
MACHTYPE=$(shell uname -m)
GCC = g++
CC=gcc
# OPTFLAGS=-g2
OPTFLAGS=-O3 -ffast-math -Wall -mfpmath=sse -msse2 -funroll-loops -march=core2
OTHERFLAGS=-Wall -fopenmp
INCLUDE_PATH=-I../lib/ann_1.1/include/ANN -I../lib/ann_1.1_char/include/ANN \
-I../lib/imagelib -I../VocabLib -I../lib/zlib/include
LIB_PATH=-L../lib -L../VocabLib -L../lib/zlib/lib
OBJS=VocabLearn.o
LIBS=-lvocab -lANN -lANN_char -limage -lz
CPPFLAGS=$(INCLUDE_PATH) $(LIB_PATH) $(OTHERFLAGS) $(OPTFLAGS)
BIN=VocabLearn
all: $(BIN)
$(BIN): $(OBJS)
g++ -o $(CPPFLAGS) -o $(BIN) $(OBJS) $(LIBS)
clean:
rm -f *.o *~ $(LIB)
When I 'make' it in the prompt, it works fine and output the following info:(I use Mac OS, c++ means clang compiler)
c++ -I../lib/ann_1.1/include/ANN -I../lib/ann_1.1_char/include/ANN
-I../lib/imagelib -I../VocabLib -I../lib/zlib/include -L../lib -L../VocabLib -L../lib/zlib/lib -Wall -fopenmp -O3 -ffast-math -Wall -mfpmath=sse -msse2 -funroll-loops -march=core2 -c -o VocabLearn.o VocabLearn.cpp
g++ -o -I../lib/ann_1.1/include/ANN -I../lib/ann_1.1_char/include/ANN
-I../lib/imagelib -I../VocabLib -I../lib/zlib/include -L../lib -L../VocabLib -L../lib/zlib/lib -Wall -fopenmp -O3 -ffast-math -Wall -mfpmath=sse -msse2 -funroll-loops -march=core2 -o VocabLearn VocabLearn.o -lvocab -lANN -lANN_char -limage -lz
I just want to know how this makefile works. As you can see, since this makefile doesn't specify which source code to compile, how does the compiler know it is 'VocabLearn.cpp' that it should process? (My guess is that it will search source file according to the name of the object file, VocabLearn.o) Also this line seems a bit strange for me:
g++ -o $(CPPFLAGS) -o $(BIN) $(OBJS) $(LIBS)
Why is there a '-o' before '$(CPPFLAGS)'?
This makefile is using implicit rules to compile the source files. The rule:
$(BIN): $(OBJS)
asks for the object files in OBJS, and make already knows how to build VocabLearn.o if there is a file VocabLean.cpp.
Basically there is an implicit rule to convert *.cpp files to *.o files, however you have to have *.o as a dependency in one your targets. In the given Makefile, you have VocabLearn.o as a dependency for $(BIN). So, VocabLearn.o gets auto-generated from VocabLearn.cpp file.
sorry about my bad english...
Well, I'm now to linux, perl and c++, but I have to do some codes for the university and I'm getting some troubles while doing the makefile.
I have a code in perl which is running perfectly. As well, I have a code in C++ that calls perl as a subroutine. Everything is working properly, but when I do the makefile on my computer, it says:
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 main.o main.cpp
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 libSpam.a main.o
/usr/bin/ld: cannot find -lperl
collect2: error: ld returned 1 exit status
make: *** [main] Error 1
The problem is that when I run the makefile in my professor's computer, it's works...
Here is the code of 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 = libSpam.a 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
Does anyone know how to solve it?
You need to install the perl library for C. If you're on a Debian based system (including Ubuntu) sudo apt-get install libperl-dev or something similar may be sufficient, depending on which version of perl you're using.
Update: ok, this is a bit strange - I've installed perl-base, and it installed /usr/lib/libperl.so.5.14 but it did not make a /usr/lib/libperl.so symlink as you'd expect. I wonder why not? If I manually create the symlink with ln -s /usr/lib/libperl.so.5.14 /usr/lib/libperl.so it links correctly.
Update the second I had perl-base installed, but not libperl-dev which gave me /usr/lib/libperl.so.5.14 but not /usr/lib/libperl.so. I suspect (don't know for sure, but strongly suspect) that the correct answer isn't to manually make the symlink, but to install libperl-dev.
I am trying to compile the open-source AAM-library. I have tried in Visual Studio, and although it compiled, it had a run-time error. Now I'm trying to compile it in Ubuntu 11.04 using G++. The only makefile provided is a cygwin makefile. I am trying to use this to compile in Ubuntu. (I have included the makefile below). The problem I am having is near the bottom in the lines:
libaamlibrary.dll.a: $(OBJS)
g++ -fPIC -shared $(OBJS) $(LIBS) -o cygaamlibrary-2.dll -Wl,--enable-auto-image-base -Xlinker --out-implib -Xlinker libaamlibrary.dll.a
"--enable-auto-image-base" is not a recognised option. I am trying to rewrite these 3 lines to a form that does the same thing but works in Ubuntu, but I am struggling, because I don't really understand what the lines are doing (e.g., I don't understand Xlinker and how it should be used). Any advice would be much appreciated... Here is the full makefile for reference:
CPPFLAGS = -I. -I/home/andrew/MscProject/OpenCV-2.3.0/include/opencv -O2 -Wall -g -MD -fPIC
PROGRAMS = libaamlibrary.dll.a libaamlibrary.a fit build
LIBS = -L/usr/local/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann
OBJS = AAM_Util.o VJfacedetect.o AAM_Shape.o AAM_CAM.o AAM_PAW.o AAM_PDM.o AAM_TDM.o AAM_MovieAVI.o AAM_Basic.o AAM_IC.o
all: $(PROGRAMS)
AAM_Util.o: AAM_Util.cpp AAM_Util.h
g++ $(CPPFLAGS) -c -o AAM_Util.o AAM_Util.cpp
AAM_Shape.o: AAM_Shape.cpp AAM_Shape.h
g++ $(CPPFLAGS) -c -o AAM_Shape.o AAM_Shape.cpp
AAM_TDM.o: AAM_TDM.cpp AAM_TDM.h
g++ $(CPPFLAGS) -c -o AAM_TDM.o AAM_TDM.cpp
AAM_PDM.o: AAM_PDM.cpp AAM_PDM.h
g++ $(CPPFLAGS) -c -o AAM_PDM.o AAM_PDM.cpp
AAM_PAW.o: AAM_PAW.cpp AAM_PAW.h
g++ $(CPPFLAGS) -c -o AAM_PAW.o AAM_PAW.cpp
AAM_CAM.o: AAM_CAM.cpp AAM_CAM.h
g++ $(CPPFLAGS) -c -o AAM_CAM.o AAM_CAM.cpp
VJfacedetect.o: VJfacedetect.cpp VJfacedetect.h
g++ $(CPPFLAGS) -c -o VJfacedetect.o VJfacedetect.cpp
AAM_MovieAVI.o: AAM_MovieAVI.cpp AAM_MovieAVI.h
g++ $(CPPFLAGS) -c -o AAM_MovieAVI.o AAM_MovieAVI.cpp
AAM_Basic.o: AAM_Basic.cpp AAM_Basic.h
g++ $(CPPFLAGS) -c -o AAM_Basic.o AAM_Basic.cpp
AAM_IC.o: AAM_IC.cpp AAM_IC.h
g++ $(CPPFLAGS) -c -o AAM_IC.o AAM_IC.cpp
demo_build.o: train.cpp
g++ $(CPPFLAGS) -c -o demo_build.o train.cpp
demo_fit.o: fit.cpp
g++ $(CPPFLAGS) -c -o demo_fit.o fit.cpp
libaamlibrary.a: $(OBJS)
ar cru libaamlibrary.a $(OBJS)
ranlib libaamlibrary.a
libaamlibrary.dll.a: $(OBJS)
g++ -fPIC -shared $(OBJS) $(LIBS) -o cygaamlibrary-2.dll -Wl,--enable-auto-image-base -Xlinker --out-implib -Xlinker libaamlibrary.dll.a
fit: demo_fit.o
g++ -o fit demo_fit.o libaamlibrary.dll.a $(LIBS)
build: demo_build.o
g++ -o build demo_build.o libaamlibrary.dll.a $(LIBS)
clean:
rm -f *.o $(PROGRAMS)
I agree that you should not use a .dll.a or .dll extension (I believe .a and .so are appropriate), but it seems you can't do without libaamlibrary[.dll].a.
Since '--enable-auto-image-base' is prefixed with -Wl, this makes it a linker (ld) option.
I searched 'man ld' and came up with this:
--enable-auto-image-base
Automatically choose the image base for DLLs, unless one is
specified using the "--image-base" argument. By using a hash
generated from the dllname to create unique image bases for each
DLL, in-memory collisions and relocations which can delay program
execution are avoided. [This option is specific to the i386 PE
targeted port of the linker]
What is your platform? It is not available to non i386 architectures as I understand, and maybe not needed? So can you try compiling without it?
By the way I recommend using the excellent Autotools package (automake/autoconf/libtool).
Regarding --out-implib it is also not available on amd64.
--out-implib file
The linker will create the file file which will contain an import
lib corresponding to the DLL the linker is generating. This import
lib (which should be called ".dll.a" or ".a" may be used to link
clients against the generated DLL; this behaviour makes it possible
to skip a separate "dlltool" import library creation step. [This
option is specific to the i386 PE targeted port of the linker]
Sorry but I don't know what an import lib is.
Practical approach: first try building without all the .dll and .dll.a stuff; just remove the lines that refer to such targets.
It seems .dll.a files are static archives containing position-independent code (PIC), which are necessary in advanced linking scenarios, i.e. if you're developing shared libraries yourself. (Even if you want such a thing, you shouldn't call it .dll.a on Linux.)