make : source and binary same name - makefile

I have many file with extension .cpp
f001.cpp
abc.cpp
...
I try compile any file with this
%.cpp:
g++ -o $* $*.cpp
but I get
make: *** No hay objetivos. Alto.

Does this work?
f001.o:
%.o: %.cpp
g++ -o $# $<
EDIT:
Good! Now try this:
OBJETIVOS = f001.o abc.o def.o ghi.o
todos: $(OBJETIVOS)
%.o: %.cpp
g++ -o $# $<
There is one problem here. Usually abc is the executable binary file, and abc.o is the object file. You are building executable files, but calling them abc.o. If you want them to be executable files, it would be better to call them abc.

with the answer of #Beta, I solved with
files = $(basename $(shell ls *cpp))
all: $(files)
%: %.cpp
g++ -o $# $<
clean:
rm $(files)
https://gist.github.com/3726212

Related

BSD make & GNU make

I have Makefile. This runs on FreeBSD with gmake and make. In BSD Make command not output log same with gmake.
$ gmake
compile main.cpp
linking myout
$ make
c++ -O2 -pipe -c main.cpp -o main.o
linking myout
$ cat Makefile
TARGET = myout
default: $(TARGET)
SRCS = main.cpp
OBJS = $(SRCS:%.cpp=%.o)
default: $(BIN)
%.o: %.cpp
#echo compile $<
#$(CXX) -c $< -o $#
$(TARGET): $(OBJS)
#echo linking $#
#$(CXX) $(OBJS) -o $#
clean:
#rm -f $(OBJS) $(TARGET)
According to the FreeBSD make documentation, it doesn't support pattern rules. So your rule here:
%.o: %.cpp
#echo compile $<
#$(CXX) -c $< -o $#
in FreeBSD make is just an explicit rule telling make how to build the literal file %.o from the literal file %.cpp. Since you don't try to build a file named %.o (you're trying to build main.o), this rule is ignored / never used.
It looks like if you want something that will work the same way between both versions of make you'll have to restrict yourself to the POSIX standard suffix rules format, like this:
.SUFFIXES: .cpp .o
.cpp.o:
#echo compile $<
#$(CXX) -c $< -o $#
The default build utilities are different. FreeBSD uses a different implementation of make than GNU/Linux. The respective man pages outline differences.
https://forums.freebsd.org/threads/difference-gmake-gnu-and-freebsd-make.28784/

Makefile with different source types doesn't notice make.depend

I want my Makefile to accept different source file types. It does, but it does not recompile when I alter an include file. Here's the Makefile:
C_SOURCES := $(wildcard *.c)
CPP_SOURCES := $(wildcard *.cpp)
CC_SOURCES := $(wildcard *.cc)
ALL_SOURCES := $(notdir $(C_SOURCES) $(CPP_SOURCES) $(CC_SOURCES))
C_OBJECTS := ${C_SOURCES:.c=.o}
CPP_OBJECTS := ${CPP_SOURCES:.cpp=.o}
CC_OBJECTS := ${CC_SOURCES:.cc=.o}
ALL_OBJECTS := $(notdir $(C_OBJECTS) $(CPP_OBJECTS) $(CC_OBJECTS))
#############################################################
all: a.out
a.out: $(ALL_OBJECTS)
g++ -o $# -g $^
%.o: %.cpp
g++ -c $# -g $^
%.o: %.cc
g++ -c $# -g $^
%.o: %.c
g++ -c $# -g $^
clean:
rm -f a.out
rm -f *.o
make.depend: $(ALL_SOURCES)
g++ -MM $^ > $#
-include make.depend
The lines starting with *.o: are a recent addition -- I wondered if it might help. No effect.
make.depend is doing its job: I checked it out, and its dependencies are correct. (For my MCVE I have one source file main.cpp which includes date.h.)
main.o: main.cpp date.h
The output of $(info $(ALL_OBJECTS)) is main.o.
So: how can I get it to recognize changes to includes?
It would be helpful, when asking questions, to show an example of running the commands and what is printed. Given the makefile you provide I'd be surprised of make actually ran any commands at all, other than generating the depend file.
That's because this:
C_OBJECTS := ${C_SOURCES: .c =.o}
is invalid syntax. Or more precisely, it doesn't do what you want to do. It replaces the literal string _____.c__ (where the _ are whitespace... SO won't let me just use spaces) at the end of each word in C_SOURCES with .o. Of course you don't have any of those, so basically your ALL_OBJECTS variable contains just your source files (since no changes are made by the substitution).
You can use:
$(info $(ALL_OBJECTS))
to see what happens here.
This needs to be written:
C_OBJECTS := ${C_SOURCES:.c=.o}
CPP_OBJECTS := ${CPP_SOURCES:.cpp=.o}
CC_OBJECTS := ${CC_SOURCES:.cc=.o}
Whitespace in makefiles is very tricky. You definitely have to be careful where you put it and you can't add it anywhere you like.
Also I have no idea why you're using notdir since all your files are in the current directory.
And technically it's incorrect to compile .c files with the g++ compiler front-end.
ETA also your pattern rules are incorrect: you're missing the -o option to the compiler; they should all be the equivalent of:
%.o: %.c
g++ -c -o $# -g $^
Better is to use the standard make variables, then you can customize the behavior without rewriting all the rules:
CFLAGS = -g
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $# $<
Update Just use the comprehensively enginerred automatic dependency file generation #MadScientist describes at http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/. This works with both GCC and clang (due to clang's explicit goal to be commandline compatible to GCC).
For completeness' sake, my original answer:
The generated dependency rules must depend on the sources determined by the dependeny rule generating rule. This requires the -MT parameter to gcc.
I have included this as an example in a slightly cleaned up version of your GNUmakefile:
#############################################################
ALL_CFLAGS = -g
ALL_CXXFLAGS = -g
#############################################################
.PHONY: all
all: all-local
#############################################################
bin_PROGRAMS += test-cxx
test_cxx_OBJECTS += main.o
test_cxx_OBJECTS += main-c.o
test-cxx: $(test_cxx_OBJECTS)
$(LINK.cc) $(ALL_CXXFLAGS) -o $# $^
ALL_OBJECTS += $(test_cxx_OBJECTS)
#############################################################
%.o: %.cpp
$(COMPILE.cpp) $(ALL_CXXFLAGS) -o $# -c $<
%.o: %.cc
$(COMPILE.cc) $(ALL_CXXFLAGS) -o $# -c $<
%.o: %.c
$(COMPILE.c) $(ALL_CFLAGS) -o $# -c $<
#############################################################
%.dep: %.cpp
$(COMPILE.cpp) -MM -MT "$*.o $# " $< > $#.tmp
mv -f $#.tmp $#
%.dep: %.cc
$(COMPILE.cc) -MM -MT "$*.o $# " $< > $#.tmp
mv -f $#.tmp $#
%.dep: %.c
$(COMPILE.c) -MM -MT "$*.o $# " $< > $#.tmp
mv -f $#.tmp $#
ALL_DEPS = $(ALL_OBJECTS:.o=.dep)
-include $(ALL_DEPS)
#############################################################
.PHONY: all-local
all-local: $(bin_PROGRAMS)
.PHONY: clean
clean:
rm -f $(bin_PROGRAMS)
rm -f *.dep
rm -f *.o
#############################################################
The *.dep generating rules will recursively examine all included source files, and list them all in the generated *.dep file.
Using a separate *.dep file for each object file means that if you change only one source file, only the *.dep files needing regeneration will actually be regenerated.
The *.dep generating rule creates a *.dep.tmp file first, and only moves that to *.dep if generating the *.dep.tmp file has been successful. So if for some reason generating the *.dep.tmp file fails (e.g. you might be including a non-existing header file), you will not have a newly generated (and thus considered up to date) empty *.dep file being included by make.

Quiet makefile not working

So I've a recursive makefile that's on a project, but for some reason, AR is the only command that still prints output.
How can I force it to be quiet? It has already '#' at the beginning, and I don't want to pipe the output to null.
How i'm calling this makefile?
#cd libc; make clean --no-print-directory
Here's the troublemaker makefile:
include ../Makefile.inc
LIB=../libc.a
SOURCES=$(wildcard *.c)
SOURCES_ASM=$(wildcard asm/*.asm)
OBJECTS=$(SOURCES:.c=.o)
OBJECTS_ASM=$(SOURCES_ASM:.asm=.o)
all: $(LIB)
#echo -e " libC [ \033[0;32mOK \033[0m]"
$(LIB): $(OBJECTS) $(OBJECTS_ASM)
#$(AR) $(ARFLAGS) -c $(LIB) $(OBJECTS_ASM) $(OBJECTS)
$(OBJECTS): $(SOURCES)
$(OBJECTS_ASM): $(SOURCES_ASM)
%.o: %.c
#$(GCC) $(GCCFLAGS) -c $< -o $#
%.o: %.asm
#$(ASM) $(ASMFLAGS) $< -o $#
clean:
#rm -rf *.o ../*.a
.PHONY:
all clean
and here's the output:
a - asm/syscall.o
a - syscall.o
a - string.o
a - stdio.o
a - integer.o
libC [ OK ]
Thanks in advance
If you don't want ar to print output then stop telling it to do so! :)
Since you haven't shown any setting for ARFLAGS I assume you're using the default value, which in GNU make is rv and the v flag means "verbose" (see man ar).
So, just setting:
ARFLAGS = r
in your makefile should turn off the verbose output from ar.
I suggest you to simply redirect the stdout to a log file for AR command only, as follows:
#$(AR) $(ARFLAGS) -c $(LIB) $(OBJECTS_ASM) $(OBJECTS) >> $(LOG_FILE)
It keeps the errors displayed because it does not redirect stderr.

Makefile: source files in a particular directory

What do I need to do if I want to compile several files (e.g. a.f90, b.f90, c.f90) in a given directory (say, MYDIR)?
My Makefile code is something like:
CC=gfortran
CFLAG=-g
HOME=MYDIR
SRC=$(HOME)/(a.f90,b.f90,c.f90)
OBJ=$(SRC:,=.o)
EXE=test.x
%.o: %.f90
$(CC) $(CFLAG) -c -o $# $<
$(EXE): $(OBJ)
$(CC) -o $# $^ $(CFLAG)
clean:
rm -f *.o
I think, the 4-th line is not correct. So what could be the replacement?
Another thought: Can I use a wildcard if I want to compile all .f90 file inside MYDIR?
There are lots of ways to do it. You can do something like:
SRC = $(addprefix $(HOME)/,a.f90 b.f90 c.f90)
Also your assignment of OBJ is wrong; there's no comma needed after the colon.
Yes you can use wildcard if you want.

Automatic generate target From Source List Make File

I have this directory structure.
app/
src
include
lib/
src
maincode/
main.cc
Makefile
I want to generate automatic target from the source list in makefile. So I don't have to write rule for each file.
Example
source=\
../src/a.cpp
../src/ab.cpp
../lib/src/b.cpp
I want to write rule like
%.o:%.cpp
so that I don't have to repeat rule for each file.
How I can achieve this ?
Edit: the find command should be inside a shell variable
If you are using Linux, I think you can use:
SOURCES=$(shell find . -name *.cpp)
OBJECTS=$(SOURCES:%.cpp=%.o)
%.o: %.cpp
<command to compile>
I like Sagar's answer, though it took me a bit to figure out I what I wanted for an additional rule to cause creation of the objects:
SOURCES=$(shell find . -name *.cpp)
OBJECTS=$(SOURCES:%.cpp=%.o)
all: $(OBJECTS)
%.o: %.cpp
<command to compile dependencies $< into target $# > $< -o $#
CPP = g++
CPPFLAGS = -Wall -pedantic -O2 -g -c
SOURCES := ${wildcard *.cpp}
OBJECTS := ${SOURCES:.cpp=.o}
.PHONY: all clean
.SUFFIXES: .cpp .o
all: main
main: $(OBJECTS)
.cpp.o:
$(CPP) $(CPPFLAGS) $< -o $#
clean:
-rm -fv *.o
For more info see the man

Resources