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

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

Related

How is this makefile rule called?

I have made a basic makefile which is supposed to compile my library. It goes like this :
NAME = mylib.a
CC = gcc
FLAGS = -Wall -Wextra -Werror
LIB_SRCS = $(shell find . -type f | grep -F ".c")
LIB_OBJ = $(notdir $(LIB_SRCS:%.c=%.o))
OBJ_DIR = obj/
HEADERS_DIR = ./includes
.PHONY: all
all: $(NAME)
.PHONY: $(NAME)
$(NAME):
#$(CC) $(FLAGS) -c $(LIB_SRCS) -I $(HEADERS_DIR)
#mkdir -p $(OBJ_DIR)
#mv $(LIB_OBJ) $(OBJ_DIR)
#ar rc $(NAME) $(addprefix $(OBJ_DIR), $(LIB_OBJ))
#ranlib $(NAME)
It works pretty well, except that when I use my lib for any project, it recompiles all the files (even when I haven't changed any source from the lib).
I've read this : (Makefile compiles all the files everytime) but it's said I have to create a rule for every source file (or group of source files), which I don't want since there is a lot of source files. I wanted only one rule that compiles file by file.
So I've googled a bit and found a makefile that recompiles only the sources that were modified. And it goes like this :
NAME = mylib.a
CC = gcc
FLAGS = -Wall -Wextra -Werror
INCLUDES = includes/
SRCS_DIR = srcs
OBJ_DIR = obj
ITEMS = $(shell find $(SRCS_DIR) -type f | grep -F ".c" | sed 's/$(SRCS_DIR)//g')
SRCS = $(addprefix $(SRCS_DIR), $(ITEMS))
OBJ = $(addprefix $(OBJ_DIR), $(ITEMS:%.c=%.o))
SRCSUBS = $(shell find $(SRCS_DIR) -type d)
OBJ_SUBDIR = $(SRCSUBS:$(SRCS_DIR)%=$(OBJ_DIR)%)
.PHONY: all
all: $(NAME)
$(OBJ_DIR)/%.o:$(SRCS_DIR)/%.c
#$(CC) $(FLAGS) -o $# -c $< -I $(INCLUDES)
$(OBJ_SUBDIR):
#mkdir $#
.PHONY: $(NAME)
$(NAME): $(OBJ_SUBDIR) $(OBJ)
#ar rc $(NAME) $(OBJ)
#ranlib $(NAME)
It works exactly as expected.
Since I didn't understand everything, I've read about automatic variables and managed to understand almost everything.
I just don't get how the rule that compiles $(OBJ_DIR)/%.o:$(SRCS_DIR)/%.c is called from the $(NAME) $(OBJ_SUBDIR) $(OBJ) rule.
Could anyone explain me how this rule is called since there is no mention to it from the "default" rule called when I execute make command (all: $(NAME)) ?

No rule to make target *, needed by *

I can't get what's wrong with my makefile:
DIST_PATH = ../dist/libs
BUILD_PATH = ../build
MKDIR_P = mkdir -p
.PHONY: all
SHELL = /bin/sh
CC = gcc
FLAGS = -std=gnu99
CFLAGS = -fPIC -pedantic -Wall -Werror
LDFLAGS = -shared
LOG_SRCS = $(shell echo log/*.c)
LOG_HEADERS = $(shell echo log/*.h)
LOG_OBJS = $(addprefix $(BUILD_PATH)/, $(notdir $(LOG_SRCS:.c=.o)))
LOG_TARGET = $(DIST_PATH)/liblog.so
all: dirs $(LOG_TARGET)
dirs :
$(MKDIR_P) $(DIST_PATH)
$(MKDIR_P) $(BUILD_PATH)
$(LOG_TARGET) : $(LOG_OBJS)
$(CC) $(FLAGS) $(CFLAGS) -o $# $(LDFLAGS)
I need to build a shared library from sources in log/ folder to ../dist/libs and put obj file in ../build but I am getting the error:
make: *** No rule to make target '../build/log.o', needed by '../dist/libs/liblog.so'. Stop.
P.S. I know there are many similar questions but I couldn't get from these questions how to resolve my problem.
The problem is that the source and object files are supposed to be placed in different directories, and there's no implicit rule for that.
You need to add a rule for how to translate a source file to an object file:
$(BUILD_PATH)/%.o: log/%.c
Now make knows how to create the object files from the source files.
There's another problem though:
$(LOG_TARGET) : $(LOG_OBJS)
$(CC) $(FLAGS) $(CFLAGS) -o $# $(LDFLAGS)
The command doesn't list any input files, you need to add all the object files to be linked:
$(LOG_TARGET) : $(LOG_OBJS)
$(CC) $(FLAGS) $(CFLAGS) -o $# $^ $(LDFLAGS)
# ^^
# List of all "prerequisites" (object files) to be linked

*** missing separator make error

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

How to remove Makefile Dependency on C file

I have the below Makefile and for some reason it's dependent on a file, ewapi.c. This file executes some SWIG commands and uses the ewapi.i file. I've clear out all the contents of ewapi.c and the Makefile successfully runs. If I remove the ewapi.c file the make file will not complete. The exception stack is below if that helps. Any ideas on how to change the Makefile so its not dependent on ewapi.c?
# BUILD_DIR and DIST_DIR are exported by build.xml
#
CMODE=
SWIG = swig
CC = $(PREFIX)gcc
LD = $(CC)
OBJ_DIR = $(BUILD_DIR)/obj
AUTOGEN_DIR = $(BUILD_DIR)/auto-generated
PACKAGE_DIR = $(AUTOGEN_DIR)/com/sample/jni
PACKAGE = com.sample.jni
INCLUDES = -I$(JAVA_INCLUDE) \
-I$(SAMPLE_SDK_DIR)/include \
-I$(JDK_HOME)/include
LIB_INCLUDES = -L$(SAMPLE_SDK_DIR)/lib
LIBS = /lib/libssl.so.4 \
/lib/libcrypto.so.4 \
-lSampleApi \
-lm
DIRS = $(PACKAGE_DIR) $(DIST_DIR) $(OBJ_DIR) $(AUTOGEN_DIR)
CFLAGS = $(CMODE) -Wall -fpic $(INCLUDES) -O0 -g3
SFLAGS = -java $(INCLUDES) -package $(PACKAGE) -outdir $(PACKAGE_DIR)
LDFLAGS = -shared $(LIB_INCLUDES) $(LIBS)
OBJECTS = $(OBJ_DIR)/ewapi_wrap.o $(OBJ_DIR)/ewapi.o
TARGET = $(DIST_DIR)/libSample.so
all: $(DIRS) $(TARGET)
%_wrap.c: %.i
$(SWIG) $(SFLAGS) $<
$(OBJ_DIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
$(TARGET): $(OBJECTS)
$(LD) $(OBJECTS) $(LDFLAGS) -o $#
$(DIRS):
mkdir -p $#
clean:
rm -rf $(TARGET) $(PACKAGE_DIR)/* $(TARGET) $(AUTOGEN_DIR) $(OBJ_DIR)
Exception Stack (when I remove ewapi.c):
[exec] rm ewapi_wrap.c
[exec] make-3.79.1-p7: *** No rule to make target `/test/build/obj/ewapi.o', needed by `/test/dist/libSample.so'. Stop.
The macros OBJECTS includes $(OBJ_DIR)/ewapi.o; the rule for $(TARGET) says it depends on $(OBJECTS); and the rule for all says it depends on $(TARGET). So, there needs to be a way to create ewapi.o from something - and in the absence of ewapi.c, there is no way to build ewapi.o, hence the complaint you get.
Possible fixes:
Replace ewapi.c.
Remove ewapi.o from the macro $(OBJECTS).
Remove $(OBJ_DIR)/ewapi.o from OBJECTS.

Creating a FORTRAN makefile

I have a FORTRAN source code consisting of many different .F and .h files. I need to build an executable from it, but I'm having some problems. The makefile that I produced so far (which may have errors as I'm new to this) is:
# compiler
FC = /usr/bin/gfortran-4.5
# compile flags
FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons
# link flags
FLFLAGS = -g -fbacktrace
# source files and objects
SRCS = $(patsubst %.F, %.o, $(wildcard *.F)) \
$(patsubst %.h, %.mod, $(wildcard *.h))
# program name
PROGRAM = blah
all: $(PROGRAM)
$(PROGRAM): $(SRCS)
$(FC) $(FCFLAGS) $# $<
%.o: %.F
$(FC) $(FLFLAGS) -o $# $<
%.mod: %.h
$(FC) $(FLFLAGS) -o $# $<
clean:
rm -f *.o *.mod
When I try to make the program, however, I'm getting a slew of undefined reference errors. I mean, every function and subroutine call in the very first compiled .F file gives back an undefined reference error. I thought this was because gfortran was trying to link the files instead of just compiling them and then linking at the end, but I thought the '-c' option was supposed to prevent that.
UPDATE:
As commenters have pointed out, I mixed up the compile and link flags. Furthermore, you shouldn't compile *.h files. Here is the latest, corrected makefile:
# compiler
FC = /usr/bin/gfortran-4.4
# compile flags
FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons -fbounds-check -std=legacy
# link flags
FLFLAGS =
# source files and objects
SRCS = $(patsubst %.F, %.o, $(wildcard *.F))
# program name
PROGRAM = blah
all: $(PROGRAM)
$(PROGRAM): $(SRCS)
$(FC) $(FLFLAGS) -o $# $<
%.o: %.F
$(FC) $(FCFLAGS) -o $# $<
clean:
rm -f *.o *.mod
Now when I run make, it will compile each *.F file in the code, but it fails at the linking stage. I get a bunch of undefined reference errors in the very first *.F file. The compiler seems to be going over each *.F file individually in the linking stage, which I'm not sure is correct. Then I get an error:
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/libgfortranbegin.a(fmain.o): In function `main':
(.text+0x26): undefined reference to `MAIN__'
collect2: ld returned 1 exit status
However, if I type the command:
gfortran -o blah *.o
The executable will be built, so it seems like I did something wrong in the makefile for the linking stage.
UPDATE: 5/9/2011
Sverre pointed out the final problem with my makefile. In my first target that builds the program, I use the shortcut command for only the first dependency ($<), but I need to include all dependencies (i.e. all *.o files) using the ($^) shortcut. The final, working makefile is as follows:
# compiler
FC := /usr/bin/gfortran-4.5
# compile flags
FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons -fbounds-check
# link flags
FLFLAGS =
# source files and objects
SRCS = $(patsubst %.F, %.o, $(wildcard *.F))
# $(patsubst %.h, %.mod, $(wildcard *.h))
# program name
PROGRAM = vipre
all: $(PROGRAM)
$(PROGRAM): $(SRCS)
$(FC) $(FLFLAGS) -o $# $^
%.o: %.F
$(FC) $(FCFLAGS) -o $# $<
# %.mod: %.h
# $(FC) $(FCFLAGS) -o $# $<
clean:
rm -f *.o *.mod
Are you using GNU make? If so,
$(FC) $(FLFLAGS) -o $# $<
may be the culprit. $< is the name of the first prerequisite, but you want all the *.o files. Try using $^ instead.

Resources