Why does make not find the file specified? - c

I am writing a makefile in which everything works if I type it into git bash, but when trying to use the command through make, it wont work.
Makefile
CC ?= gcc
CFLAGS ?= -Wall
INCLUDE_DIR ?= src/headers
TARGET_EXEC ?= o.exe
SRC_DIR ?= src
BIN_DIR ?= bin
SRCS := $(wildcard $(SRC_DIR)/*.c)
OBJS := $(addprefix $(BIN_DIR)/, $(notdir $(SRCS:%.c=%.o)))
.PHONY: all
all: $(OBJS)
$(CC) $(OBJS) -o $(BIN_DIR)/$(TARGET_EXEC)
$(BIN_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $# -I$(INCLUDE_DIR)
Console output
process_begin: CreateProcess(NULL, cc -Wall -c src/main.c -o bin/main.o -Isrc/headers, ...) failed.
make (e=2): The system cannot find the file specified.
makefile:17: recipe for target 'bin/main.o' failed
mingw32-make: *** [bin/main.o] Error 2
I have already tried reinstalling git, vscode, mingw. I have also tried removing
enviroment variables.
I also stumbled onto this answer: Makefile error make (e=2): The system cannot find the file specified
Which also did not work for me.
I have also checked which shell is being used by typing echo $(SHELL), which outputs sh.exe

Thanks to #Barmar and #teapos418, I found the answer.
The file not found was indeed CC, because the variable $(CC) was declared by using CC ?= gcc, wich is not the right use case. Changing it to CC = gcc fixed the problem.
makefile manual: https://www.gnu.org/software/make/manual/html_node/Setting.html

Related

ld: can't open output file for writing [duplicate]

I'm trying to compile my code on OSX El Capitan. This is my Makefile
TARGET = proj_name
CC = gcc
# compiling flags
CFLAGS = -std=c99 -Wall -I.
LINKER = gcc -o
# linking flags
LFLAGS = -Wall -I. -lm
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SOURCES := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm = rm -f
$(BINDIR)/$(TARGET): $(OBJECTS)
#$(LINKER) $# $(LFLAGS) $(OBJECTS)
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) -c $< -o $#
#echo "Compiled "$<" successfully!"
.PHONEY: clean
clean:
#$(rm) $(OBJECTS)
#echo "Cleanup complete!"
.PHONEY: remove
remove: clean
#$(rm) $(BINDIR)/$(TARGET)
#echo "Executable removed!"
I keep getting the following error while compiling on El Capitan
ld: can't open output file for writing: bin/proj, errno=2 for architecture x86_64
I understand that its a linker issue, but if someone could help me amending the Makefile, it would really help.
Errno 2 means (google for something like errno list):
#define ENOENT 2 /* No such file or directory */
bin/proj is relative path.
Looking at the Makefile, the most likely cause seems to be, bin directory simply does not exist. ld will not try create it if it is not there. To fix, add
mkdir -p $(BINDIR)
before $(LINKER) line (-p switch allows creating a path if it does not exist, which in this case prevents error if bin already exists).
A side note: Another common cause with relative paths is, that working directory is not what you think it is, when ld is run. Adding command like pwd to before $(LINKER) command would help troubleshooting this. But looking at Makefile, this probably is not the reason here.

Trying to compile zbspac.exe with MinGW Distro

I am using this Git for Zbspac.exe
https://github.com/uyjulian/zbspac
And the following for my MinGW Distro:
https://nuwen.net/mingw.html
I have a MinGW distro set up to target my zbspac.exe Makefile. However, I keep getting bounced for
make (e=2): The system cannot find the file specified.
make: *** [Makefile:25: BitStream.o] Error 2
I have BitStream.c and Bitstream.h in the main directory, but it seems the object file doesn't register for the Distro. I feel that it's going to be the same for all the other object files.
My first idea was to create a duplicate file for each .c file into a .o file. This helped clear the issues relating to the .o not being found (although, this solution is probably not ideal). Is there a way to fix this (besides creating duplicate files)?
It then gives me the error
i686-w64-mingw32-gcc -o zbspac.exe BitStream.o ByteArray.o CmdArgs.o FileSystem.o HuffmanDecoder.o HuffmanEncoder.o Logger.o LzssDecoder.o LzssEncoder.o MinHeap.o NexasPacker.o NexasUnpacker.o ScriptPacker.o ScriptUnpacker.o StringUtils.o zbspac.o external/zlib/adler32.o external/zlib/compress.o external/zlib/crc32.o external/zlib/deflate.o external/zlib/gzclose.o external/zlib/gzlib.o external/zlib/gzread.o external/zlib/gzwrite.o external/zlib/infback.o external/zlib/inffast.o external/zlib/inflate.o external/zlib/inftrees.o external/zlib/trees.o external/zlib/uncompr.o external/zlib/zutil.o -static -static-libstdc++ -static-libgcc
process_begin: CreateProcess(NULL, i686-w64-mingw32-gcc -o zbspac.exe BitStream.o ByteArray.o CmdArgs.o FileSystem.o HuffmanDecoder.o HuffmanEncoder.o Logger.o LzssDecoder.o LzssEncoder.o MinHeap.o NexasPacker.o NexasUnpacker.o ScriptPacker.o ScriptUnpacker.o StringUtils.o zbspac.o external/zlib/adler32.o external/zlib/compress.o external/zlib/crc32.o external/zlib/deflate.o external/zlib/gzclose.o external/zlib/gzlib.o external/zlib/gzread.o external/zlib/gzwrite.o external/zlib/infback.o external/zlib/inffast.o external/zlib/inflate.o external/zlib/inftrees.o external/zlib/trees.o external/zlib/uncompr.o external/zlib/zutil.o -static -static-libstdc++ -static-libgcc, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [Makefile:22: zbspac.exe] Error 2
, which is a self-referential error, since I want to be compiling zbspac.exe, not referring to it.
For reference, the Makefile, which has not been edited:
EXE_TARGET = zbspac.exe
TXTS = License.txt Readme.txt Instructions.txt PackageFormat.txt ScriptTxtFormat.txt
PROJECT_FILE = Makefile .project .cproject
SRC_DIST = zbspac-src.7z
BIN_DIST = zbspac-bin.7z
CC = i686-w64-mingw32-gcc
LD = i686-w64-mingw32-ld
CFLAGS = -O2 -std=c99 -Werror -Wall -pedantic -pedantic-errors -Iexternal/zlib
LIBS = -static -static-libstdc++ -static-libgcc
DIST_MAKE = 7za a
ZLIB_SRCS = external/zlib/adler32.c external/zlib/compress.c external/zlib/crc32.c external/zlib/deflate.c external/zlib/gzclose.c external/zlib/gzlib.c external/zlib/gzread.c external/zlib/gzwrite.c external/zlib/infback.c external/zlib/inffast.c external/zlib/inflate.c external/zlib/inftrees.c external/zlib/trees.c external/zlib/uncompr.c external/zlib/zutil.c
SRCS = $(wildcard *.c) $(ZLIB_SRCS)
HEADERS = $(wildcard *.h)
OBJS = $(patsubst %.c, %.o, $(SRCS))
all: $(EXE_TARGET)
$(EXE_TARGET): $(OBJS)
$(CC) -o $(EXE_TARGET) $(OBJS) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $# $<
src_dist: $(SRC_DIST)
bin_dist: $(BIN_DIST)
$(SRC_DIST): $(SRCS) $(HEADERS) $(TXTS) $(PROJECT_FILE)
$(DIST_MAKE) $(SRC_DIST) $(SRCS) $(HEADERS) $(TXTS) $(PROJECT_FILE)
$(BIN_DIST): $(EXE_TARGET) $(TXTS)
$(DIST_MAKE) $(BIN_DIST) $(EXE_TARGET) $(TXTS)
.PHONY: clean
clean:
$(RM) $(OBJS) $(EXE_TARGET) $(SRC_DIST) $(BIN_DIST)
How do I solve this?

Makefile Stops Building Files After First .o In Out-of-Source Build

I have a bit of a huge Makefile that basically works as I want it to.
Issue: The problem I'm having is that the makefile only checks if the first .o needs updating and not if any others do. I'm not sure what part of my makefile is in error.
Context: I have project structure like this:
quendor
src
main.c
options.c
quendor.h
Makefile
When my Makefile builds, it constructs a build directory and things look as follows:
quendor
build
src
main.d
main.o
options.d
options.o
src
main.c
options.c
quendor.h
Makefile
To See the Problem: Now let's say I don't change my main.c but I do change my options.c file. In that case, when I run make again I get this:
make: 'build/./src/main.o' is up to date.
I'm not sure if this is because it's building into a build/src directory rather than just build as I intended.
Here is the full Makefile and I'm including all of it just because I'm not sure what might be a problem and I don't want to make unwarranted assumptions.
.PHONY : all clean
NAME := quendor
PLATFORM := windows
CC := gcc
LINK := gcc
BUILD_DIR ?= ./build
SRC_DIR ?= ./src
ifeq ($(PLATFORM), windows)
TARGET ?= quendor.exe
else
TARGET ?= quendor
endif
ifeq ($(CC), gcc)
CFLAGS += -std=c11 -Wall -Wextra -Wpedantic -Wconversion -Wmissing-prototypes -Wshadow -MMD -MP
LDFLAGS +=
OPT +=
endif
SRCS := $(wildcard $(SRC_DIR)/*.c)
OBJS := $(SRCS:%.c=$(BUILD_DIR)/%.o)
DEPS := $(OBJS:%.o=%.d)
MKDIR_P ?= #mkdir -p $(dir $#)
-include $(DEPS)
all : $(TARGET)
#echo "Building $(TARGET)"
$(TARGET) : $(OBJS)
$(LINK) $(OPT) -o $# $^ $(LDFLAGS)
$(BUILD_DIR)/%.o : %.c
$(MKDIR_P)
$(CC) $(CFLAGS) -c $< -o $#
clean:
$(RM) $(TARGET) -r $(BUILD_DIR)
This may be an artifact of how StackOverflow is parsing my Makfile but I do notice that it's showing different syntax highlighting after this line:
SRCS := $(wildcard $(SRC_DIR)/*.c)
The problem is that you are including the dependencies before you define the all rule:
-include $(DEPS)
all : $(TARGET)
If you don't specify a particular target to build on the command line (e.g., if you don't run make all) then make chooses the first explicit target in the makefile (and any included makefiles!!) as the target to build.
I assume that the dependency definitions in the $(DEPS) variable define main.o as a target and since that comes before all, it's the only thing that's run by default.
Move the -include statement later in the makefile (I typically put these all at the end of the makefile) and it will work.

ld: can't open output file for writing: bin/s, errno=2 for architecture x86_64

I'm trying to compile my code on OSX El Capitan. This is my Makefile
TARGET = proj_name
CC = gcc
# compiling flags
CFLAGS = -std=c99 -Wall -I.
LINKER = gcc -o
# linking flags
LFLAGS = -Wall -I. -lm
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SOURCES := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm = rm -f
$(BINDIR)/$(TARGET): $(OBJECTS)
#$(LINKER) $# $(LFLAGS) $(OBJECTS)
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) -c $< -o $#
#echo "Compiled "$<" successfully!"
.PHONEY: clean
clean:
#$(rm) $(OBJECTS)
#echo "Cleanup complete!"
.PHONEY: remove
remove: clean
#$(rm) $(BINDIR)/$(TARGET)
#echo "Executable removed!"
I keep getting the following error while compiling on El Capitan
ld: can't open output file for writing: bin/proj, errno=2 for architecture x86_64
I understand that its a linker issue, but if someone could help me amending the Makefile, it would really help.
Errno 2 means (google for something like errno list):
#define ENOENT 2 /* No such file or directory */
bin/proj is relative path.
Looking at the Makefile, the most likely cause seems to be, bin directory simply does not exist. ld will not try create it if it is not there. To fix, add
mkdir -p $(BINDIR)
before $(LINKER) line (-p switch allows creating a path if it does not exist, which in this case prevents error if bin already exists).
A side note: Another common cause with relative paths is, that working directory is not what you think it is, when ld is run. Adding command like pwd to before $(LINKER) command would help troubleshooting this. But looking at Makefile, this probably is not the reason here.

When I use "gcc" in makefile, after making it, I got a "cc" output

For example:
There are 3 source files {main.c test1.c test2.c} in the directory
and a directory file named test3,
and there is a source file named test.c in the directory of test3.
Now I want to create a makefile to compile and link these four source files.
And this is my Makefile:
# Cancel statement "CC=gcc"
src:=$(wildcard *.c) test3.c
obj:=$(patsubst %.c,%.o,$(src))
main:$(obj)
gcc -o main $(obj)
.PHONY:clean
clean:
rm *.o *~
When I called make to compile them, I got a output like this:
cc -c -o main.o main.c
cc -c -o test1.o test1.c
cc -c -o test2.o test2.c
cc -c -o test3.o test3/test3.c
gcc -o main main.o test1.o test2.o test3.o
I know 'cc' is linked to 'gcc' in Linux.
What I don't understand is why did Make call cc to compile these four source files, but call gcc to link the object files?
You changed one rule: the one that links the program main from the object files. And when make did that link, you can see it used gcc.
You didn't do anything to change the built-in rules that make is using to compile the object files, so they use the default (the value of the variable CC) which is cc.
You wrote only the rule to link the object files, and allowed Make to use its default rule to decide how to build the object files from the source files.
GNU Make will expose its rules if you ask it with --print-data-base. In this case, it tells us
%.o: %.c
# recipe to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
and
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
and finally
CC = cc
This explains why Make uses cc to compile your C sources. To change that, simply set CC = gcc. Here's a complete Makefile which does that and also makes best use of Make's built-in rules, to help when you need to extend it:
src := $(wildcard *.c) test3.c
obj := $(patsubst %.c,%.o,$(src))
CC = gcc
main: $(obj)
$(LINK.c) -o $# $^ $(LDLIBS)
.PHONY: clean
clean:
$(RM) *.o *~

Resources