Problem with makefile after rename variable - variables

after changing the name of a variable into a makefile, its behavior changed drastically. From unsuccessful compilation to successful one.
I tried everything - different names, adding various additional conditions, but all without success.
Version of make:
$make --version
GNU Make 3.82
Built for x86_64-redhat-linux-gnu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
This is a source code file
int main(int argc, char *argv[])
{
return 0;
}
Original(desired) behavior makefile:
SHELL = /bin/sh
.SUFFIXES:
.SUFFIXES: .c .o
CC := gcc
LD := gcc
CFLAGS := -g
STRICT_CFLAGS := -Wall -Wextra -Wpedantic -Werror
INCLUDE_CFLAGS :=
ALL_CFLAGS := $(INCLUDE_CFLAGS) $(STRICT_CFLAGS) $(CFLAGS)
STRICT_LDFLAGS := -Wall -Wextra -Wpedantic -Werror
INCLUDE_LDFLAGS :=
LDFLAGS := $(STRICT_LDFLAGS) $(INCLUDE_LDFLAGS) $(CFLAGS)
SOURCES := $(wildcard *.c)
BINARIES := $(SOURCES:%.c=%)
.PHONY: all
all: $(BINARIES)
%: %.o
#echo "Checking..."
$(LD) $(LDFLAGS) -o $#
.c.o:
#echo "Creating object..."
$(CC) $(ALL_CFLAGS) -c $< -o $#
.PHONY: clean
clean:
#echo "Cleaning up..."
-rm -rvf *.o $(BINARIES)
Compile output:
$make
gcc -g -Wall -Wextra -Wpedantic -Werror -g test.c -o test
test.c: In function ‘main’:
test.c:1:14: error: unused parameter ‘argc’ [-Werror=unused-parameter]
} return 0;nt argc, char *argv[])
^
test.c:1:26: error: unused parameter ‘argv’ [-Werror=unused-parameter]
} return 0;nt argc, char *argv[])
^
cc1: all warnings being treated as errors
make: *** [test] Error 1
Makefile after renaming variable (LDFLAGS -> T_LDFLAGS) - wrong behavior:
SHELL = /bin/sh
.SUFFIXES:
.SUFFIXES: .c .o
CC := gcc
LD := gcc
CFLAGS := -g
STRICT_CFLAGS := -Wall -Wextra -Wpedantic -Werror
INCLUDE_CFLAGS :=
ALL_CFLAGS := $(INCLUDE_CFLAGS) $(STRICT_CFLAGS) $(CFLAGS)
STRICT_LDFLAGS := -Wall -Wextra -Wpedantic -Werror
INCLUDE_LDFLAGS :=
T_LDFLAGS := $(STRICT_LDFLAGS) $(INCLUDE_LDFLAGS) $(CFLAGS)
SOURCES := $(wildcard *.c)
BINARIES := $(SOURCES:%.c=%)
.PHONY: all
all: $(BINARIES)
%: %.o
#echo "Checking..."
$(LD) $(T_LDFLAGS) -o $#
.c.o:
#echo "Creating object..."
$(CC) $(ALL_CFLAGS) -c $< -o $#
.PHONY: clean
clean:
#echo "Cleaning up..."
-rm -rvf *.o $(BINARIES)
Compile output:
$make
gcc -g test.c -o test
Please someone explain to me why, after the name change, we lose flags for a strict code.
Thanks for your time!

Neither of your make targets are being hit. If you look at the output, you'll notice that Checking... is not printed and Creating object... is not printed. So your program is being build with the default target. This default target automatically adds $(CFLAGS) and $(LDFLAGS) to the build line. That's why things stopped working when you renamed LDFLAGS.
Also, your makefile currently is trying to create an executable for each individual .c file.
You need to change your targets as follows:
SOURCES := $(wildcard *.c)
OBJECTS := $(SOURCES:%.c=%.o)
BINARY := myprog
.PHONY: all
all: $(BINARY)
$(BINARY): $(OBJECTS)
#echo "Checking..."
$(LD) $(T_LDFLAGS) $(OBJECTS) -o $#
%.o: %.c
#echo "Creating object..."
$(CC) $(ALL_CFLAGS) -c $< -o $#
The OBJECTS variable will contain a list of .o files that correspond to each .c file. This will be the dependency list for the binary and the list of objects to link. The target for object files says to create a .o file for each .c file.

Related

How to create a makefile for a Fortran program using modules

The challenge is to create a makefile which takes a list of modules and does not require me to sort out precendence. For example, the modules are
mod allocations.f08 mod precision definitions.f08 mod unit values.f08
mod blocks.f08 mod shared.f08 mod parameters.f08
mod timers.f08
The main program is characterize.f08. The error message is
Fatal Error: Can't open module file ‘mprecisiondefinitions.mod’ for reading at (1): No such file or directory
The first statement in the main program is use mPrecisionDefinitions, the module defined in mod precision definitions.f08.
The following makefile, based upon Creating a FORTRAN makefile, is:
# compiler
FC := /usr/local/bin/gfortran
# compile flags
FCFLAGS = -g -c -Wall -Wextra -Wconversion -Og -pedantic -fcheck=bounds -fmax-errors=5
# link flags
FLFLAGS =
# source files and objects
SRCS = $(patsubst %.f08, %.o, $(wildcard *.f08))
# program name
PROGRAM = a.out
all: $(PROGRAM)
$(PROGRAM): $(SRCS)
$(FC) $(FLFLAGS) -o $# $^
%.mod: %.f08
$(FC) $(FCFLAGS) -o $# $<
%.o: %.f08
$(FC) $(FCFLAGS) -o $# $<
clean:
rm -f *.o *.mod
For starters, I recommend to replace all spaces in your file names with underscores or something similar.
Spaces are almost universally used as separators, and any program that is started with something like
gfortran -c -o mod precision definitions.o mod precision definitions.f08
would interpret this line as 'create an object file called mod from the source files precision, definitions.o, mod, precision, and definitions.f08. And while there are ways to do it, with increasing automation, you have to jump more and more hoops.
In contrast, this works well:
gfortran -c -o mod_precision_definitions.o mod_precision_definitions.f08
I would use this command to change all the spaces into underscores:
rename 's/ /_/g' *.f08
If that doesn't work, use this command:
for f in *.f08; do mv "$f" ${f// /_}; done
Next, I wouldn't worry about .mod files. They get generated together with the object files when you compile a module. So while technically some routine that uses a module requires the .mod file for that module, you might as well claim in your Makefile that it depends on the object file itself.
So with that said, here's the Makefile I would use (with some assumed inter-module dependencies added):
# Find all source files, create a list of corresponding object files
SRCS=$(wildcard *.f08)
OBJS=$(patsubst %.f08,%.o,$(SRCS))
# Ditto for mods (They will be in both lists)
MODS=$(wildcard mod*.f08)
MOD_OBJS=$(patsubst %.f08,%.o,$(MODS))
# Compiler/Linker settings
FC = gfortran
FLFLAGS = -g
FCFLAGS = -g -c -Wall -Wextra -Wconversion -Og -pedantic -fcheck=bounds -fmax-errors=5
PROGRAM = characterize
PRG_OBJ = $(PROGRAM).o
# make without parameters will make first target found.
default : $(PROGRAM)
# Compiler steps for all objects
$(OBJS) : %.o : %.f08
$(FC) $(FCFLAGS) -o $# $<
# Linker
$(PROGRAM) : $(OBJS)
$(FC) $(FLFLAGS) -o $# $^
# If something doesn't work right, have a 'make debug' to
# show what each variable contains.
debug:
#echo "SRCS = $(SRCS)"
#echo "OBJS = $(OBJS)"
#echo "MODS = $(MODS)"
#echo "MOD_OBJS = $(MOD_OBJS)"
#echo "PROGRAM = $(PROGRAM)"
#echo "PRG_OBJ = $(PRG_OBJ)"
clean:
rm -rf $(OBJS) $(PROGRAM) $(patsubst %.o,%.mod,$(MOD_OBJS))
.PHONY: debug default clean
# Dependencies
# Main program depends on all modules
$(PRG_OBJ) : $(MOD_OBJS)
# Blocks and allocations depends on shared
mod_blocks.o mod_allocations.o : mod_shared.o

Why am I getting "nvcc fatal : redefinition of argument 'optimize'"?

I am trying to compile on MacBook Pro Retina with CUDA Driver Version: 7.0.36 and cuda toolkit 7.0 in a nVidia GT 750 M, the following code with its makefile but it gives me this error:
nvcc fatal : redefinition of argument 'optimize'.
Despite I have been able to compile and execute other programes with nvcc, with makefiles and so, now I am not.
Also, I have not been able to find something useful about this error so I ask it here if someone knows how to solve it. I am new with CUDA so if you need more information please ask for it.
Here is my Makefile.inc:
CXX := nvcc
OPTIM := -O3
DEBUG := -g -DOLB_DEBUG
CXXFLAGS := $(OPTIM)
ARPRG := ar
LDFLAGS := -O3
PARALLEL_MODE := OFF
OMPFLAGS := -fopenmp
BUILDTYPE := precompiled
INPUTDIR := ./input
OUTPUTDIR := ./output
INCDIR := ./inc
OBJDIR := ./obj
SRCDIR := ./HeatTransfer
BINDIR := ./bin
###########################################################################
## defines shell
SHELL := /bin/sh
and the Makefile:
###########################################################################
ROOT := .
include $(ROOT)/Makefile.inc
######################################################## Operational system
OS = $(shell uname -s)
MACH = $(shell uname -m)
HOST = $(shell uname -n)
WHOAMI = $(shell whoami )
###########################################################################
HeatTransfer := \
mesh\
stack
PROGRAM := $(BINDIR)/program
###########################################################################
OBJECTS := $(foreach file, $(HeatTransfer), $(OBJDIR)/$(file).o)
###########################################################################
all : compile link
###########################################################################
compile : $(OBJECTS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cu
#echo Compile $<
$(CXX) $(CXXFLAGS) -I$(INCDIR) -c $< -o $#
###########################################################################
link: $(PROGRAM)
$(PROGRAM): $(OBJECTS)
#echo Link $#
$(CXX) $(LDFLAGS) -I$(INCDIR) $(foreach file, $(HeatTransfer), $(OBJDIR)/$(file).o) $(LDFLAGS) -I$(INCDIR) -o $#
###########################################################################
clean : cleanprog cleanobj
cleanprog:
#echo Clean rubbish files
#rm -f *~ core .tmpfile $(PROGRAM)
cleanobj:
#echo Clean object files
#rm -f $(OBJECTS)
###########################################################################
###########################################################################
The complete messege when I try to compile is this:
...Heat_Transfer_CUDA$ make
Compile HeatTransfer/mesh.cu
nvcc -O3 -I./inc -c HeatTransfer/mesh.cu -o obj/mesh.o
Compile HeatTransfer/stack.cu
nvcc -O3 -I./inc -c HeatTransfer/stack.cu -o obj/stack.o
Link bin/program
nvcc -O3 -I./inc ./obj/mesh.o ./obj/stack.o -O3 -I./inc -o bin/program
nvcc fatal : redefinition of argument 'optimize'
make: *** [bin/program] Error 1
The problem is arising due to the fact that your link command is specifying the -O3 switch twice:
nvcc -O3 -I./inc ./obj/mesh.o ./obj/stack.o -O3 -I./inc -o bin/program
^^^ ^^^
And this is not allowed - it will produce that error.
The problem seems to occur due to the fact that your makefile specifies the use of LDFLAGS twice here:
$(CXX) $(LDFLAGS) -I$(INCDIR) $(foreach file, $(HeatTransfer), $(OBJDIR)/$(file).o) $(LDFLAGS) -I$(INCDIR) -o $#
which should not be necessary. Something like this instead:
$(CXX) $(LDFLAGS) -I$(INCDIR) $(foreach file, $(HeatTransfer), $(OBJDIR)/$(file).o) -o $#
should probably fix the issue.

Makefile rule using the automatic variable $^ without dependencies

I learnt from the GNU Make manual that the sign $^ is an automatic variable which represents the names of all the prerequisites. However I fell upon a makefile like this one:
SVR_OBJECT_FILES = server.o\
server_func.o
CLT_OBJECT_FILES = client.o
CFLAGS = -Wall -Werror -W
CC = gcc
all: client/client server/serveur
client/client: $(CLT_OBJECT_FILES)
server/serveur: $(SVR_OBJECT_FILES)
client/client server/serveur:
#mkdir -p $(dir $#)
$(CC) $(CFLAGS) $^ -o $#
%.o: %.c
$(CC) -c $<
clean:
rm -f client/client server/serveur *.o
Which works fine so my question is :
How can the command below can link the right object files while the $^ variable is refering no preprerequisites at all. (the rule has no prerequisites)
$(CC) $(CFLAGS) $^ -o $#
$^ contains all the prerequisites of the target, not just the ones that are mentioned with the rule itself. The same file can appear as a target several times in rules with no commands:
sometarget: dependency1
…
sometarget: dependency2
assemble -o $# $^
…
sometarget: dependency3
The dependencies of sometarget are dependency1, dependency2 and dependency3, and when the assemble command is invoked by make sometarget, it will receive all three as arguments.
Here, $^ will contain all $(CLT_OBJECT_FILES) or $(SRV_OBJECT_FILES) depending on which target the command is executed for.

gcc Makefile: Variable Substitution error with %

My make file has worked, up until I tried some variable substitution. %.o is not recognized.
I get make: * No rule to make target `%.o', needed by `parser'. Stop.
CC=gcc
CFLAGS=-ansi -pedantic -Wall -ggdb3
PROJECT=project.c project.h
PARSER=parser.c parser.h
OBJ=project.o parser.o
#CFILE=project.c parser.c
#1 no problem
#parser: project.o parser.o
# $(CC) $(CFLAGS) -o $# $^
#2 no problem
#parser: $(OBJ)
# $(CC) $(CFLAGS) -o $# $^
#3 this fails
parser: %.o
$(CC) $(CFLAGS) -o $# $^
#parser: project.o parser.o
# gcc -ansi -pedantic -Wall -ggdb -o parser project.o parser.o
project.o: $(PROJECT)
$(CC) $(CFLAGS) -c $^
parser.o: $(PARSER)
$(CC) $(CFLAGS) -c $^
clean:
rm -f $(OBJ) parser
You're not creating a pattern rule, since there is no % in the target name. As a result the % has no special meaning in the list of dependencies. It's seen as a literal part of a file name; you can't use it as a regular wildcard.

Prepending a path on make

In my makefile I have an object variable. I need to prepend obj/ to every .o file. How would I do this?
CC=g++
CFLAGS=-C -Wall
LDFLAGS=-lsqlite3 -lpthread -ldl
SOURCES=main.cpp Database.cpp actionInit.cpp TileSet.cpp Player.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=mahjong-counter
all: bin $(OBJECTS) $(EXECUTABLE)
bin:
mkdir -p bin
%.o: %.cpp
$(CC) $(LDFLAGS) $< -c -o $#
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $(EXECUTABLE)
clean:
rm $(OBJECTS)
You want CXX, not CC. CC is for C compiler, not the C++ compiler
In any case, I believe the following should work:
CXX=g++
CXXFLAGS=-C -Wall
LDFLAGS=-lsqlite3 -lpthread -ldl
OBJ_DIR = obj
BIN_DIR = bin
EXECUTABLE=mahjong-counter
SOURCES= main.cpp Database.cpp actionInit.cpp TileSet.cpp Player.cpp
OBJECTS= $(SOURCES:%.cpp=$(OBJ_DIR)/%.o)
all: dirs $(OBJECTS) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $(EXECUTABLE)
$(OBJ_DIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $#
dirs:
mkdir -p $(BIN_DIR)
mkdir -p $(OBJ_DIR)
.PHONY: dirs all
You could use more expressive version of substitution you employed when assigning OBJECTS
OBJECTS=$(SOURCES:%.cpp=obj/%.o)
or use a standard text transformation function
OBJECTS=$(addprefix obj/,$(SOURCES:.cpp=.o))