Troubles with my Makefile - makefile

I downloaded this Makefile and I'm having a hard time understanding how it works.
I am programming in Ocaml and for some module, I implemented an interface (.mli). Strangely, even when I add the .mli file before the corresponding .ml file, the Makefile seems to skip it; so I'm getting the error
could not find the X.cmi for the module X.
Worse, I added some file without the required .mli and strangely again the Makefile automatically added them to the list of sources.
I'm saying strangely but perhaps its perfectly normal to Makefiles expert.
I'm not an expert when it comes to Makefile, can anyone help me understanding how this Makefile works?
The compilation works fine, when I replace the line
$(EXEC): $(OBJS)
$(CAMLC) $(CUSTOM) -o $(EXEC) $(LIBS) $(OBJS)
With
$(EXEC): $(SOURCES)
$(CAMLC) $(CUSTOM) -o $(EXEC) $(LIBS) $(SOURCES)
and add the required .mli

Try
# Makefile
PRG =
# Fichiers dans l'ordre
ML =
MLI =
CMO=${ML:.ml=.cmo}
CMX=${ML:.ml=.cmx}
CMI=${ML:.mli=.cmi}
OCAMLFLAGS = -I
OCAMLLD = -ccopt -L.
OCAMLOPT = ocamlopt.opt
OCAMLC = ocamlc.opt
OCAMLDEP = ocamldep
${PRG}: ${OCAMLOPT} ${OCAMLFLAGS} ${OCAMLLD} -o $# ${CMX}
make clean
.SUFFIXES: .ml .mli .cmo .cmx .cmi
.ml.cmx:
${OCAMLOPT} ${OCAMLFLAGS} ${OCAMLLD} -c $<
.ml.cmo:
${OCAMLC} -c $<
.mli.cmi:
${OCAMLC} -c $<
clean:
rm -f *~ *.o *.cm? *mli
fullclean: clean
rm -f .depend ${PRG}
depend: .depend
.depend: ${ML} ${MLI}
rm -f .depend
${OCAMLDEP} ${ML} ${MLI} > .depend
include .depend
You'll have to setup PRG, ML, MLI, FLAGS, LD. :)

Related

Makefile ignoring included rules

I'm trying to create a makefile for a very basic c++ program. I'm trying to implement the automatic generation of dependencies by running g++ with the -M flag, storing this output in a .d file, and then including those .d files in my main makefile. The makefile content is below
CC=g++
CPPFLAGS=-Wall -Wextra -g -std=c++11
SOURCEDIR=src
SOURCES = $(wildcard $(SOURCEDIR)/*.cpp)
BUILDDIR=build
OBJDIR=$(BUILDDIR)/objs
OBJS=$(SOURCES:$(SOURCEDIR)/%.cpp=$(OBJDIR)/%.o)
DEP_FILES = $(OBJS:.o=.d)
OUTFILE=hello.out
$(OUTFILE) : $(OBJS)
$(CC) -o $# $^ $(CPPFLAGS)
include $(DEP_FILES)
$(OBJDIR)/%.d : $(SOURCEDIR)/%.cpp
$(CC) $(CPPFLAGS) $< -MM -MT $(#:.d=.o) > $#
$(DEP_FILES) : | $(OBJDIR)
$(OBJS): | $(OBJDIR)
$(OBJDIR):
mkdir -p $(OBJDIR)
.PHONY: clean
clean:
rm -f $(BUILDDIR) -r
rm -f *~
rm -f $(OUTFILE)
When I run make, the directory build/objs/ is generated and a .d file is generated with rules in it. Here's main.d file:
build/objs/main.o: src/main.cpp src/main.h
And here's the myfunc.d file:
build/objs/myfunc.o: src/myfunc.cpp src/main.h
Here's the issue
Since I'm calling include on these .d files, I'd expect the .o files which they specify to then be created, and then the main outfile to be created as the main rule. However, make creates the .d files, and then skips directly to the main compilation step without creating any .o files:
g++ -o hello.out build/objs/myfunc.o build/objs/main.o -Wall -Wextra -g -std=c++11
This fails with the following error, since the .o files are never created:
g++: error: build/objs/myfunc.o: No such file or directory
g++: error: build/objs/main.o: No such file or directory
g++: fatal error: no input files
How can I use this makefile to generate the .o files necessary for g++? Thank you for any help in advance!
I saw you got your makefile working but I just wanted to add a few things you might want to consider for future projects. I recommend using the vpath variable rather than specifying $(OBJDIR)/%.o in your makefile recipes. I actually read somewhere that it's not "cannon" to build object files in a separate directory, but in the cursory search I conducted before posting, I couldn't find the document.
That being said, I wrote a makefile that does what you wanted; it builds the output folder, generates the dependencies, and compiles the program. I specifically included the $(COMPILE.cpp) definition so you could see what it's composed of. $(CC) is specifically the C compiler, and $(CFLAGS) is specifically flags for the C compiler. They're just variables, obviously, so you can change them like you did and it will work fine, but the main think to keep in mind is that whoever uses your programs will expect to be able to configure the compilation as they see fit. This means they will set the $(CXX) and $(CXXFLAGS) expecting to set the C++ compiler and flags. $(CPPFLAGS) stands for C/C++ Preprocessor flags.
It's not the cleanest makefile, and if I was to change something, I would just compile the object files in place and save myself that headache. That cuts down on unnecessary make hacking, but for the purposes of answering your question, here it is. Anyways I hope this helps you somewhat, let me know if you have any questions.
Oh yea, I almost forgot; notice I changed your make clean script. I used $(RM) instead of simply rm -f. When you use utilities in your makefiles, you want to use them as variables. Again, this is to allow your users as much freedom and flexibility as possible when they're compiling your program.
vpath %.cpp src
vpath %.hpp include
vpath %.o build/objs
vpath %.d build/objs
.SUFFIXES:
.SUFFIXES: .cpp .hpp .o .d
SRCDIR = src
INCLUDESDIR = include
BUILDDIR = build
OBJDIR = $(BUILDDIR)/objs
SRCS = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS)))
DEP_FILES = $(patsubst %.o, %.d, $(OBJS))
INCLUDE_DIRS = -I $(INCLUDESDIR)
CXX = g++
CPPFLAGS =
CXXFLAGS = -Wall -Wextra -g -std=c++11
PROGRAM = hello.out
COMPILE.cpp = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDE_DIRS) $(TARGET_ARCH)
all: $(PROGRAM)
$(PROGRAM): %: $(OBJS)
$(LINK.cpp) $(INCLUDE_DIRS) $(addprefix $(OBJDIR)/, $^) $(LOADLIBES) $(LDLIBS) -o $#
%.o: %.cpp
$(COMPILE.cpp) -c -o $(OBJDIR)/$# $<
%.d: %.cpp
mkdir -p $(OBJDIR)
$(COMPILE.cpp) $^ -MM -MT $(addprefix $(OBJDIR)/, $(#:.d=.o)) > $(OBJDIR)/$#
include $(DEP_FILES)
.PHONY: clean
clean:
#echo $(RM)
$(RM) $(BUILDDIR) -r
$(RM) *~
$(RM) $(PROGRAM)
For anyone having a similar issue, here's the correct solution is in the comments. Here for convenience: The included .d files generate dependencies but not a recipe for making the .o files, and since I'm putting things in various directories the default rule doesn't work here, so the .o files aren't created. The solution was to add in the following rule to my main makefile.
$(OBJDIR)/%.o :
$(CC) -c -o $# $< $(CPPFLAGS)
Thanks Matt and Renaud for your answers!

Makefile to auto compile, assemble and link many files in a directory

Sorry for repetition, but I could not find the solution.
Following is the sequence of the commands I want Makefile to accomplish.
gcc-elf-gcc -S -combine loadStoreByte.c string.c lib_uart.c bubble_uart.c -o bubble_uart.s
gcc-elf-as -o startup.o startup.s;
gcc-elf-as -o handler.o handler.s;
gcc-elf-as -o bubble_uart.o bubble_uart.s;
gcc-elf-ld -o bubble_uart -T browtb.x bubble_uart.o startup.o handler.o;
That is, I want to compile all C files into a single S file and then assemeble all s files into corresponding object files and the link all object files into one executable.
I tried the following makefile. The individual targets work fine, but could not run all the target at the same time using "make all".
Please guide how to fix it.
CC = brownie32-elf-gcc
AS = brownie32-elf-as
LK = brownie32-elf-ld
SFILE = $(wildcard *.s)
OFILE = $(patsubst %.s,%,$(SFILE))
CFILE = $(wildcard *.c)
OBJ = $(wildcard *.o)
APP = bubble_uart
all: compile assemble link
link: $(OBJ)
$(LK) -o $(APP) -T browtb.x $^
assemble: $(OFILE)
%: %.s compile
$(AS) -o $#.o $<
compile: $(CFILE)
$(CC) -S -combine $^ -o $(APP).s
clean:
rm -f $(OBJ) $(APP) $(APP).s *.o
Thanks
Your makefile is not written with "best practices" and because of that it was easy for you to make mistakes. I will re-write your makefile here, with best practices, which solves all your problems. Please study it with the aid of the GNU Make manual.
The biggest single problem is that you have "procedures/actions", such as "assemble" as make targets. This makes the makefile into a kind of "procedural" program. GNU Make is not designed to be a procedural language, instead, it is a declarative language. The "targets" should not be actions, but actual files, or "phony" files, which should be collections of actual files.
The use of wildcard in makefiles is a bad idea - it is best to list your files explicitly, as I have shown.
Please consult my answer
makefile enforce library dependency ordering
for a discussion of good practices, including phony and real targets.
MAKEFILE := $(lastword $(MAKEFILE_LIST))
CFILES := \
loadStoreByte.c \
string.c \
lib_uart.c \
bubble_uart.c
SFILE_OUTPUT := bubble_uart.s
SFILES := $(SFILE_OUTPUT) \
startup.s \
handler.s
OFILES := $(SFILES:s=o)
APP := bubble_uart
.PHONY: all
all: $(APP)
$(APP): browtb.x $(OFILES) $(MAKEFILE)
gcc-elf-ld -o $# -T $< $(OFILES)
$(OFILES): %o : %s $(MAKEFILE)
gcc-elf-as -o $# $<
$(SFILE_OUTPUT): $(CFILES) $(MAKEFILE)
gcc-elf-gcc -S -combine $(CFILES) -o $#
It is usually best if the target of a rule is the name of the file the rule produces.
So the compile rule:
compile: $(CFILE)
$(CC) -S -combine $^ -o $(APP).s
should be this:
$(APP).s: $(CFILE)
$(CC) -S -combine $^ -o $#
Likewise the object rule:
%: %.s compile
$(AS) -o $#.o $<
should be this:
%.o: %.s
$(AS) -o $# $<
(There's no reason for it to depend on compile or $(APP).s, since bubble_uart.s is irrelevant to most object files.)
Then the list of object files should include bubble_uart.o:
SFILES = $(sort $(wildcard *.s) $(APP).s)
OFILES = $(patsubst %.s,%.o,$(SFILES))
(The sort is to remove duplicates.) Note that this is the list of object files needed for construction of the executable, not the list of object files that happen to exist at the beginning of the build process.
Finally, the executable:
$(APP): $(OFILES)
$(LK) -o $# -T browtb.x $^

How to write a makefile for Fortran with modules?

gg=mpif90
DEPS=matrix.mod
OBJ= main.o sub1.o
main.out: $(OBJ)
$(gg) -o $# $^
%.mod:%.90 %.o
$(gg) -c -o $# $^
%.o:%.f90 $(DEPS)
$(gg) -c -o $# $^
.PHONY: clean
clean:
-rm -f *.o *~
Look. The main program is main.f90.sub1.f90 will be called by main.f90. Both will use matrix.f90 which is a module. I know I can directly generate the executable program without compile then link. But I do not like that way.
The mod file is only a by-product of compiling %.o, you shouldn't use -o $# here, change it to
%.mod: %.90
$(gg) -c $^
This will work for most cases, but not all. That's because the name of mod file depends only on the module name, it has nothing to do with the source file name. So the safest way is to specify the dependency explictly.
matrix.mod: matrix.f90
$(gg) -c matrix.f90
Sometimes one f90 source file can contain two or more modules.
matrix33.mod matrix99.mod: matrix.f90
$(gg) -c matrix.f90

Fortran90 Makefile with pre-compilation and modules

I'm trying to write a Makefile to compile a Fortran90 project that consists of several source files containing subroutines and modules. To make things more complicated, I'm using pre-compilation (creating *.for files from *.F files). I could not find any answer to this, but this may be because I get confused by the different styles of Makefile syntax.
I created a stripped-down version for reproducing my problem (available on https://github.com/stineb/stackoverflow). This contains a main program (sayhello.F), two subroutines in separate source files (schleppe.F and schnuppi.F), and two modules in separate source files (words_schleppe.mod.F and words_schnuppi.mod.F). The executable is hello.
I am able to build it with a simple Makefile and avoiding the pre-compilation. This file (Makefile_simple) looks like this:
FCOM=gfortran
EXE = hello
standard:
$(FCOM) -c words_schleppe.mod.F
$(FCOM) -c words_schnuppi.mod.F
$(FCOM) -c schleppe.F
$(FCOM) -c schnuppi.F
$(FCOM) words_schleppe.mod.o words_schnuppi.mod.o schleppe.o schnuppi.o sayhello.F -o $(EXE)
.PHONY: clean
clean:
rm $(EXE) *.o *.mod
However, my project will be a bit bigger than this so I want to make use of the cryptic features of a more complex Makefile for defining rules. And crucially: I want to pre-compile source files *.F into .for. This is where I haven't managed to define the rules to create the .mod files from the modules and build the whole thing. Disregarding the modules, I do get it running with the following Makefile (Makefile_complex on my github repository):
FCOM=gfortran
CPPFLAGS=-e
COMPFLAGS=
EXE=hello
SOURCES=sayhello.F schleppe.F schnuppi.F
OBJS=$(SOURCES:.F=.o)
all: $(OBJS)
# this may also be replaced by the ar command (creating archive)
$(FCOM) $(OBJS) -o $(EXE)
%.for: %.F
rm -f $*.for
$(FCOM) $(CPPFLAGS) $*.F > $*.for
$(OBJS): %.o: %.for
$(FCOM) -c -o $# $(COMPFLAGS) $*.for
# clean: remove .for, .o, .do, and .stb files
.PHONY: clean
clean:
-rm -f *.for *.o *.stb *.mod
What do I have to add to this in order to include the modules in the build? The dependencies are as follows: subroutine schleppe <- module words_schleppe; and subroutine schnuppi <- module words_schnuppi.
Help, anyone?
Thanks a bunch!
I FOUND THE SOLUTION! Simply, the rule for all: must include the module source files, and these must precede the other source files. Plus, rules of creating the object files from the module source files have to be added. The working Makefile looks like this:
FCOM=gfortran
CPPFLAGS=-E
COMPFLAGS=
EXE=hello
SOURCES=sayhello.F schleppe.F schnuppi.F
MODS=words_schleppe.F words_schnuppi.F
OBJS=$(SOURCES:.F=.o)
MODOBJS=$(MODS:.F=.o)
# this may also be replaced by the ar command (creating archive)
all: $(MODOBJS) $(OBJS)
$(FCOM) $(OBJS) $(MODOBJS) -o $(EXE)
%.for: %.F
rm -f $*.for
$(FCOM) $(CPPFLAGS) $*.F > $*.for
$(MODOBJS): %.o: %.for
$(FCOM) -c -o $# $(COMPFLAGS) $*.for
$(OBJS): %.o: %.for
$(FCOM) -c -o $# $(COMPFLAGS) $*.for
# clean: remove .for, .o, .do, and .stb files
.PHONY: clean
clean:
-rm -f *.for *.o *.stb *.mod

Makefiles: Get .cpp from one directory and put the compiled .o in another directory

I'm working on a cross-platform 2D engine for mobile devices (Windows Mobile 6 and Android). My Windows version is pretty much ready, but I still need to make sure the same functionality is available on Android.
What I want is one Makefile in the root of the project and several Makefile's for the project itself and the test applications.
Makefile
---Engine
------Makefile
------src
------bin
------intermediate
---Tests
------TestOne
---------Makefile
---------src
---------bin
---------intermediate
------TestTwo
---------Makefile
---------src
---------bin
---------intermediate
I'm basing my attempts on the following Makefile:
include ../makeinclude
PROGS = test1
SOURCES = $(wildcard *.cpp)
# first compile main.o and start.o, then compile the rest
OBJECTS = main.o start.o $(SOURCES:.cpp=.o)
all: $(PROGS)
clean:
rm -f *.o src
test1: $(OBJECTS)
$(LD) --entry=_start --dynamic-linker system/bin/linker -nostdlib -rpath system/lib -rpath $(LIBS) -L $(LIBS) -lm -lc -lui -lGLESv1_CM $^ -o ../$#
acpy ../$(PROGS)
.cpp.o:
$(CC) $(CFLAGS) -I $(GLES_INCLUDES) -c $*.cpp $(CLIBS)
However, I'm not very good with these things. What I want is for it to take the .cpp's that are in the src folder, compile them to .o and put them in the intermediate folder and, finally, compile the .o's to the compiled exe and put it in the bin folder.
I've managed to get clean to work like this:
cd intermediate && rm -f *.o
However, I can't get it to retrieve the .cpp's, compile them and put them in the intermediate folder.
I've looked at several other Makefiles, but none do the things I want to do.
Any help is appreciated.
There's more than one way to do this, but the simplest is to run in TestOne, making Intermediate/foo.o out of Src/foo.cpp and test1 out of Intermediate/foo.o, like this:
# This makefile resides in TestOne, and should be run from there.
include makeinclude # Adjust the path to makeinclude, if need be.
PROG = bin/test1
SOURCES = $(wildcard Src/*.cpp)
# Since main.cpp and start.cpp should be in Src/ with the rest of
# the source code, there's no need to single them out
OBJECTS = $(patsubst Src/%.cpp,Intermediate/%.o,$(SOURCES))
all: $(PROG)
clean:
rm -f Intermediate/*.o bin/*
$(PROG): $(OBJECTS)
$(LD) $(BLAH_BLAH_BLAH) $^ -o ../$#
$(OBJECTS): Intermediate/%.o : Src/%.cpp
$(CC) $(CFLAGS) -I $(GLES_INCLUDES) -c $&lt $(CLIBS) -o $#

Resources