gfortran makefile not working on mac - makefile

I am trying to run a makefile with gfortran in my mac. It compiles without problem in Fedora 18, but I can't make it work in Mac OS 10.8.4 with the last gfortran from HPC.
I am newbie on fortran, so some light would be appreciated.
Here is the Make file:
# Makefile made to work with GNU Make
.DEFAULT:
BIN=bin
OBJ=obj
vpath= %$(OBJ)/.o $(OBJ)
vpath= %.mod $(OBJ)
EXES= pasos \
pasosng \
pasosm \
trans \
cost \
lcal \
fluj \
loc \
eval \
impas \
imptra \
mats \
imploc \
matesp \
dimen
FC=gfortran
LN=gfortran
FCFLAGS=$(USER_FCFLAGS) -g3 -B $(OBJ) -J $(OBJ) #fc_options #fc_warnings
LFLAGS=$(USER_LFLAGS)
ifdef SystemRoot
dotexe=.exe
endif
ifdef F_PROFILE
FCFLAGS:=$(FCFLAGS) -pg
LFLAGS:=$(LFLAGS) -pg
endif
ifdef F_TEST
FCFLAGS:=-O0 -fbounds-check $(FCFLAGS)
else
FCFLAGS:=-O3 $(FCFLAGS)
endif
COMPILE=$(FC) $(FCFLAGS) -o $# -c $<
LINK=$(LN) $(LFLAGS) -o $# -Wl,-Map=$#.map $^
%.o : %.f90
$(COMPILE)
all: prepare $(EXES)
$(OBJ)/%.o : %.f90
$(COMPILE)
clean:
rm -rf $(OBJ) $(BIN)
prepare: $(BIN) $(OBJ)
$(BIN):
mkdir $(BIN)
$(OBJ):
mkdir $(OBJ)
pasos: prepare $(BIN)/pasos$(dotexe)
#echo $#
$(BIN)/pasos$(dotexe) : $(OBJ)/pasos.o \
$(OBJ)/nodes.o \
$(OBJ)/io_list.o \
$(OBJ)/rcomm.o \
$(OBJ)/tparc.o \
$(OBJ)/zcomm.o \
$(OBJ)/rcomm.o \
$(OBJ)/pcomm.o \
$(OBJ)/getoptm.o \
$(OBJ)/control.o \
$(OBJ)/heap.o \
$(OBJ)/gener.o \
$(OBJ)/param.o \
$(OBJ)/ascii.o \
$(OBJ)/pcomm.o \
$(OBJ)/mensamod.o \
$(OBJ)/optionsm.o \
$(OBJ)/debugm.o
$(LINK)
The file is longer, but I dont know if it is needed to understand the error. The error I get when I run make over the directory is:
tcapelle$ gnumake
gfortran -o bin/pasos -Wl,-Map=bin/pasos.map obj/pasos.o obj/nodes.o obj/io_list.o obj/rcomm.o obj/tparc.o obj/zcomm.o obj/pcomm.o obj/getoptm.o obj/control.o obj/heap.o obj/gener.o obj/param.o obj/ascii.o obj/mensamod.o obj/optionsm.o obj/debugm.o
ld: unknown option: -Map=bin/pasos.map
collect2: error: ld returned 1 exit status
gnumake: *** [bin/pasos] Error 1
Edit:
I changed in the makefile
LINK=$(LN) $(LFLAGS) -o $# -Wl,-Map=$#.map $^
to
LINK=$(LN) $(LFLAGS) -o $# $^
and it compiles with some errors, but it worked.
What does this -Wl,-Map= thing do?

The problem is that the BSD linker (in contrast to the GNU linker) does not recognize options, if they are separated from the corresponding value by an equal sign (instead of a whitespace). So
ld -Map test.map
is fine, while
ld -Map=test.map
is not. Therefore, you must make sure, the compiler passes the linker options to the linker in the latter form. For that you need
gfortran -Wl,-Map,test.map ...
which you can achieve by changing the definition of the LINK variable to:
LINK=$(LN) $(LFLAGS) -o $# -Wl,-Map,$#.map $^

Related

Why is Makefile not including the header?

I'm trying to make a library for my project but I am very very new to Makefiles. I tried several configurations and adding -I but none worked.
I have the following three:
libft/
../includes/
....libft.h
../lst
....ft_lstnew.c
....ft_lstadd_front.c
....ft_lstadd_back.c
.... [...]
../src
....ft_isalpha.c
....ft_isalnum.c
.... [...]
And the following makefile:
NAME=libft.a
LIBSO=libft.so
CC=gcc
CFLAGS=-Wall -Wextra -Werror
SRC_DIR=src/
BONUS_DIR=lst/
OBJ_DIR=obj/
SRC_FILES= ft_bzero.c \
ft_isalmun.c \
ft_isalpha.c \
ft_isascii.c \
ft_isdigit.c \
ft_isprint.c \
ft_memchr.c \
ft_memcpy.c \
ft_memmove.c \
ft_memset.c \
ft_strchr.c \
ft_strlcat.c \
ft_strlcpy.c \
ft_strlen.c \
ft_strncmp.c \
ft_strrchr.c \
ft_tolower.c \
ft_toupper.c
BONUS_FILES=ft_lstadd_back.c \
ft_lstadd_front.c \
ft_lstdelone.c \
ft_lstclear.c \
ft_lstiter.c \
ft_lstlast.c \
ft_lstmap.c \
ft_lstnew.c \
ft_lstsize.c
SRC_PATH=$(addprefix $(SRC_DIR), $(SRC_FILES))
BONUS_PATH=$(addprefix $(BONUS_DIR), $(BONUS_FILES))
SRC_NAMES=$(SRC_FILES:.c=.o)
BONUS_NAMES=$(BONUS_FILES:.c=.o)
SRC_PATH_O=$(addprefix $(SRC_DIR), $(SRC_NAMES))
BONUS_PATH_O=$(addprefix $(BONUS_DIR), $(BONUS_NAMES))
HDR_NAME=libft.h
HDR_DIR=includes/
HDR= $(addprefix $(HDR_DIR),$(HDR_NAME))
all: $(NAME)
$(NAME): $(SRC_PATH_O)
ar rc $# $<
ranlib $#
$(OBJ_DIR):
mkdir $#
$(OBJ_DIR)%.o: $(SRC_DIR)%.c $(HDR_NAME)
$(CC) $(CFLAGS) -c $< -o $# -I $(HDR)
clean:
rm -rf $(OBJ_DIR)
fclean: clean
rm -f $(NAME)
re: fclean all
.PHONY: all clean fclean re
And I keep getting this each time I type make on the terminal:
gcc -Wall -Wextra -Werror -c -o src/ft_bzero.o src/ft_bzero.c
src/ft_bzero.c:1:10: fatal error: libft.h: No such file or directory
1 | #include "libft.h"
| ^~~~~~~~~
compilation terminated.
make: *** [<builtin>: src/ft_bzero.o] Error 1
Am I missing something? It's literally my first time.
Yes, you're missing some things.
First, look at the command line make shows:
gcc -Wall -Wextra -Werror -c -o src/ft_bzero.o src/ft_bzero.c
Note that the output here is not right for the recipe of the pattern rule you created: there's no -I option, and the object file is being written to src/ not obj/.
From this you should realize that your pattern rule is not being used at all, and instead make is using its built-in rule for building object files.
Why isn't your pattern rule being used? Let's look at it:
$(OBJ_DIR)%.o: $(SRC_DIR)%.c $(HDR_NAME)
what is this after variable expansion?
obj/%.o: src/%.c libft.h
This pattern (like all patterns) can only match if ALL the prerequisites either already exist or can be built. The src/%.c exists, after the pattern substitution. What about libft.h? No, that doesn't exist. What does exist is includes/libft.h but that's not the same thing.
So, this rule fails to match and make goes back to using its default rules.
If you want to say that every object file depends on that header, you have to use the correct path to the header file when you write the pattern.
Next, this is wrong:
$(CC) $(CFLAGS) -c $< -o $# -I $(HDR)
What is $(HDR)? It's the name of the file: include/libft.h. You don't include header file names with -I; you include directories that headers are looked for in. So you need $(HDR_DIR) here instead.

makefile C code compile and link in one step but want two separate steps

My currently working makefile uses gcc to compile and link in one step. It is 600 lines long so I have cut it down to just show you the 'compile and link' and hex stages (very cut down code here!)
$(PROGRAM_ELF): \
$(BSP_DIR)/install/lib/$(CONFIGURATION)/libmetal.a \
$(BSP_DIR)/install/lib/$(CONFIGURATION)/libmetal-gloss.a \
$(BSP_DIR)/metal.$(LINK_TARGET).lds
mkdir -p $(dir $#)
$(MAKE) -C $(SRC_DIR) $(basename $(notdir $#)) \
PORT_DIR=$(PORT_DIR) \
AR=$(RISCV_AR) \
CC=$(RISCV_GCC) \
CXX=$(RISCV_GXX) \
ASFLAGS="$(RISCV_ASFLAGS)" \
CCASFLAGS="$(RISCV_CCASFLAGS)" \
CFLAGS="$(RISCV_CFLAGS)" \
CXXFLAGS="$(RISCV_CXXFLAGS)" \
XCFLAGS="$(RISCV_XCFLAGS)" \
LDFLAGS="$(RISCV_LDFLAGS)" \
LDLIBS="$(RISCV_LDLIBS)" \
PROJ_SRC="$(PROJ_SRC)"
$(PROGRAM_HEX): \
$(PROGRAM_ELF)
$(RISCV_OBJCOPY) -O ihex $(PROGRAM_ELF) $#
mv $(PROGRAM_HEX) $(PROGRAM_TMP)
$(RISCV_OBJCOPY) -O verilog $(PROGRAM_ELF) $#
cp $(PROGRAM_HEX) $(PROGRAM_MEM)
mv $(PROGRAM_TMP) $(PROGRAM_HEX)
However, I need the 'compile and link stage' to be in 2 steps now as I'll be using a different compiler which has separate compile and link exes. How would I do this ? So the above would need to be split into 2. Examples online are a bit vague.
at its simplest, you use the gcc (or g++) -c option to compile the source without linking. This will generate an object file - which you can use in the linker state. Here is a simple example:
SOURCE = test.cpp
OBJECT = test.o
OUTPUT = run
all:
#g++ $(SOURCE) -c -o $(OBJECT) <------ Compile test.cpp, produces test.o
#g++ $(OBJECT) -o $(OUTPUT) <------ Links test.o into executable `run`
clean:
#$(RM) -rf $(OBJECT) $(OUTPUT)
That's it...
I did this which seemed to work:
#list of all files
PROJ_SRC = $(SRC_DIR)/plsi2c_riscv.c \
$(SRC_DIR)/SimSpi.c \
etc
#assume BUILD_FOLDER defined already
OBJ_FILES = $(addprefix $(BUILD_FOLDER)/,$(PROJ_SRC:.c=.o))
$(BUILD_FOLDER)/%.o: %.c
#Create the folder structure for the output file
#mkdir -p $(dir $#)
$(MY_CC) $(CCFLAGS) $< -o $#
$(BUILD_FOLDER)/example: $(OBJ_FILES)
mkdir -p $(dir $#)
#echo Linking $(notdir $#)
$(MY_LINK) $(LFLAGS) $^ $(LDLIBS) -o $#

What's the usage of "depend" in makefile

$(obj)u-boot: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT)
UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \
sed -n -e 's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
what does "depend" do here in the dependency line?
In this example, depend seems to simply be an arbitrary label which identifies another target further down in the file.

`No such file or directory` error when building Qt project without QMake, despite appropriate include path constructed

I'm trying to compile a small application using Qt but without using QMake, but whenever I try to run it, I get the following error message:
g++ -c -g -pg -Wall -Wextra -pipe -c -o ../../MOCFiles/moc_projectModel.o ../../MOCFiles/moc_projectModel.cpp
In file included from ../../MOCFiles/moc_projectModel.cpp:10:0:
../../MOCFiles/../Src/ProjectStructure/projectModel.h:4:30: fatal error: QAbstractItemModel: No such file or directory
compilation terminated.
make: *** [../../MOCFiles/moc_projectModel.o] Error 1
This would seem to suggest that I haven't constructed my $(INCLUDE) variable properly, but it is as follows:
INCLUDE = -I/usr/include/qt4 \
-I/usr/include/qt4/QtGui \
-I/usr/include/qt4/QtCore \
-I/usr/include/qt4/QtXml \
-I/usr/share/qt4/mkspecs/linux-g++ \
-I../../Src/ProjectStructure
and I am able to locate the QAbstractItemModel file in /usr/include/qt4/QtCore/, a directory which is part of my include variable. This is my first time writing a GNU Makefile and I'm not sure what it is I'm doing wrong. For reference, the entire file is included here:
CXX = g++
CXXFLAGS = -c -g -pg -Wall -Wextra -pipe
LINK = g++
LIBS = -L/usr/lib \
-L/usr/lib/i386-linux-gnu \
-lgtest \
-lQtGui \
-lQtCore \
-lQtXml \
-lpthread
INCLUDE = -I/usr/include/qt4 \
-I/usr/include/qt4/QtGui \
-I/usr/include/qt4/QtCore \
-I/usr/include/qt4/QtXml \
-I/usr/share/qt4/mkspecs/linux-g++ \
-I../../Src/ProjectStructure
OBJECTS = ../Objects/main.o \
../Objects/test_projectEntity.o \
../Objects/moc_test_projectModel.o \
../../Objects/projectEntity.o \
../../Objects/projectModel.o \
../../MOCFiles/moc_projectModel.o
../../Binaries/tests: $(OBJECTS)
$(LINK) $^ $(LIBS) -o $#
../Objects/main.o : ../Src/main.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) ../Src/main.cpp -o ../Objects/main.o
../Objects/moc_test_projectModel.o : ../MOCFiles/moc_test_projectModel.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) ../MOCFiles/moc_test_projectModel.cpp -o ../Objects/moc_test_projectModel.o
../../MOCFiles/moc_test_projectModel.cpp : ../Src/test_projectModel.cpp
moc ../Src/test_projectModel.cpp -o ../MOCFiles/moc_test_projectModel.cpp
../Objects/test_projectEntity.o : ../Src/test_projectEntity.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) ../Src/test_projectEntity.cpp -o ../Objects/test_projectEntity.o
clean:
rm -f ../Objects/main.o ../Objects/test_projectEntity.o ../Objects/test_projectModel.o
It looks as if you're trying to build ../../Binaries/tests. One of the preqs is ../../MOCFiles/moc_projectModel.o, but there's no explicit rule for building that, so Make uses the implicit rule and attempts this:
g++ -c -g -pg -Wall -Wextra -pipe -c -o ../../MOCFiles/moc_projectModel.o ../../MOCFiles/moc_projectModel.cpp
Notice that there's no mention of INCLUDE there. So g++ doesn't know to look in /usr/include/qt4/QtCore/. The simple solution is to add a rule:
../../MOCFiles/moc_projectModel.o : ../../MOCFiles/moc_projectModel.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) $< -o $#
Notice that I used automatic variables $< and $# there, to reduce redundancy and clutter. We could also make it into a pattern rule:
../../MOCFiles/%.o : ../../MOCFiles/%.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) $< -o $#
This takes care of moc_projectModel.o and anything else that has the same pattern (source and object both in MOCFiles/). We could make other improvements, but that should be enough to get you up and running.

Makefile issue. Second set of eyes please

PROJ = .
SRC_ROOT = .
FLAGS = -g -Wall -Wextra
INC = -I$(PROJ) \
-I$(SRC_ROOT)/Exception \
-I$(SRC_ROOT)/MapFile
DEPS = $(SRC_ROOT)/Exception/Exception.h \
$(SRC_ROOT)/Exception/Exception.cpp \
$(SRC_ROOT)/MapFile/MapFile.h \
$(SRC_ROOT)/MapFile/MapFile.cpp
OBJS = $(SRC_ROOT)/MapFile/MapFIle.o \
$(SRC_ROOT)/Exception/Exception.o
all: main $(OBJS)
%.o : %.cpp %.h
g++ -c $(FLAGS) $(INC) $< -o $#
main: $(DEPS) $(OBJS) main.cpp
g++ -o main $(FLAGS) $(INC) main.cpp $(OBJS)
$(SRC_ROOT)/MapFile/MapFIle.o : $(SRC_ROOT)/MapFile/MapFIle.cpp $(SRC_ROOT)/MapFile/MapFIle.h
g++ -c $(FLAGS) $(INC) $< -o $#
clean:
rm -f *~
rm -f $(OBJS)
rm -f main
rm -f -R *.dSYM
When I comment out the explicit rule for MapFile.o I get a "no rule to build error for it" yet the implicit rule clearly works for Exception.o. Any idea what could be the issue? Hope it is not something simple that I am missing having been staring at it for a few. Thanks in advance.
Using GNU Make 3.81
The filenames are case-sensitive; in some places you have MapFile.cpp and MapFile.h, but elsewhere you have MapFIle.o (with a capital I) and MapFIle.cpp and so on.

Resources