Error 1: no input files when making a c file - c

I'm trying to compile a c-file with dependencies, using a makefile that gets stuck with this error:
Compiling tpc_lqe.o ...
/cygdrive/c/Sandbox/ZigBee/Tools/ba-elf-ba2/bin/ba-elf-gcc -c -o tpc_lqe.o
[some -options]
-I/cygdrive/c/Sandbox/ZigBee/Components/TPC/Include
-I/cygdrive/c/Sandbox/ZigBee/Components/TPC/Source
-I/cygdrive/c/Sandbox/ZigBee/Components/AppApi/Include
-I/cygdrive/c/Sandbox/ZigBee/Components/Common/Include
-I /cygdrive/c/Sandbox/ZigBee/Components/TPC/Source/tpc_lqe.c -MD -MF tpc_lqe.d -MP
ba-elf-gcc: no input files
make: *** [tpc_lqe.o] Error 1
Makefile:138: recipe for target 'tpc_lqe.o' failed
I saw other questions regarding the same error, but I can't relate to them with my problem.
This is the makefile line that is causing the error, please point out if some context is missing:
%.o: %.c
$(info Compiling $# ...)
$(CC) -c -o $*.o $(CFLAGS) $(INCFLAGS) $< -MD -MF $*.d -MP
Update following unwind's answer:
I didn't include specify a variable (include path of a library), which caused the following inclusion of that variable (INCFLAGS) to contain a blank space in its stead. This blank space ended up in the -I option thus returning the error.
Once defined that variable, everything worked smoothly.

INCFLAGS looks broken, since the compiler invocation has a "bare" -I, without a value immediately following, which causes gcc to interpret the next argument (the source file name) as that argument:
[...] -I /cygdrive/c/Sandbox/ZigBee/Components/TPC/Source/tpc_lqe.c
^
|
???

Related

Handling assembly files in Makefile - include statement problem?

Here are parts of a Makefile:
MY_SRC += \
scr1.c \
src2.c \
src3.c
BUILD_PATH=outdir
MY_OBJ := $(addprefix $(BUILD_PATH)/,$(addsuffix .o, $(MY_SRC)))
MY_DEP := $(MY_OBJ:.c.o=.c.d)
.
.
.
$(BUILD_PATH)/%.c.o: %.c
#echo " CC $<"
$(CC) $< -c $(CFLAGS) $(call MDOPT,$(#:.c.o=.c.d)) -o $#
.
.
.
-include $(MY_DEP)
The MDOPT is defined as MDOPT = -MMD -MF $(1).
I needed to add assembly .asm.ssource files, so I added:
MY_SRC += myfile.asm.s
.
.
.
$(BUILD_PATH)/%.s.o: %.s
#echo " ASM $<"
$(Q)$(CC) $< -c $(CFLAGS) -o $#
However, when trying to compile the sources, it gave me error:
ASM myfile.asm.s out/myfile.asm.s.o:1: *** missing separator. Stop.
I have found the following fix - remove the last line in the Makefile:
-include $(MY_DEP).
What caused the error?
Why did removal of the -include line fix the problem? What is the purpose of this line at all?
What caused the error?
The error message suggests a syntax error in the binary file
out/myfile.asm.s.o. The error isn't detected at include time because
the -include directive was used (try info make include, near the
end). myfile.asm.s is appended to MY_SRC, and out/myfile.asm.s.o
therefore to MY_OBJ and MY_DEP. The binary file gets included
because MY_DEP := $(MY_OBJ:.c.o=.c.d) leaves .s.o intact.
UPDATE: To be more precise about the timeline,
make, on seeing -include $(MY_DEP), decides it can remake the
requested .s.so file from an implicit rule; no errors at this
point, even if it could not be remade
builds the .s.so displaying the output from #echo but not the
$(CC) command line (since $(Q) expands to #, it seems); no errors yet
reads and parses the .s.so as a makefile, fails on line 1, and
terminates with an error message (end UPDATE)
Why did removal of the -include line fix the problem?
It skips reading out/myfile.asm.s.o which isn't a makefile.
What is the purpose of this line at all?
See info make 'Automatic Prerequisites'.
The problem was resolved in two steps:
MY_DEP := $(MY_OBJ:.c.o=.c.d) did not take in the .s assembly files. This was fixed with:
MY_DEP_TEMP := $(MY_OBJ:.c.o=.c.d)
MY_DEP += $(MY_DEP_TEMP:.s.o=.s.d)
Additional target for compiling .s files needed to be changed in order to generate .d files:
$(BUILD_PATH)/%.s.o: %.s
#echo " AS $<"
$(AS) $< -c $(ASFLAGS) $(call MDOPT_ASM,$(#:.s.o=.s.d)) -o $#
Special care needed to be taken with respect to MDOPT_ASM which needed to be defined as MDOPT_AS = -MD $(1), which is different then the one for .c targets (MDOPT_C = -MMD -MF $(1)).

no rule to make target needed by x.o NASM and producing .o file as output. What mean by tthis error -- How to correct it

I am getting error
No rule to make target 'kernel-entry.asm', needed by 'kernel-entry.o'. Stop.
Can .asm file containing assembly instructions get converted to .o file? I did not no
from this page
Makefile: no rule to make target '*.o', needed by '*'. Stop
its say I have to include $(CFLAGS)
After making chages My make file looks like this
# $# = target file
# $< = first dependency
# $^ = all dependencies
# First rule is the one executed when no parameters are fed to the Makefile
CFLAGS= -Wall -g
all: run
kernel.bin: kernel-entry.o kernel.o
ld -m elf_i386 -o $# -Ttext 0x1000 $^ --oformat binary
kernel-entry.o: kernel-entry.asm
nasm $(CFLAGS) $< -f elf -o $#
kernel.o: kernel.c
gcc -m32 -ffreestanding -c $< -o $#
mbr.bin: mbr.asm
nasm $< -f bin -o $#
os-image.bin: mbr.bin kernel.bin
cat $^ > $#
But the error No rule to make target 'kernel-entry.asm', needed by 'kernel-entry.o'. Stop. did not go away. What I am doing wrong?
How to correct the error. Thanks for help
Update
Yes my kernel-entry file was .c I made it .asm and removed -CFLAGS because I was getting invalid NASM flags on CFLAGES Now I am getting this error
warning: overriding recipe for target 'abc.bin'
Makefile:4: warning: ignoring old recipe for target 'abc.bin'
nasm kernel-entry.asm -f elf -o kernel-entry.bin
kernel-entry.asm:2: error: invalid directive line
make: *** [Makefile:11: kernel-entry.bin] Error 1
are -f elf -o in above line are directives? What they are used for. is above error saying that -f elf -o are invalid. what above even means?
This is my make file thats generating error after Update above
all: run
abc.bin:abc.asm
nasm $< -f bin -o $#
kernel.bin: kernel-entry.bin kernel.o
ld -m elf_i386 -o $# -Ttext 0x1000 $^ --oformat binary
kernel-entry.bin: kernel-entry.asm
nasm $< -f elf -o $#
kernel.o: kernel.c
gcc -m32 -ffreestanding -c $< -o $#
abc.bin: abc.asm
nasm $< -f bin -o $#
mbr.bin: mbr.asm
nasm $< -f bin -o $#
os-image.bin: abc.bin mbr.bin kernel.bin
cat $^ > $#
run: os-image.bin
qemu-system-i386 -fda $<
clean:
$(RM) *.bin *.o *.dis
The problem is that, in line 13 of your Makefile you have:
kernel-entry.o: kernel-entry.asm
nasm $(CFLAGS) $< -f elf -o $#
which states how to create (by assembling it with nasm) kernel-entry.o from kernel-entry.asm. By the way, kernel-entry.o is needed to create kernel.bin above in your makefile. But as you don't have kernel-entry.asm, the make utility complains about not being able to create kernel-entry.o because there's no existing source file to generate it (and there is no rule to generate file kernel-entry.asm, in case it could be built automatically).
You lack a source file (an assembler file called kernel-entry.asm) and you have no kernel-entry.o either, so you cannot solve the problem without providing it.
Edit
You say you made an kernel-entry.asm file from your kernel-entry.c file (I cannot guess the reason to do that, but anyway it is not important here) but at some point you lost your kernel-entry.asm file. This is what make is telling you... that it doesn't find the source file (neither kernel-entry.asm nor kernel-entry.c, to generate kernel-entry.o needed to link the final program) You can use any, or even both rules, to generate the .asm file from the .c one, and then provide the C source code.
Anyway, apart of this... the default rule (the first one in your makefile, for target all) shows that it depends on target run, which is not defined anywhere, so if you run just:
make
you will get a similar message about no rule for target run. This is because you say all depends on run, and run depends on nothing, so make assumes run (or kernel-entry.asm) must be provided by the user, or the build will fail.
Another important thing is that if you build a rule for compiling (using gcc or whatever) and you declare a set of common options for compiling .c files, there's nothing special in variable CFLAGS that makes it to be used by the compiler, so you have to rewrite all rules' commands in which you compile C code to read as the one below:
kernel.o: kernel.c
gcc $(CFLAGS) -m32 -ffreestanding -c $< -o $#
or the -Wall and -g options will never be used on compiling (CFLAGS are, by convention, compiling flags, not assembling, so use instead ASFLAGS for assembling, as compiler flags probably will not be well received by nasm)

GCC issues a warning that my precompiled headers (.h.gch) are invalid

I'm trying to use precompiled headers for the first time. I have the following rules in my Makefile:
$(UNITS_h_gch): $(builddir)/%.h.gch: $(INCLUDEDIR)/%.h $(mk) \
| $$(#D)/. $(builddir)/%.h.d
$(info - CC $$builddir/$*.h.gch)
$(CC) $(CFLAGS) -I $(INCLUDEDIR) -DPCH -S -o $# $<
$(UNITS_c_s): $(builddir)/%.c.s: $(SRCDIR)/%.c $(builddir)/alx/%.h.gch $(mk) \
| $$(#D)/. $(builddir)/%.c.d
$(info - CC $$builddir/$*.c.s)
$(CC) $(CFLAGS) -I $(builddir) -I $(INCLUDEDIR) -S -o $# $<
The rule for the .s files is the same as before, except that it now depends also on the PCH, obviously; and also that it includes $(builddir) in the headers with -I to be able to use the precompiled headers that I generate there.
The nonstandard notation (.c.s) is to simplify the Makefile, as I also have .cxx.s files which follow a slightly different rule, using g++ of course.
As GCC documentation says (https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html), I used the same command line to produce the PCHs. It failed due to #pragma once, so I added a conditional in the headers to remove it when building the PCH; that's why I define PCH with -DPCH.
I've seen that people compiles PCHs with -c, but I also produce temporary assembly files, so I used -S. May that be the cause f the failure?
Logs:
$ make
- CC $builddir/alx/base/assert/array.h.gch
- CC $builddir/base/assert/array.c.s
/home/alx/src/alx/libalx/src/base/assert/array.c:10:35: error: /home/alx/src/alx/libalx/tmp/alx/base/assert/array.h.gch: not a PCH file [-Werror]
10 | #include <alx/base/assert/array.h>
| ^
cc1: all warnings being treated as errors
make[1]: *** [/home/alx/src/alx/libalx/lib/recipes.inc.mk:49: /home/alx/src/alx/libalx/tmp/base/assert/array.c.s] Error 1
make: *** [Makefile:63: base] Error 2
I'm seeing an error because of -Werror, and that appeared after adding -Winvalid-pch. Before that the compilation was successful, but because it was taking the original header file, and not the precompiled one. I suspected of this, because the compilation was twice as slow.
BTW, I use bracket includes (<...>) because this is a library that I install in the system and then use from other programs.

make ignoring include directives

I'm using GNU make and have the following in my Makefile:
token_check: token_check.o $(STATIC_LIBRARIES)
$(CC) -o $# $^
%.o: %.c pipeline/*.h compiler/*.h
$(CC) $(COMPILER_FLAGS) -I./pipeline -I./compiler -c $<
However, when I run make, the command actually run is
cc -c -o token_check.o token_check.c
and I get the error
token_check.c:3:10: fatal error: scanner.h: No such file or directory
3 | #include "scanner.h"
| ^~~~~~~~~~~
compilation terminated.
make: *** [<builtin>: token_check.o] Error 1
scanner.h is contained in the compiler subdirectory.
Why are my -I directives being ignored?
EDIT:
I checked and I do have header files in both pipeline and compiler.
What's really weird is, even if I replace the recipe with
%.o: %.c pipeline/*.h compiler/*.h
echo blah
and run
make token_check.o
it still tries to compile the source file and "blah" never gets printed.
Most likely make is using its implicit rule, not yours. And most likely it does so because your pattern rule does not apply. One reason could be that you do not have any header file in pipeline.

What is the implicit command in "thing.o: thing.c" in a Makefile?

I have a Makefile with the line:
thing.o: thing.c
I want to give an explicit command to do the same, as I need to make a modification to what is run.
What is the implied command?
If I try:
$(CC) $(CFLAGS) thing.c -o thing.o
I get an error, so I assume that this is not what is implicit.
When I use the implicit make rule (i.e. I specify no command) it works properly.
(The error, only when explicitly specifying the command, is:
/opt/avr8-gnu-toolchain-linux_x86_64/bin/avr-gcc -g -Wall -mcall-prologues -mmcu=atmega328p -Os thing.o -Wl,-gc-sections -Wl,-relax -o pmu.obj
pmu.o: In function `__vector_22':
(.text+0x7c): multiple definition of `__bad_interrupt'
/opt/avr8-gnu-toolchain-linux_x86_64/bin/../lib/gcc/avr/4.9.2/../../../../avr/lib/avr5/crtatmega328p.o:(.text+0x0): first defined here
/opt/avr8-gnu-toolchain-linux_x86_64/bin/../lib/gcc/avr/4.9.2/../../../../avr/bin/ld: Disabling relaxation: it will not work with multiple definitions
thing.o: In function `__vectors':
(.text+0x0): multiple definition of `__vectors'
/opt/avr8-gnu-toolchain-linux_x86_64/bin/../lib/gcc/avr/4.9.2/../../../../avr/lib/avr5/crtatmega328p.o:(.vectors+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [thing.obj] Error 1
but the exact error is unimportant - I need to find what I can replace the implicit command with.)
It does just compile (not link), thus you need option -c:
$(CC) $(CFLAGS) -c thing.c
You can use make -pn to dump the built-in rules, the one you're looking for is
%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
which can be further broken down into
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $# $<
-c is probably the main culprit although CPPFLAGS could play a role too.

Resources