*** missing separator make error - makefile

I have tried to create a makefile to compile my C program. However, when I execute the make command in the terminal I keep getting this error:
makefile:7: *** missing separator. Stop.
This is my makefile:
CC= gcc -Wall
LIBS = -lm
HEADER_FILES_DIR = ./headerFiles
INCLUDES = -I $(HEADER_FILES_DIR)
MAIN= ejecutable
SRCS = asignarElemento.c destruyeMatriz.c main.c prodEscalar.c suma.c
creaMatriz.c imprimeMatriz.c obtenerElemento.c producto.c
DEPS = $(HEADER_FILES_DIR)/matriz.h
OBJS = $(SRCS:.c=.o)
$(MAIN): $(OBJS)
$(CC) -o $(MAIN) $(OBJS) $(LIBS)
%.o: %.c $(DEPS)
$(CC) -c $< $(INCLUDES)
I have tried substituting the tabs by \t, changing the location of my header file... but I don't get it to work. The project does compile on Netbeans and Visual Studio, so it has to be a makefile problem.
How can I fix it?

It looks like your sources need to continue on the same line using the \ character
SRCS = asignarElemento.c destruyeMatriz.c main.c prodEscalar.c suma.c \
creaMatriz.c imprimeMatriz.c obtenerElemento.c producto.c

Related

How can my makefile include subdirectories?

(updated for clarity) (solution added at bottom)
I found a makefile online which builds all the cpp files in that directory and compiles them.
But I can't work out how I can include files inside a subdirectory.
Here's a breakdown of what happens:
I create the files test.cpp & test.hpp and place them inside the sub-directory '/gui' which is contained within my working directory, they contain the function testFunction().
Without including test.hpp, I type "make" into terminal and I receive the error:
:
g++ -c -o main.o main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:6:2: error: 'testFunction' was not declared in this scope
testFunction();
^~~~~~~~~~~~
make: *** [<builtin>: main.o] Error 1
If I include (#include "gui/test.hpp"), I then receive a different error:
:
g++ -c -o main.o main.cpp
g++ main.o -Wall -o testfile
/usr/bin/ld: main.o: in function `main':
main.cpp:(.text+0x14): undefined reference to `testFunction()'
collect2: error: ld returned 1 exit status
make: *** [makefile:34: testfile] Error 1
But if I then add "-I/gui" or (at a guess) "-I./gui" to CFLAGS, I get the exact same error message.
Here's the makefile for reference:
TARGET = testfile
LIBS =
CC = g++
CFLAGS = -g -Wall
.PHONY: default all clean
default: $(TARGET)
all: default
OBJECTS = $(patsubst %.cpp, %.o, $(wildcard *.cpp))
HEADERS = $(wildcard *.hpp)
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $#
.PRECIOUS: $(TARGET) $(OBJECTS)
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -Wall $(LIBS) -o $#
clean:
-rm -f *.o
-rm -f $(TARGET)
Thanks in advance!
Updated makefile since accepted answer:
(Changes were to include directories, CC replaced with CXX, and %.c replaced with %.cpp)
TARGET = testfile
DIRS =
LDLIBS =
CXX = g++
CXXFLAGS= -g -Wall
# this ensures that if there is a file called default, all or clean, it will still be compiled
.PHONY: default all clean
default: $(TARGET)
all: default
# substitute '.cpp' with '.o' in any *.cpp
OBJECTS = $(patsubst %.cpp, %.o, $(wildcard *.cpp $(addsuffix /*.cpp, $(DIRS))))
HEADERS = $(wildcard *.h)
# build the executable
%.o: %.cpp $(HEADERS)
$(CXX) $(CXXFLAGS) -c $< -o $#
# if make is interupted, dont delete any object file
.PRECIOUS: $(TARGET) $(OBJECTS)
# build the objects
$(TARGET): $(OBJECTS)
$(CXX) $(OBJECTS) -Wall $(LDLIBS) -o $#
clean:
-rm -f *.o $(addsuffix /*.o, $(DIRS))
-rm -f $(TARGET)
To understand what's happening here you have to look up the definitions of declaration versus definition in C++ (and other languages). You should definitely do that.
A declaration (typically put into a header file) is like the address of your house. If someone wants to send you a letter, they need your address. If your main function wants to call another function like testFunction(), it needs the declaration of the function.
The first error happens because you don't have the header file included, so the compiler doesn't have the declaration of the function you want to call, which means it won't compile your calling function.
But for the letter to actually arrive, you need your actual house. The address is the declaration and your house is the definition... in this case the actual function implementation. That lives in test.cpp file. When you link your code together, the linker (in this scenario I guess the linker is like the postal service :p :) ) will try to link up the call to the definition.
However, you can see that you are not compiling the test.cpp file nor are you linking the object file:
g++ main.o -Wall -o testfile
here we see main.o, but not gui/test.o.
Why not? This line:
OBJECTS = $(patsubst %.cpp, %.o, $(wildcard *.cpp))
Matches all *.cpp files and converts them into .o files. But *.cpp matches only files in the current directory, like main.cpp. If you want to put files in a different directory you have to tell make where they are; for example:
OBJECTS = $(patsubst %.cpp, %.o, $(wildcard *.cpp gui/*.cpp))

Makefile: Unable to add .h files from folder using a .mk file

I'm trying to link a .h file from a folder into a Makefile using a .mk file. Folder with .h file (include) is in the same folder as Makefile.
When I run from terminal: make memory.o or make memory.o PLATFORM=MSP432 I get the following error
make: *** No rule to make target '-I./include', needed by 'memory.o'. Stop.
My .mk folder looks like this:
# Add your Source files to this variable
SOURCES = \
./main.c \
./memory.c
# Add your include paths to this variable
INCLUDES =-I./include
My Make file looks like this:
include sources.mk
# Platform Overrides
PLATFORM =
# Architectures Specific Flags
LINKER_FILE = msp432p401r.lds
CPU = cortex-m0plus
ARCH = thumb
SPECS = nosys.specs
# Compiler Flags and Defines
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
TARGET= c1m2
LDFLAGS = -Wl, -Map=$(TARGET).map -T $(LINKER_FILE)
CFLAGS = -Wall -Werror -g -O0 -std=c99 -mcpu=$(CPU) -m$(ARCH) --specs=$(SPECS)
CPPFLAGs =
ifeq ($(PLATFORM),MSP)
CPU=cortex-m4
CC=arm-none-eabi-gcc
endif
ifeq ($(PLATFORM),HOST)
CC=gcc
endif
OBJS = $(SOURCES:.c=.o)
%.o : %.c $(INCLUDES)
$(CC) -c $< $(CFLAGS) -o $#
.PHONY: build
build: all
.PHONY: all
all: $(TARGET).out
$(TARGET).out: $(OBJS) $(INCLUDES)
$(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) -o $#
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET).out $(TARGET).map
Can anybody help?
You shouldn't put $(INCLUDES) as a prerequisite of your .o file. This is not right:
%.o : %.c $(INCLUDES)
$(CC) -c $< $(CFLAGS) -o $#
INCLUDES contains options that need to be passed to the compiler (-I...). Prerequisites of targets need to be files that are used during the build. I suppose you want this:
%.o : %.c
$(CC) -c $< $(CFLAGS) $(INCLUDES) -o $#

Why do I get an "Unterminated quoted string" error?

This is my makefile for a particular C++ project, but when I run make all, I get:
/bin/sh: 1: Syntax error: Unterminated quoted string
Makefile:28: recipe for target '"system' failed
make: *** ["system] Error 2
When I change exe to something with no spaces, it works fine.
EDIT #1: The reason I used quotes was so I could use spaces in the output file name.
cc = g++
exe = "system software version 1.0"
src_dir = src
obj_dir = obj
src = $(wildcard $(src_dir)/*.cpp)
obj = $(patsubst $(src_dir)/%.cpp, $(obj_dir)/%.o, $(src))
libs = -lallegro -lallegro_primitives
include_paths = -I "include" -I "~/allegro5/include/"
lib_paths = -L "/usr/lib/"
flags = -Wall -Wextra -Wpedantic -g -std=c++14
all: $(exe)
play: all
$(exe)
$(exe): $(obj)
$(cc) $(lib_paths) $^ $(libs) -o $#
compile_only: $(obj)
$(obj_dir)/%.o: $(src_dir)/%.cpp
$(cc) $(flags) $(include_paths) -c $^ -o $#
clean:
rm -f $(obj_dir)/*.o
build: all
rebuild: clean build
.PHONY: all clean rebuild
You cannot use paths containing whitespace with make. There are crazy tricks that can make some limited things work, but basically it's simply not supported.
See this recent question and answer: https://stackoverflow.com/a/56411000/939557

Makefile error, can't resolve include

I'm working with a project using flex/bison and trying to compile it using make. The lex.yy.c, tab.c, tab.h from flex/bison are generated correctly and placed in the obj directory. However, there is an error when trying to compile the obj/lex.yy.c file and it cannot resolve an include to a file in the src/frontend directory. Any ideas where I am going wrong? Makefile and output included below.
Makefile:
VPATH = src obj src/frontend src/interpreter
SRCS = lex.yy.c C.tab.c symbol_table.c nodes.c print_ast.c interpreter.c main.c
OBJS := $(SRCS:%.c=obj/%.o)
INCLUDES = -Isrc -Iobj -Isrc/frontend -Isrc/interpreter
CPPFLAGS = -Wall
LDFLAGS = -Wall
CC = gcc
LEX = flex
YACC = bison -d -t -v
all: bin/mycc
bin/mycc: $(OBJS)
$(CC) -g $(LDFLAGS) $(INCLUDES) -o $# $^
obj/lex.yy.c: C.flex obj/C.tab.h
$(LEX) -o $# $<
obj/C.tab.c: C.y
$(YACC) -o $# $<
obj/C.tab.h: obj/C.tab.c
#touch $#
obj/%.o: src/%.c
$(CC) -g $(CPPFLAGS) $(INCLUDES) -c $^
clean:
rm $(OBJS) obj/lex.yy.c obj/C.tab.c obj/C.tab.h
depend:
$(CC) -M $(SRCS) > .deps
cat Makefile .deps > makefile
Output:
bison -d -t -v -o obj/C.tab.c src/frontend/C.y
src/frontend/C.y: conflicts: 4 shift/reduce, 14 reduce/reduce
src/frontend/C.y:248.11-53: warning: rule useless in parser due to conflicts: external_declaration: function_definition
flex -o obj/lex.yy.c src/frontend/C.flex
gcc -Wall -c -o obj/lex.yy.o obj/lex.yy.c
src/frontend/C.flex:13:19: fatal error: token.h: No such file or directory
#include "token.h"
^
compilation terminated.
make: *** [obj/lex.yy.o] Error 1
The problem is that you define your -I flags for compiling in the variable $(INCLUDES) instead of in the normal $(CPPFLAGS). As a result, when the default rule for compiling C files runs, it does not use any of those -I flags and so the compiler can't find the include files. You can see the command line for the compiler in your output.
To fix it, get rid of the INCLUDES = line and add all of them to CPPFLAGS:
CPPFLAGS = -Wall -Isrc -Iobj -Isrc/frontend -Isrc/interpreter

My Makefile is trying to compile a non-exsistent/made up filename

This is my VERY FIRST Makefile and so I have cut and paste junk I have found all over the web. My directory structure is pretty flat and was not thought out for Makefiles. It is:
Project/
Project/Control
Project/NodeMgmt
Project/Common
Project/Interfaces
I am writing a Makefile for Control and would like it to standalone inside Control. It needs to include compile and include from Common & Interfaces. Here's my Makefile:
CC = g++
CFLAGS = -Wall -c
INCLUDES = -I/usr/local/include -I/SuperCool/Ion-1.0.0-snapshot-1/include -I/SuperCool/FastrakSDK-4.0.1-snapshot-1/include/Fastrak/Engine/Core/CoreIpc -I/Projects/Common -I/Projects/Interfaces -I/Projects/NodeMgmt -I/Projects/Controller
LFLAGS = -L/usr/local/lib -L/SuperCool/FastrakSDK-4.0.1-snapshot-1/lib
LIBS = -lCoreIpc4 -lIonOs
VPATH = ../Interfaces/
VPATH = ../Common/
VPATH = ../NodeMgmt/
SRCS = *.cc
OBJS = $(SRCS:.cc=.o)
MAIN = controller
.PHONY: clean
all: $(MAIN)
#echo Built Controller
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
.cc.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
clean:
$(RM) *.o $(MAIN)
It's compiling the first .cc file it finds "-c Controller.cc -o *.o" which make sense but that's all it's compiling and I get a *.o output file, not a Controller.o file. It does not compile any other files.
Here's one problem:
SRCS = *.cc
Make doesn't understand wildcards without the wildcard function:
SRCS = $(wildcard *.cc)
That should get it working; we can make minor improvements later.

Resources