Could not find the .cmi file - makefile

I would like to add a makefile for this project. I tried the following makefile:
SHELL:= /bin/bash
OCAMLC= ocamlfind ocamlc -package ppx_deriving.std -package sedlex.ppx -package sedlex -package MenhirLib
OCAMLYACC= $(OCAMLPREFIX)menhir -v
OCAMLLEX= $(OCAMLPREFIX)ocamllex -ml
%.ml %.mli: %.mly
$(OCAMLYACC) $*.mly
%.ml: %.mll
$(OCAMLLEX) $*.mll
%.cmi: %.mli
$(OCAMLC) $(OCAMLFLAGS) -c $*.ml
%.cmo: %.ml
$(OCAMLC) $(OCAMLFLAGS) -c $*.ml
ML_DOMAIN_MAIN= syntax.ml \
parser.ml \
lexer.ml \
calc.ml
CMO_DOMAIN_MAIN=$(ML_DOMAIN_MAIN:%.ml=%.cmo)
calc: $(CMO_DOMAIN_MAIN)
$(OCAMLC) -g -linkpkg -o $# $+
clean:
rm -rf calc *.o *.cm[oixa] *.annot *~ *.log *.output *.out *.mli parser.ml parser.mli
It returned an error:
menhir -v parser.mly
ocamlfind ocamlc -package ppx_deriving.std -package sedlex.ppx -package sedlex -package MenhirLib -c parser.ml
File "parser.ml", line 1:
Error: Could not find the .cmi file for interface parser.mli.
make: *** [parser.cmo] Error 2
rm parser.ml
Does anyone know how to fix this?

You have a typo in this rule:
%.cmi: %.mli
$(OCAMLC) $(OCAMLFLAGS) -c $*.ml
The prerequisite is .mli but you pass .ml to the compiler.
Why don't you just use the $< automatic variable, then you don't have to worry about this?
%.ml %.mli: %.mly
$(OCAMLYACC) $<
%.ml: %.mll
$(OCAMLLEX) $<
%.cmi: %.mli
$(OCAMLC) $(OCAMLFLAGS) -c $<
%.cmo: %.ml
$(OCAMLC) $(OCAMLFLAGS) -c $<

Related

MakeFile can't run command 'rm'

I made this MakeFile for a project in C lang:
CC = g++
CFLAGS = -c -std=c99 -g
LDFLAGS = -g
SRC = ${wildcard src/*.c}
HDR = ${wildcard include/*.h}
OBJ = ${SRC:.c=.o}
EXEC = reaper
all: ${SRC} ${OBJ} ${EXEC}
${EXEC}: ${OBJ}
${CC} ${LDFLAGS} $^ -o $#
%.o: %.c ${HDR}
${CC} ${CFLAGS} $< -o $#
clean:
rm src/*.o ${EXEC}.exe
when I run make clean gives me this Error:
rm src/*.o reaper.exe
process_begin: CreateProcess(NULL, rm src/*.o reaper.exe, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [Makefile:18: clean] Error 2
How can I fix it?

Issue with Makefile recipe for inputting object files

I have a makefile, that I edited so that object files should go to a separate directory.
I edited the makefile and it is now doing what I wanted to, but during linker stage it is not working as expected because I am doing something wrong.
I have a sources file and makefile as shown below:
Sources File
TARGET = demo
SRC_DIR = modbus/ascii/ \
modbus/functions/ \
modbus/port/ \
modbus/rtu/ \
modbus/ \
./
INCLUDE_DIR = modbus/include/ \
modbus/port/ \
modbus/rtu \
modbus/ascii \
./
SOURCE = modbus/ascii/mbascii.c \
modbus/functions/mbfunccoils.c \
modbus/functions/mbfuncdiag.c \
modbus/functions/mbfuncdisc.c \
modbus/functions/mbfuncholding.c \
modbus/functions/mbfuncinput.c \
modbus/functions/mbfuncother.c \
modbus/functions/mbutils.c \
modbus/port/port.c \
modbus/port/portevent.c \
modbus/port/portserial.c \
modbus/port/porttimer.c \
modbus/rtu/mbcrc.c \
modbus/rtu/mbrtu.c \
modbus/mb.c \
demo.c \
startup_LPC17xx.c \
system_LPC17xx.c
Makefile
include ./sources
ARCH = arm-none-eabi
BUILD_DIR := build/objs
# Tool definitions
CC = $(ARCH)-gcc
LD = $(ARCH)-gcc
AR = $(ARCH)-ar
AS = $(ARCH)-as
CP = $(ARCH)-objcopy
OD = $(ARCH)-objdump
SIZE = $(ARCH)-size
RM = rm
Q = # #./quiet "$#"
# Flags
CFLAGS = -W -Wall -O0 --std=gnu99 -fgnu89-inline -mcpu=cortex-m3 -mthumb
CFLAGS += -ffunction-sections -fdata-sections
ASFLAGS =
LDFLAGS = -nostartfiles -specs=nosys.specs
CPFLAGS =
ODFLAGS = -x --syms
PRFLAGS ?=
# Source files
LINKER_SCRIPT = LPC17xx.ld
OBJS = $(SOURCE:.c=.o)
BUILD_OBJS := $(patsubst %,$(BUILD_DIR)/%,$(SOURCE:.c=.o))
OBJ_DIR := $(dir $(BUILD_OBJS))
INC_PARAMS = $(foreach d, $(INCLUDE_DIR), -I$d)
print-% : ; #echo $* = $($*)
.PHONY: all size clean nuke
all: $(TARGET).bin $(TARGET).hex
isp: $(TARGET).bin
# #./quiet $< cp $^ $(MBED_VOLUME)/
size: $(TARGET).elf
#$(SIZE) $<
%.hex: %.elf
$Q $(CP) $(CPFLAGS) -O ihex $< $*.hex
%.bin: %.elf
$Q $(CP) $(CPFLAGS) -O binary $< $*.bin
$(TARGET).elf: $(OBJS)
#touch $(#:.elf=.map)
$Q $(LD) -Xlinker -Map $(#:.elf=.map) $(LDFLAGS) -T $(LINKER_SCRIPT) $(BUILD_DIR)/$^ -o $#
$Q $(OD) $(ODFLAGS) $# > $(#:.elf=.dump)
#$(SIZE) $#
$(OBJS): %.o: %.c
mkdir -p $(dir $(BUILD_OBJS))
$Q $(CC) $(CFLAGS) $(INC_PARAMS) -c $< -o $(BUILD_DIR)/$#
.PHONY: clean
clean: CRUFT=$(shell find . -name '*.o' -o -name '*.d')
clean: ; rm -f $(CRUFT); rm -f *.elf *.hex *.bin *.dump *.map; rm -rf $(BUILD_DIR)/*
nuke: clean
-rm -f *.hex *.bin *.dump *.map
The issue is in line:
$Q $(LD) -Xlinker -Map $(#:.elf=.map) $(LDFLAGS) -T $(LINKER_SCRIPT) $(BUILD_DIR)/$^ -o $#
For which the output is:
arm-none-eabi-gcc -Xlinker -Map demo.map -nostartfiles -specs=nosys.specs -T LPC17xx.ld build/objs/modbus/ascii/mbascii.o modbus/functions/mbfunccoils.o modbus/functions/mbfuncdiag.o modbus/functions/mbfuncdisc.o modbus/functions/mbfuncholding.o modbus/functions/mbfuncinput.o modbus/functions/mbfuncother.o modbus/functions/mbutils.o modbus/port/port.o modbus/port/portevent.o modbus/port/portserial.o modbus/port/porttimer.o modbus/rtu/mbcrc.o modbus/rtu/mbrtu.o modbus/mb.o demo.o startup_LPC17xx.o system_LPC17xx.o -o demo.elf
The output command picks only the first object file from correct directory under build/objs.
Rest object file path doesn't have build/objs/.
Please anyone help me resolve this issue?
You are violating Mad Scientist's second rule of makefiles, and inviting more problems than you know.
Look at these rules (simplified):
$(TARGET).elf: $(OBJS)
$(LD) $(BUILD_DIR)/$^ -o $#
$(OBJS): %.o: %.c
$(CC) -c $< -o $(BUILD_DIR)/$#
Suppose the build directory is build/ and the object file is build/foo.o. The target of the second rule is foo.o, but what it actually builds is build/foo.o. Likewise, the first rule claims foo.o as a prerequisite, but it doesn't actually use foo.o, it uses build/foo.o These two errors cancel each other out, in a sense; Make succeeds in building the main target. But as you have found, it has trouble if there is more than one object file, because if the prerequisite list is foo.o bar.o, then
`$(BUILD_DIR)/$^`
expands to
build/foo.o bar.o
Also, Make will run the second rule even if build/foo.o exists and is up to date, and will fail to run it if foo.o exists. The target of a non-PHONY rule should be the name of the file it builds, and a non-PHONY prerequisite should be the name of a file whose existence is relevant:
$(TARGET).elf: $(BUILD_OBJS)
$(LD) $^ -o $#
$(BUILD_OBJS): $(BUILD_DIR)/%.o: %.c
$(CC) -c $< -o $#

makefile with 2 executables, how?

My project is organized like this :
src/plateau.c plateau.h tuile.c tuile.h main.c
tests/tests.c
obj/
bin/
I'm trying to do a makefile with 2 executables. I can't figure out why it doesn't works.
The makefile with one executable only works fine, it looks like this :
CC = gcc -Wall -Wextra -ansi
SRCDIR = src
OBJDIR = obj
BINDIR = bin
DOXYGEN = doxygen
all: honshu
honshu: $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o honshu
$(OBJDIR)/plateau.o: $(SRCDIR)/plateau.c $(SRCDIR)/plateau.h
$(CC) -c $(SRCDIR)/plateau.c -o $(OBJDIR)/plateau.o
$(OBJDIR)/tuile.o: $(SRCDIR)/tuile.c $(SRCDIR)/tuile.h
$(CC) -c $(SRCDIR)/tuile.c -o $(OBJDIR)/tuile.o
$(OBJDIR)/main.o: $(SRCDIR)/main.c
$(CC) -c -I src $(SRCDIR)/main.c $# -lm
doxygen:
$(DOXYGEN) -g
$(DOXYGEN) Doxyfile
clean:
rm *.o
rm honshu
And with two executables, I tried like this :
CC = gcc -Wall -Wextra -ansi
SRCDIR = src
OBJDIR = obj
BINDIR = bin
DOXYGEN = doxygen
all: honshu tests
honshu: $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o honshu
tests: $(OBJDIR)/test_honshu.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/test_honshu.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o tests
$(OBJDIR)/plateau.o: $(SRCDIR)/plateau.c $(SRCDIR)/plateau.h
$(CC) -c $(SRCDIR)/plateau.c -o $(OBJDIR)/plateau.o
$(OBJDIR)/tuile.o: $(SRCDIR)/tuile.c $(SRCDIR)/tuile.h
$(CC) -c $(SRCDIR)/tuile.c -o $(OBJDIR)/tuile.o
$(OBJDIR)/main.o: $(SRCDIR)/main.c
$(CC) -c -I src $(SRCDIR)/main.c $# -lm
$(OBJDIR)/test_honshu.o: $(SRCDIR)/test_honshu.c
$(CC) -c -I src $(SRCDIR)/test_honshu.c $# -lm
doxygen:
$(DOXYGEN) -g
$(DOXYGEN) Doxyfile
clean:
rm *.o
rm honshu
But I have the following message "no rules to make "src/test_honshu.c", necessary for "obj.test_honshu.o", do you have an idea ? Thanks !

Makefile issue - target command not excuted

I have the following makefile. When I run "make" or "make all", I get the following output:
make all -n
protoc -I protos/ --cpp_out=protos-gen/ protos//fd.proto
g++-4.9 -O4 -std=c++14 -g -I/usr/local/include -pthread -c -o protos-gen//fd.pb.o protos-gen//fd.pb.cc
protoc -I protos/ --grpc_out=protos-gen/ --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` protos//fd.proto
python -m grpc_tools.protoc -I protos/ --python_out=protos-gen/ --grpc_python_out=protos-gen/ protos//fd.proto
g++-4.9 -O4 -std=c++14 -g -I/usr/local/include -pthread -c -o protos-gen//fd.grpc.pb.o protos-gen//fd.grpc.pb.cc
Issue is: I don't see the following line executed:
$(CXX) $(CXXFLAGS) $(INCLUDE) $(SOURCE_DIR)/fd_server_grpc.cpp $(DLIB_DIR)/dlib/all/source.cpp -DDLIB_JPEG_SUPPORT=1 -DDLIB_PNG_SUPPORT=1 $(LIB) -lzmq -o $(BIN_DIR)/fd_server_grpc
What am I missing?
======================
SOURCE_DIR = src
BUILD_DIR = build
BIN_DIR = bin
DLIB_DIR = ../../3rdparty/dlib/
all: $(BIN_DIR)/fd_server_grpc $(BIN_DIR)/fd_client_grpc
$(BIN_DIR)/fd_server_grpc: $(PROTOS_GEN_PATH)/fd.pb.o
$(PROTOS_GEN_PATH)/fd.grpc.pb.o $(SOURCE_DIR)/fd_server_grpc.cpp
$(DLIB_DIR)/dlib/all/source.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) $(SOURCE_DIR)/fd_server_grpc.cpp
$(DLIB_DIR)/dlib/all/source.cpp -DDLIB_JPEG_SUPPORT=1 -DDLIB_PNG_SUPPORT=1 $(LIB) -lzmq -o $(BIN_DIR)/fd_server_grpc
$(BIN_DIR)/fd_client_grpc: $(PROTOS_GEN_PATH)/fd.pb.o
$(PROTOS_GEN_PATH)/fd.grpc.pb.o $(SOURCE_DIR)/fd_client_grpc.cpp
$(DLIB_DIR)/dlib/all/source.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) $(SOURCE_DIR)/fd_client_grpc.cpp
$(DLIB_DIR)/dlib/all/source.cpp -DDLIB_JPEG_SUPPORT=1 -DDLIB_PNG_SUPPORT=1
$(LIB) -lzmq -o $(BIN_DIR)/fd_client_grpc
.PRECIOUS $(PROTOS_GEN_PATH)/fd.grpc.pb.cc $(PROTOS_GEN_PATH)/fd.pb.cc:
$(PROTOS_GEN_PATH)/fd.pb.o:$(PROTOS_GEN_PATH)/fd.pb.cc
$(PROTOS_GEN_PATH)/fd.pb.cc: $(PROTOS_PATH)/fd.proto
$(PROTOC) -I $(PROTOS_PATH) --cpp_out=$(PROTOS_GEN_PATH) $(PROTOS_PATH)/fd.proto
$(PROTOS_GEN_PATH)/fd.grpc.pb.o:$(PROTOS_GEN_PATH)/fd.grpc.pb.cc
$(PROTOS_GEN_PATH)/fd.grpc.pb.cc: $(PROTOS_PATH)/fd.proto
$(PROTOC) -I $(PROTOS_PATH) --grpc_out=$(PROTOS_GEN_PATH) --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $(PROTOS_PATH)/fd.proto
python -m grpc_tools.protoc -I $(PROTOS_PATH) --python_out=$(PROTOS_GEN_PATH) --grpc_python_out=$(PROTOS_GEN_PATH) $(PROTOS_PATH)/fd.proto
clean:
rm -f $(BUILD_DIR)/* $(BIN_DIR)/* $(PROTOS_GEN_PATH)/*
I figured this out. The line $(CXX) did not start with a tab; had 8 spaces instead. Once I introduced tabs, it worked just fine. Thanks all!

addprefix command not recognized in makefile using nmake.exe windows

all: prd.exe
CC=cl
CFLAGS=-O2 -I../src -I. /W4
LDFLAGS = /Zi
LIBSRC = $(addprefix ../lib/, \
open.c malloc.c \
) \
$(addprefix ../src/, \
main.c \
) \
helper.c
LIBOBJS = $(LIBSRC:.c=.o)
prd.exe: ../src/main.obj
$(CC) $(LDFLAGS) -Fe$# *.o
../src/main.obj: ../src/main.c
$(CC) $(CFLAGS) $(LIBOBJS) -c $< -Fo $#
.c.o:
$(CC) $(CFLAGS) $(LIBOBJS) -c $< -Fo $#
.c.i:
$(CC) $(CFLAGS) $(LIBOBJS) -C -E $< > $#
clean:
del /s /f /q ..\lib\*.o ..\src\*.o *.o *.exe *.pdb
distclean: clean
I get this error
fatal error U1000: syntax error : ')' missing in macro invocation at line 6
Am i missing something here? nmake does recognize addprefix, right?
No, addprefix is a GNU make extension. You have a GNUmakefile that requires GNU make (gmake) to process.
Alternatively, you could rewrite the GNU makefile to not use GNU extensions. In your case this should be easy:
LIBSRC = $(addprefix ../lib/, \
open.c malloc.c \
) \
$(addprefix ../src/, \
main.c \
) \
helper.c
becomes
LIBSRC = ../lib/open.c ../lib/malloc.c ../src/main.c helper.c

Resources