makefile .mod compilation rule - makefile

I'm modifying makefile of a code. After compiling, I see that some *.mod files are generated. looking online, I figured out they are module files, but I don't see a compilation rule for them. I'm trying to change the directory in which these files are generated. I can change the rule for object files, but I can't find the rule that generates *.mod files.
Looking at the makefile, can someone advise me if a line in this file generates them or how to change their directory. Here is the makefile:
# GNU Makefile
# Paths
SDIR=./solver
ODIR=./obj
_CASE=./WorkCases/problem
CASE=$(SDIR)/$(_CASE)
TOP = .
FC = ifort
FFLAGS = -fpp -O1 -DPTR_INTEGER8 -warn nousage
# Define rule to make .f90
$(ODIR)/%.o : $(SDIR)/%.f90
$(FC) -c $(FFLAGS) $< -o $#
# set executable name
EXEC = $(dir ${CASE})/$(basename $(notdir ${CASE})).out
# shared global variables
_SHARED_OBJ = shared_modules.o main_vars.o debug_vars.o
SHARED_OBJ = $(patsubst %,$(ODIR)/%,$(_SHARED_OBJ))
OBJ = ${_SHARED_OBJ} $(_CASE).PARAMS.o
OBJ = $(patsubst %,$(SDIR)/%,$(_OBJ))
MAIN_OBJ = $(ODIR)/main.o
main : ${SHARED_OBJ} $(OBJ) $(MAIN_OBJ)
$(FC) ${FFLAGS} $(OBJ) $(MAIN_OBJ) -o $(EXEC) -lstdc++ -shared-intel

You can specify the destination directory for the .mod files by using the -module compiler option.
-module <directory>
See the ifort documentation here:
You can use the module path compiler option to specify the directory
in which to create the module files. If you do not use this option,
module files are created in the current directory.

Related

Makefile dependency error after using flags $(#:.o=.d)

I have created a Makefile for the below code structure
work
├── code
| |
| ├──inc/
| | └── main.h and test.h files here
| |
| ├──src/
│ └── main.c and test.c files here
├── _Build/
│ └── Makefile here
Here is the Makefile
# All path are referenced with the directory path of Makefile
# Directory Path for workspace
WORKSPACE = ..
# Directory path for code
PATH_DIR_CODE = $(WORKSPACE)/code
# Directory path for c source files
PATH_DIR_C_SOURCES = $(PATH_DIR_CODE)/src
# Directory path for c header files
DIR_PATH_C_HEADERS = $(PATH_DIR_CODE)/inc
# Directory path for obj files
DIR_PATH_OBJ = $(WORKSPACE)/obj
# Directory path for executables
DIR_PATH_BIN = $(WORKSPACE)/bin
# Executable name declaration
FILE_PATH_EXE = $(DIR_PATH_BIN)/main
# Command mkdir
MKDIR = mkdir
FILE_PATH_C_HEADER = $(shell find $(PATH_DIR_CODE) -name *.h)
DIR_PATH_C_HEADER = $(patsubst %/,%,$(sort $(dir $(FILE_PATH_C_HEADER))))
FILE_PATH_C_SRC = $(shell find $(PATH_DIR_CODE) -name *.c)
DIR_PATH_C_SRC = $(patsubst %/,%,$(sort $(dir $(FILE_PATH_C_SRC))))
INC_FILE_C_HEADER = $(addprefix -I, $(DIR_PATH_C_HEADER))
FILE_PATH_OBJ = $(patsubst $(DIR_PATH_C_SRC)/%.c, $(DIR_PATH_OBJ)/%.o, $(FILE_PATH_C_SRC))
CC = gcc
CFLAGS = -Werror -Wall
CDEPS = -MMD -MP -MF $(#:.o=.d)
LDFLAGS = -Llib
LDLIBS = -lm
MKDIR = mkdir
-include $(FILE_PATH_OBJ:.o=.d)
all : $(FILE_PATH_EXE)
.PHONY : all
$(FILE_PATH_EXE) : $(FILE_PATH_OBJ) | $(DIR_PATH_BIN)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(DIR_PATH_OBJ)/%.o : $(DIR_PATH_C_SRC)/%.c | $(DIR_PATH_OBJ)
$(CC) $(CFLAGS) -c $< $(CDEPS) -o $#
$(DIR_PATH_BIN) $(DIR_PATH_OBJ):
$(MKDIR) -p $#
clean :
$(RM) -rv $(DIR_PATH_BIN) $(DIR_PATH_OBJ)
Based on tutorial for dependencies I have used the flags
CDEPS = -MMD -MP -MF $(#:.o=.d)
and
-include $(FILE_PATH_OBJ:.o=.d)
still I am getting the following error
mkdir -p ../obj
gcc -Werror -Wall -c ../code/src/main.c -MMD -MP -MF ../obj/main.d -o ../obj/main.o
../code/src/main.c:4:10: fatal error: test.h: No such file or directory
#include "test.h"
^~~~~~~~
compilation terminated.
make: *** [Makefile:56: ../obj/main.o] Error 1
To remove this error what should be included in the Makefile?
Dependencies should be removed by this logic or some other logic should be used?
You are conflating two different things.
The .d files tell make where to look for prerequisites of the target. In this case the target is an object file (.o) and the prerequisite is a header file, but to make they're just "targets" and "prerequisites". Make is not restricted to just compiling C programs: it can do essentially any task where changing some files means that some other files need to be updated: compiling programs (not just C programs) is one common use but it can build documentation, web sites, run tests, etc. Make does its job by running commands, just as you would do it yourself from the command line (except make never forgets to add an option and doesn't make typos). It doesn't really know anything about "compilers" and "linkers", internally.
The error you are getting is from the compiler (or to be pedantic, the preprocessor), not make, and the compiler has to be told where to look for the header files it needs to include. Those are two completely different things and require different operations: the compiler requires that you provide the directories to search using the -I command line option.
I suppose it might be nice if the compiler could parse make's .d files and figure out where to look for headers, but it can't. You have to specify the flags yourself.
In your situation it's even more clear: you are actually using the compiler to generate the .d files! So there's a chicken-and-egg problem: if the compiler could get the paths from the .d files, but the .d files are being created from the compiler, then where do the paths come from in the first place?

Using GNU Make to compile non-existent object files

I've been learning C++ for a few months now by just using an editor and my terminal to compile and run my programs. But I saw a need to be a bit more formal with my projects, so I'm trying to learn how to build a proper project file structure and also how to use Make.
Currently, I am using GNU Make 4.1. But I am having trouble to creating object files with Make, receiving the error:
make: *** No rule to make target 'build/%.o', needed by 'main'. Stop.
I've been looking all over for a solution, but none have worked so far.
Here is my makefile:
# Specify compiler
CC=gcc
# Specify linker
LINK=gcc
# Specify flags
CPPFLAGS = -Wall -g
# Specify directories
SRCDIR = ./src
OBJDIR = ./build
# Compile object files
$(OBJDIR)/%.o : $(SRCDIR)/%.cpp
$(CC) -c -o $# $< $(CPPFLAGS)
# Compile object files into binary
main : $(OBJDIR)/%.o
$(CC) -o $# $^
Consider the final rule...
# Compile object files into binary
main : $(OBJDIR)/%.o
$(CC) -o $# $^
Unfortunately $(OBJDIR)/%.o isn't expanded in the way in which you require. Assuming all of your source files are in $(SRCDIR) you can create a variable containing their names...
SRCFILES := $(wildcard $(SRCDIR)/*.cpp)
Now create a variable containing the corresponding object file paths...
OBJFILES := $(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(SRCFILES))
Now $(OBJFILES) should contain the list of object file paths on which main is dependent. So the final rule becomes...
main: $(OBJFILES)
$(CC) -o $# $^

gcc output directory for submakes

I`m having a makefile with Sub makes. I want to place the Output of the submakes in one Directory. Can anyone explain me how to do this right?
-root |
|-stub
|-test
|-source
|-out
|-makefile
all of my submakes shall place their *.o files in out. I`m getting Errors there is no File or Directory ./out/**.o if i add ../out to the Objectfile.
here is my submakefile
# makefile to generate UNIT-tests
# sub makefile for location stub
# define any directories containing header files other than /usr/include
# TODO
# define any libraries to link into executable:
# if I want to link in libraries (libx.so or libx.a) I use the -llibname
# option, something like (this will link in libmylib.so and libm.so:
LIBS =
# TODO define the C source files
SRCS = $(STUBS)
# define the C object files
#
# This uses Suffix Replacement within a macro:
# $(name:string1=string2)
# For each word in 'name' replace 'string1' with 'string2'
ODIR=../out
OBJ = $(SRCS:%.c=%.o)
# define the C compiler to use
CC = gcc
# define any compile-time flags
#compile without link
CFLAGS = -O0 -Wall -c -g -fmessage-length=0 -fprofile-arcs -ftest-coverage
#TODO Linkerflags
LFLAGS = --coverage
# define the executable file,
all: $(TARGET) $(OBJ)
$(CC) $(OBJ) $(CFLAGS) -o $(TARGET) $(LFLAGS) $(OBJ)
#echo +++ build of stub finished +++
clean:
$(RM) *.o *~ $(MAIN)
# DO NOT DELETE THIS LINE -- make depend needs it

Makefile: Error referencing source files in "src" directory

[edit]- The answer is I have incorrectly defined the path to the include directory. Embarrasing mistake.
I am writing a makefile that builds objects from .c files in a src directory with headers in an include directory and stores them in an obj directory, and then builds and exe from those objects. A toy version is below.
# Makefile
IDIR = ../include
CC = gcc
CFLAGS = -I$(IDIR) -Wall
SDIR = src
ODIR = obj
_SOURCES = main.c aux1.c aux2.c aux3.c
SOURCES = $(patsubst %,$(SDIR)/%,$(_SOURCES))
_OBJECTS = $(_SOURCES:.c=.o)
OBJECTS = $(patsubst %,$(ODIR)/%,$(_OBJECTS))
_DEPS = aux1.h aux2.h aux3.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
EXE = exefile
$(ODIR)/%.o: $(SDIR)/%.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
$(EXE): $(OBJECTS)
$(CC) -o $# $^ $(CFLAGS)
.PHONY: clean
clean:
rm *o $(EXE)
The directory the makefile is in looks like this (when you ls)
include Makefile obj src trash
When I type make, I get the following error
make: *** No rule to make target `obj/main.o', needed by `exefile'. Stop.
I suspect the problem is with this line
$(ODIR)/%.o: $(SDIR)/%.c $(DEPS)
I am attempting to build each object file in obj/ by referencing the corresponding source file in src/ but the line seems do to something else. Is this the case? Is there an easy way to reference .c files in the source directory without "entering" the directory?
Thanks in advance
I believe your problem is the $(DEPS) dependency.
You set IDIR to ../include but from the toplevel directory (where make is run from) that path is incorrect.

Makefile: Compiling from directory to another directory

I am trying to use Makefile to compile a bunch of .cpp files located in src/code/*.cpp, then compile each *.o in build/, and finally generate executable with those in build/ as well.
I have read a couple answers that I tried to work with but have encountered issues I do not understand.
CC = g++
FLAGS = -g -c
SOURCEDIR = /src/code
BUILDDIR = build
EXECUTABLE = DesktopSpecificController
SOURCES = $(wildcard src/code/*.cpp)
OBJECTS = $(patsubst src/code/*.cpp,build/%.o,$(SOURCES))
all: dir $(BUILDDIR)/$(EXECUTABLE)
dir:
mkdir -p $(BUILDDIR)
$(BUILDDIR)/$(EXECUTABLE): $(OBJECTS)
$(CC) $^ -o $#
$(OBJECTS): $(BUILDDIR)/%.o : $(SOURCEDIR)/%.cpp
$(CC) $(FLAGS) $< -o $#
clean:
rm -f $(BUILDDIR)/*o $(BUILDDIR)/$(EXECUTABLE)
I do get the following error, and I am not sure why:
Makefile:19: target `src/code/main.cpp' doesn't match the target pattern
I also see that when trying to build the EXECUTABLE, it is not using the .o files, so it seems my rule is wrong here.
Your patsubst function is wrong; you can't use shell wildcard characters like *. You want:
OBJECTS = $(patsubst $(SOURCEDIR)/%.cpp,$(BUILDDIR)/%.o,$(SOURCES))
Also you should be using SOURCEDIR and BUILDDIR everywhere, not just in some places (otherwise you'll get inconsistencies). And finally, your SOURCEDIR value is wrong: it should not start with / I expect:
SOURCEDIR = src/code
SOURCES = $(wildcard $(SOURCEDIR)/*.cpp)

Resources