I want my Makefile to be as simple as possible and still function. This is what it looks like.
load: load.cpp
g++ load.cpp -g -o load
list: list.cpp
g++ list.cpp -g -o list
It worked fine when there was only one entry. But when I added the second entry, it doesn't check to see if it's updated and needs to be recompiled, unless I specifically supply the name. How do I fix this?
Make only makes the first target automatically. So add a new first target that depends on both the others.
all: load list
load: load.cpp
g++ load.cpp -g -o load
list: list.cpp
g++ list.cpp -g -o list
Dave Hinton has shown how to get the Makefile to work. Here's how to make it simpler:
all: load list
%: %.cpp
g++ $< -g -o $#
Related
I am kinda rookie in makefile field but trying to write makefile that would go in two modes: normal mode make outputing executable file called say bingo depending on some files and a mode make debug outputing executable file called bingo.debug that shall be compiled with debug option. I'm trying to use target variable with the following result:
PROGRAM = bingo
SUFIX = .debug
CC = gcc
CFLAGS = -Wall -O2
DEBUG = -g -D DEBUG
all: $(PROGRAM)
debug: CFLAGS += $(DEBUG)
debug: PROGRAM += $(SUFIX)
debug: all
file1.o: file1.c file1.h
$(CC) -c $(CFLAGS) -o $# $<
file2.o: file2.c file2.h
$(CC) -c $(CFLAGS) -o $# $<
$(PROGRAM).o: $(PROGRAM).c
$(CC) -c $(CFLAGS) -o $# $<
$(PROGRAM): file1.o file2.o ($PROGRAM).o
$(CC) -o $# $^
.PHONY: all clean
clean:
rm -rf $(PROGRAM) *.o
It looks like make debug correctly compiles the file with debug flags but it does not change the file name (i.e. both modes outputs the same bingo file). Any help much appriciated!
You cannot use target-specific variables in targets. The documentation is very clear that they are available only in recipes.
In general it's problematic to do things this way, because make has no idea which objects were built with debug and which weren't. If you forget to do a complete clean and/or run make the wrong way then you'll get a mix of different object files: some compiled with debug and some not.
Instead, you should put your debug object files in a different directory from your non-debug object files so you don't have to worry about that.
I have the redis server installed, and can use it from the command line. Now, I am wanting to write a client program using hiredis. To begin with, I tried to compile example.c which is present in the hiredis directory:
vishal#expmach:~/redis-2.6.14/deps/hiredis$ ls
adapters async.h COPYING dict.h *example.c* example-libevent.c
hiredis.c Makefile net.h sds.c test.c async.c CHANGELOG.md dict.c example-
ae.c example-libev.c fmacros.h hiredis.h net.c README.md sds.h
Here are the commands:
vishal#expmach:~/redis-2.6.14/deps/hiredis$ gcc -c -I hiredis example.c
vishal#expmach:~/redis-2.6.14/deps/hiredis$ gcc -o example -I hiredis -L hiredis -lhiredis -lm
/usr/bin/ld: cannot find -lhiredis
collect2: ld returned 1 exit status
I am not sure how to go about fixing this. Please help.
gcc -o example example.c -lhiredis $(pkg-config --cflags --libs glib-2.0)
why don't you juste juste the provided Makefile?
make
./hiredis-example
I'm having a hard time finding good documentation on the most common g++ options. I have the following g++ command and I'm trying to understand it well:
g++ q1.cpp -o q1 -I/usr/local/include/opencv -L/usr/local/lib -lm -lopencv_core -lopencv_highgui -lopencv_calib3d -lopencv_imgproc
What does the -I option do?
-I adds to the path for searching for include files.
-l links to a particular library. (e.g. -lm links libm which is math)
It's not for a library I think it's only for include files. (It's a i not a l, l it's for libraries)
I am asked to write a Makefile which needs to selects between two compilers, and each of these compilers should support 3 build versions (debug, release, test).
There are a lot of variables that change based on input (compiler, compiler options, output directory, include directories etc). My first option was to go through target-specific variables and configure variables according to target. Do you think this is good idea?
I am not extremely familiar with those kind of variables. It seems to me that if I do something like this:
release: variable1=value1 #release is target
release: variable2=value2
release:
# some compilation rule
Only the variable1 will be configured. Am I right about this?
Update
Thank you for your reply. I am trying to deal with compiler selection issue through additional variable which would be configured according to target. But, here is the problem. I have the following lines:
release: CFLAGS = -DCORE_SW_VERSION='"$(CORE_SW_VERSION)"' -Wall
release: CFLAGS += -fgnu89-inline -mno-volatile-cache $(INCLUDE)
release: TARGET=release
After this lines, I do some ifeq sequence in which I decide which compiler to use (according to TARGET variable value).
And CFLAGS is configured properly, but the TARGET variable is empty. This leads me to conclusion that you can configure only one target-specific variable. Am I right? If not, I am not aware what I am doing wrong. Could you please help me?
Target-specific variables are defined only when building that target and any prerequisites of that target. You can't use target-specific variables arbitrarily throughout the makefile (as it sounds like you're trying to do with ifeq). For that, you may want to look at $(MAKECMDGOALS). I don't believe there is any limit on the number of target-specific variables, certainly not a limit of one.
Needing either target-specific variables or $(MAKECMDGOALS) may be a warning that you're trying to do coerce make into doing something it wasn't meant to do.
It's not clear to me whether you want to build three versions (debug/test/release with a single compiler for each one), or six versions. Assuming three, here is a unix-y Makefile to build with different compilers and CFLAGS depending on the target. However, note that this could just as easily be coded with RELEASE_CFLAGS, RELEASE_CC, DEBUG_CFLAGS, etc... variables.
all: release debug test
release: CC=gcc
release: CFLAGS=
debug: CC=gcc
debug: CFLAGS=-g
test: CC=cc
test: CFLAGS=-Wall
.PHONY: release debug test
release: release/exe
debug: debug/exe
test: test/exe
OBJECTS := test.o
release/%.o: %.c
$(CC) $(CLFAGS) -c -o $# $<
debug/%.o: %.c
$(CC) $(CLFAGS) -c -o $# $<
test/%.o: %.c
$(CC) $(CLFAGS) -c -o $# $<
release/exe: $(OBJECTS:%=release/%)
$(CC) $(CFLAGS) -o $# $^
debug/exe: $(OBJECTS:%=debug/%)
$(CC) $(CFLAGS) -o $# $^
test/exe: $(OBJECTS:%=test/%)
$(CC) $(CFLAGS) -o $# $^
My problem is that ocamlc and ocamlopt apear to be refusing to find third party libraries installed through apt-get. I first started having this problem when I tried to incorporate third-party modules into my own OCaml programs, and quickly wrote it off as a personal failing in understanding OCaml compilation. Soon-- however-- I found myself running into the same problem when trying to compile other peoples projects under their own instructions.
Here is the most straight-forward example. The others all use ocamlbuild, which obfuscates things a little bit.
The program: http://groups.google.com/group/fa.caml/msg/5aee553df34548e2
The compilation:
$ocamlc -g -dtypes -pp camlp4oof -I +camlp4 dynlink.cma camlp4lib.cma -cc g++ llvm.cma llvm_bitwriter.cma minml.ml -o minml
File "minml.ml", line 43, characters 0-9:
Error:Unbound module Llvm
Even when I provide ocamlc with the obsolute paths to the llvm files, like so...
$ ocamlc -g -dtypes -pp camlp4oof -I +camlp4 dynlink.cma camlp4lib.cma -cc g++ /usr/lib/ocaml/llvm-2.7/llvm.cma /usr/lib/ocaml/llvm-2.7/llvm_bitwriter.cma minml.ml -o minml
... to no avail.
What am I doing wrong?
Your command is doing two things: it's compiling minml.ml (into minml.cmo), then linking the resulting object into minml.
Compiling a module requires the interfaces of the dependencies. The interfaces contain typing information that is necessary to both the type checker and the code generator; this information is not repeated in the implementation (.cma here). So for the compilation stage, llvm.cmi must be available. The compiler looks for it in the include path, so you need an additional -I +llvm-2.7 (which is short for -I /usr/lib/ocaml/llvm-2.7).
The linking stage requires llvm.cma, which contains the bytecode implementation of the module. Here, you can either use -I or give a full path to let ocamlc know where to find the file.
ocamlc -g -dtypes -I +camlp4 -I +llvm-2.7 -pp camlp4oof -c minml.ml
ocamlc -g -cc g++ -I +camlp4 -I +llvm-2.7 dynlink.cma camlp4lib.cma llvm.cma llvm_bitwriter.cma minml.cmo -o minml
or if you want to do both stages in a single command:
ocamlc -g -dtypes -cc g++ -I +camlp4 -I +llvm-2.7 dynlink.cma camlp4lib.cma llvm.cma llvm_bitwriter.cma -pp camlp4oof minml.ml -o minml