Makefile for Fortran gives this error: make: don't know how to make datastructures.o - makefile

I am trying to prepare my first makefile for Fortran:
My code is so far separated in three object modules.
This is my makefile:
# Variables
OBJS=datastructures.o global.o main.o
FC=/usr/local/bin/gfortran8
FFLAGS=-Wl,-rpath=/usr/local/lib/gcc8
# Makefile
test1: $(OBJS)
$(FC) -o mktpro_a $(FFLAGS) $(OBJS)
%.o: %.f90
$(FC) -c $(FFLAGS) $<
clean:
rm $(OBJS)
rm test1
But I get the following error:
$ make test1
make: don't know how to make datastructures.o. Stop
make: stopped in /usr/home/user/marketprofile
I am using FreeBSD12 and gcc8 (gfortran8)

Instead of
%.o: %.f90
$(FC) -c $(FFLAGS) $<
change it to
.f90.o:
$(FC) -c $(FFLAGS) $<
You might need an explicit output too (I am not familiar with this compiler):
.f90.o:
$(FC) -c $(FFLAGS) -o $# $<

In case it helps other people, this seems the way to implement this in FreeBSD 12 make (which seems to be PMake).
.SUFFIXES : .o .f90
.f90.o :
$(FC) $(FFLAGS) -c $(.IMPSRC)
More info here: ftp.netbsd.org/pub/NetBSD/misc/lite2-docs/psd/12.make.ps.gz

Related

How to use a makefile with gprof to recompile dependencies?

I have a makefile which compiles and links together objects to create an executable. In order to profile, I need to use an additional flag -pg before compiling. Here is my current makefile:
# objects required
OBJS = obj1.o obj2.o
# flags
FC = gfortran
FLAGS = -O3
PROFILEFLAG = -pg
# executable
EXE = program.exe
PROFEXE = program_prof.exe
# suffixes
.SUFFIXES: .o .f90
# rules
%.o: %.f90
$(FC) $(FLAGS) -c $<
default: $(OBJS)
$(FC) $(FLAGS) $(OBJS) -o $(EXE)
profile: $(OBJS)
$(FC) $(FLAGS) $(OBJS) -o $(PROFEXE) $(PROFILEFLAG)
clean:
rm *.o *.mod
Running make profile runs the rule associated with profile, which creates the executable program_prof.exe which can be profiled. However, since the individual dependencies obj1 and obj2 are not compiled with the -pg flag, I cannot profile the code running in those files.
Is there a way I can add a rule such that the individual objects are also recompiled with the -pg flag when I need to profile?
Currently I am editing the individual object dependencies manually to:
%.o: %.f90
$(FC) $(FLAGS) -c $< -pg
which works as expected, but is time consuming (my actual makefile has multiple dependencies in subfolders, all of which need to be edited). Ideally, I am looking for a rule which should recompile individual objects with the `-pg' flag.
You can do exactly what you want, with target-specific variables:
PROFILE :=
%.o : %.f90
$(FC) $(FLAGS) $(PROFILE) -c -o $# $<
default: $(OBJS)
....
profile: PROFILE := -pg
profile: $(OBJS)
....
However, this is not usually the preferred way. Unless you're really diligent about always doing a full clean when switching back and forth between profile and non-profile builds it's very easy to get confused and have some objects compiled with profiling and others compiled without.
As mentioned in the comments, it's better to build them into separate directories:
$(PDIR)/%.o : %.f90
#mkdir -p $(#D)
$(FC) $(FLAGS) -pg -c -o $# $<
$(ODIR)/%.o : %.f90
#mkdir -p $(#D)
$(FC) $(FLAGS) -c -o $# $<
default: $(addprefix $(ODIR)/,$(OBJS))
$(FC) $(FLAGS) $^ -o $#
profile: $(addprefix $(PDIR)/,$(OBJS))
$(FC) $(FLAGS) -pg $^ -o $#

Makefile multiple targets from same source file, with different flags

I have a binary that I need to build multiple times with different compiler flags. Therefore, I have a Makefile that states something like:
OBJECTS_A := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.a.o))
OBJECTS_B := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.b.o))
OBJECTS_C := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.c.o))
I also define a rule to change the flags for each OBJECTS_x:
$(OBJECTS_B): DEFINES+=-D_B
$(OBJECTS_C): DEFINES+=-D_C
And this is where the problem happens: If I state the targets separately, as:
$(OBJFOLDER)/%.a.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $#
$(OBJFOLDER)/%.b.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $#
$(OBJFOLDER)/%.c.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $#
All works. However, if I merge all rules into one, only the first is evaluated:
$(OBJFOLDER)/%.a.o $(OBJFOLDER)/%.b.o $(OBJFOLDER)/%.c.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $#
What I get on a dry run is that only $(OBJFOLDER)/%.a.o objects are build, but on the linking rule each binary requires its objects (and b and c binaries fail to build, therefore).
Any ideas?
Thank you!
You can achieve this using secondary expansion :
.SECONDEXPANSION:
$(OBJFOLDER)/%.o: $$(basename $$*).cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $#
Note that this is not a very idiomatic way of doing this, a more usual define / call / eval combo can be used to generate rules as in your first solution :
VARIANTS=a b c
DEFINES_FOR_a=
DEFINES_FOR_b=-D_B
DEFINES_FOR_c=-D_C
define make_target =
$$(OBJFOLDER)/%.$(1).o: %.cpp
$$(COMPILER) $$(CFLAGS) $$(INCFOLDER) $$(DEFINES_FOR_$(1)) -c $$< -o $$#
endef
$(eval $(foreach variant,$(VARIANTS),$(call make_target,$(variant))))
Another way is to create symlinks to your source files and compile those with different flags. This way the same one generic pattern rule (OBJFOLDER)/%.o: %.cpp can build all of your targets:
OBJECTS_A := $(SOURCES:%.cpp=$(OBJFOLDER)/%.a.o)
OBJECTS_B := $(SOURCES:%.cpp=$(OBJFOLDER)/%.b.o)
OBJECTS_B := $(SOURCES:%.cpp=$(OBJFOLDER)/%.c.o)
$(OBJECTS_B): DEFINES+=-D_B
$(OBJECTS_C): DEFINES+=-D_C
%.a.cpp : %.cpp
ln -s $< $#
%.b.cpp : %.cpp
ln -s $< $#
%.c.cpp : %.cpp
ln -s $< $#
$(OBJFOLDER)/%.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c -o $# $<

How to move .o on project folder?

I wrote this Makefile to move all .o of the project inside a directory 'obj' in the main folder.
Directories
.:
actor/ lib/ Controller.cpp Controller.h Controller.o doc.txt main.cpp main.o Makefile uno VRP*
./actor:
Customer.cpp Customer.h Customer.o Depot.cpp Depot.h Depot.o Route.cpp Route.h Route.o Vehicle.cpp Vehicle.h Vehicle.o
./lib:
Search.cpp Search.h Search.o Utils.cpp Utils.h Utils.o VRP.cpp VRP.h VRP.o
Makefile
CXX=g++
RM=rm -rf
BIN_NAME=VRP
CPPFLAGS=-s -O2 -std=gnu++11 -Wall
SRCS=$(wildcard *.cpp actor/*.cpp lib/*.cpp)
OBJS=$(subst .cpp,.o,$(SRCS))
all: $(OBJS_DIR) $(BIN_NAME)
$(OBJS_DIR):
mkdir $(OBJS_DIR)
$OBJS_DIR)/%.o : $(SRCS)
$(CXX) $(CPPFLAGS) -c $< -o $#
$(BIN_NAME) : $(OBJS)
$(CXX) -o $# $^
debug:
$(CXX) -g $(CPPFLAGS) -o $(BIN_NAME) $(OBJS)
.PHONY : all clean
clean:
$(RM) $(OBJS) $(OBJS_DIR)
dist-clean: clean
$(RM) $(BIN_NAME)
How can I make it works?
This line $OBJS_DIR)/%.o : $(SRCS) sets the prerequisites of every file that matches $OBJS_DIR)/%.o to all the files in $(SRCS) that's not even close to what you want. (It is also a typo. You are missing the opening ().
You can't write a single rule for what you are trying to do here you need three pattern rules (or one with a vpath/VPATH setup).
$(OBJS_DIR)/%.o: %.cpp
$(CXX) $(CPPFLAGS) -c $< -o $#
$(OBJS_DIR)/%.o: actor/%.cpp
$(CXX) $(CPPFLAGS) -c $< -o $#
$(OBJS_DIR)/%.o: lib/%.cpp
$(CXX) $(CPPFLAGS) -c $< -o $#
That being said you don't actually have any targets that match $(OBJS_DIR)/%.o since the value of $(OBJS) is Controller.o ... actor/Customer.o ... lib/Search.o. To fix that you also need:
OBJS=$(addprefix $(OBJS_DIR)/,$(patsubst %.cpp,%.o,$(notdir $(SRCS))))
$(notdir) to get just the filename from the source files.
$(patsubst) instead of $(subst) just for correctness (subst would have modified a Bar.cpp.cpp file to Bar.o.o).
$(addprefix) to add the $(OBJS_DIR) prefix to the bare object file names.

Multiple Level of Dependencies in a Makefile

I am very new to makefiles. I have been able to write the script shown below by copying different examples found online. If I am doing something wrong, or not conventional, please point it out.
This is my (working) Makefile for a fortran code I have. The main program stored in main.f08 calls a module stored in file1.f08:
FC = gfortran
SRCS: main.f08
OBJS: $(SRCS:.f08=.o)
EXEC: $(SRCS:.f08=)
all: $(EXEC)
file1.o file1.mod: file1.f08
$(FC) -c $<
touch $*.o $*.mod
main.o: file1.mod
%.o: %.f08
$(FC) $(FFLAGS) -c $<
main: file1.o
%: %.o
$(FC) -o MainExe $^
clean:
rm -f MainExe *.o *.mod
I have tried to extrapolate that technique to write a makefile which has a ladder of dependencies. For example, main.f08 would be calling the module file1.f08, which in turn would be calling the module file2.f08. Here is what I have so far:
FC = gfortran
SRCS: main.f08
OBJS: $(SRCS:.f08=.o)
EXEC: $(SRCS:.f08=)
all: $(EXEC)
file2.o file2.mod: file2.f08
$(FC) -c $<
touch $*.o $*.mod
file1.o: file2.mod
file1.o file1.mod: file1.f08
$(FC) -c $<
touch $*.o $*.mod
main.o: file2.mod file1.mod
%.o: %.f08
$(FC) $(FFLAGS) -c $<
main: file1.o
%: %.o
$(FC) -o MainExe $^
clean:
rm -f MainExe *.o *.mod
The command line output consist of a few line showing that the code starts compiling the two modules and the main program and then several lines of errors that look like this:
Undefined symbols for architecture x86_64:
"___brownian_MOD_calcb", referenced from:
___integral_MOD_calcint in Integral.o
I've been working on this and I actually have figured it out.
The main executable should be linked to the module's object files in the correct order (an object file should not precede its dependency) followed by its object file, main.o. The module's object file should be linked to their dependency (if any) and their .f08 file. Finally, the touch command makes sure that the .mod files are up to dates with the .o files. Here is the corrected code showed in its simplest version:
FC = gfortran
all: main
main : file2.o file1.o main.o
$(FC) -o executable file2.o file1.o main.o
main.o: main.f08
$(FC) -c main.f08
file2.o : file2.f08
$(FC) -c file2.f08
touch file2.o file2.mod
file1.o : file2.o file1.f08
$(FC) -c file1.f08
touch file1.o file1.mod
A more advanced version of the makefile is shown below:
FC = gfortran
SRCS = main.f08
SOBJ = $(SRCS:.f08=.o)
EXEC = #(SRCS:.f08=)
FILE = file2.f08 file1.f08
FOBJ = $(SRCS:.f08=.o)
all: $(EXEC)
$(EXEC): $(FOBJ) $(SOBJ)
$(FC) -o executable $^
%.o: %.f08
$(FC) -c $<
touch $*.o $*.mod

Makefile : No rule to make target (automatic variables)

I am having trouble with my makefile, i have been reading somme tutoriels on how to make a more re-usable makefile but i am facing this error, and i have been searching for a while now, especially on the GNU make manual and here.
Here is my makefile :
SRC_DIR=./src
BUILD_DIR=./build
OBJS= $(BUILD_DIR)/main.o $(BUILD_DIR)/hamming.o
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/%.h
$(CC) -c $< $(CFLAGS) -o $#
$(BUILD_DIR)/main: $(OBJS)
$(CC) -o $# $^ $(CFLAGS)
I am having the error :
make: No rule to make target build/main.o', needed bybuild/main'. Stop.
It seems to me that the objects in the variable OBJS are not associated with the %.o pattern rule, but i don't know why.
In my working directory there is : my makefile and the two directories 'src' and 'build'.
Thank you.
I'll go out on a limb and guess that there is no src/main.h. If that's the case, you could fix things this way:
$(BUILD_DIR)/hamming.o: $(BUILD_DIR)/%.o : $(SRC_DIR)/%.h
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) -c $< $(CFLAGS) -o $#
EDIT:
Now I'm puzzled. Please try this (it is crude, but if it works we can refine it):
SRC_DIR=./src
BUILD_DIR=./build
OBJS= $(BUILD_DIR)/main.o $(BUILD_DIR)/hamming.o
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/%.h
$(CC) -c $< $(CFLAGS) -o $#
$(BUILD_DIR)/main.o: $(SRC_DIR)/main.c
$(CC) -c $< $(CFLAGS) -o $#
$(BUILD_DIR)/main: $(OBJS)
$(CC) -o $# $^ $(CFLAGS)
Here is a little documentation I put together for NMake a while back I hope it helps. Are you sure there are only tabs before the commands. You can't have spaces that is the number one error I have seen in the past.

Resources