`No such file or directory` error when building Qt project without QMake, despite appropriate include path constructed - makefile

I'm trying to compile a small application using Qt but without using QMake, but whenever I try to run it, I get the following error message:
g++ -c -g -pg -Wall -Wextra -pipe -c -o ../../MOCFiles/moc_projectModel.o ../../MOCFiles/moc_projectModel.cpp
In file included from ../../MOCFiles/moc_projectModel.cpp:10:0:
../../MOCFiles/../Src/ProjectStructure/projectModel.h:4:30: fatal error: QAbstractItemModel: No such file or directory
compilation terminated.
make: *** [../../MOCFiles/moc_projectModel.o] Error 1
This would seem to suggest that I haven't constructed my $(INCLUDE) variable properly, but it is as follows:
INCLUDE = -I/usr/include/qt4 \
-I/usr/include/qt4/QtGui \
-I/usr/include/qt4/QtCore \
-I/usr/include/qt4/QtXml \
-I/usr/share/qt4/mkspecs/linux-g++ \
-I../../Src/ProjectStructure
and I am able to locate the QAbstractItemModel file in /usr/include/qt4/QtCore/, a directory which is part of my include variable. This is my first time writing a GNU Makefile and I'm not sure what it is I'm doing wrong. For reference, the entire file is included here:
CXX = g++
CXXFLAGS = -c -g -pg -Wall -Wextra -pipe
LINK = g++
LIBS = -L/usr/lib \
-L/usr/lib/i386-linux-gnu \
-lgtest \
-lQtGui \
-lQtCore \
-lQtXml \
-lpthread
INCLUDE = -I/usr/include/qt4 \
-I/usr/include/qt4/QtGui \
-I/usr/include/qt4/QtCore \
-I/usr/include/qt4/QtXml \
-I/usr/share/qt4/mkspecs/linux-g++ \
-I../../Src/ProjectStructure
OBJECTS = ../Objects/main.o \
../Objects/test_projectEntity.o \
../Objects/moc_test_projectModel.o \
../../Objects/projectEntity.o \
../../Objects/projectModel.o \
../../MOCFiles/moc_projectModel.o
../../Binaries/tests: $(OBJECTS)
$(LINK) $^ $(LIBS) -o $#
../Objects/main.o : ../Src/main.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) ../Src/main.cpp -o ../Objects/main.o
../Objects/moc_test_projectModel.o : ../MOCFiles/moc_test_projectModel.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) ../MOCFiles/moc_test_projectModel.cpp -o ../Objects/moc_test_projectModel.o
../../MOCFiles/moc_test_projectModel.cpp : ../Src/test_projectModel.cpp
moc ../Src/test_projectModel.cpp -o ../MOCFiles/moc_test_projectModel.cpp
../Objects/test_projectEntity.o : ../Src/test_projectEntity.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) ../Src/test_projectEntity.cpp -o ../Objects/test_projectEntity.o
clean:
rm -f ../Objects/main.o ../Objects/test_projectEntity.o ../Objects/test_projectModel.o

It looks as if you're trying to build ../../Binaries/tests. One of the preqs is ../../MOCFiles/moc_projectModel.o, but there's no explicit rule for building that, so Make uses the implicit rule and attempts this:
g++ -c -g -pg -Wall -Wextra -pipe -c -o ../../MOCFiles/moc_projectModel.o ../../MOCFiles/moc_projectModel.cpp
Notice that there's no mention of INCLUDE there. So g++ doesn't know to look in /usr/include/qt4/QtCore/. The simple solution is to add a rule:
../../MOCFiles/moc_projectModel.o : ../../MOCFiles/moc_projectModel.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) $< -o $#
Notice that I used automatic variables $< and $# there, to reduce redundancy and clutter. We could also make it into a pattern rule:
../../MOCFiles/%.o : ../../MOCFiles/%.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) $< -o $#
This takes care of moc_projectModel.o and anything else that has the same pattern (source and object both in MOCFiles/). We could make other improvements, but that should be enough to get you up and running.

Related

Makefile linking: undefined reference to _exit

I have been trying to create a neatly-organized makefile project template utilizing the ARM mbed library. I have already solved a few of the problems (see this post) related to header file paths. However, now I am having problems with the linker. My goal is to have sources and headers in src, object files in obj, and the final binaries in either debug or release.
Here is the error I am getting...
make
arm-none-eabi-g++ -DTARGET_M4 -DMBED_BUILD_TIMESTAMP=1453683815.81 -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -DTARGET_RTOS_M4_M7 -DTARGET_FF_MORPHO -DTARGET_CORTEX_M -D__FPU_PRESENT=1 -DTARGET_FF_ARDUINO -DTARGET_STM32F446RE -DTARGET_NUCLEO_F446RE -D__MBED__=1 -DTARGET_STM -DTARGET_STM32F4 -D__CORTEX_M4 -DARM_MATH_CM4 -std=c++98 -fno-rtti -I lib/ -I lib/mbed/ -I lib/mbed/TARGET_NUCLEO_F446RE/ -I lib/mbed/TARGET_NUCLEO_F446RE/TARGET_STM/ -I lib/mbed/TARGET_NUCLEO_F446RE/TARGET_STM/TARGET_STM32F4/ -I lib/mbed/TARGET_NUCLEO_F446RE/TOOLCHAIN_GCC_ARM/ -I lib/mbed/TARGET_NUCLEO_F446RE/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F446RE/ -o obj/main.o src/main.cc
/usr/lib/gcc/arm-none-eabi/6.1.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
make: *** [makefile:54: obj/main.o] Error 1
This is my makefile. I have denoted where the problem(s) might be, but I am not sure.
#Project parameters
PROJECT = Nucleo_blink
OBJECTS = obj/main.o
DEST = debug
VPATH = src lib $DEST
TARGET = NUCLEO_F446RE
#Compilation options
DEBUG = 1
#Tools
AS = $(GCC_BIN)arm-none-eabi-as
CC = $(GCC_BIN)arm-none-eabi-gcc
CXX = $(GCC_BIN)arm-none-eabi-g++
LD = $(GCC_BIN)arm-none-eabi-gcc
OBJCOPY = $(GCC_BIN)arm-none-eabi-objcopy
OBJDUMP = $(GCC_BIN)arm-none-eabi-objdump
SIZE = $(GCC_BIN)arm-none-eabi-size
include $(TARGET).mk
CFLAGS = $(INCLUDE_PATHS) $(CC_SYMBOLS) $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -Wextra -fno-exceptions -ffunction-sections -fdata-sections -fomit-frame-pointer -MMD -MP
ifeq ($(HARDFP),1)
FLOAT_ABI = hard
else
FLOAT_ABI = softfp
endif
ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -O0
else
CFLAGS += -DNDEBUG -Os
endif
#MY PROBLEM MAY BE HERE
LD_FLAGS = $(CPU) -Wl,--gc-sections --specs=nano.specs -Wl,--wrap,main -Wl,-Map=$(PROJECT).map,--cref
#`-u _printf_float -u _scanf_float` after -specs for floating point I/O
LD_SYS_LIBS = -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys
LIBRARIES = -lmbed
.PHONY: all clean lst size
all: $(PROJECT).bin $(PROJECT).hex
clean:
rm -f debug/* obj/* asm/* $(DEPS)
obj/%.o: %.c
$(CC) $(CC_FLAGS) $(CC_SYMBOLS) -std=c99 $(INCLUDE_PATHS) -o $# $<
obj/%.o: %.cc
$(CXX) $(CC_FLAGS) $(CC_SYMBOLS) -std=c++98 -fno-rtti $(INCLUDE_PATHS) -o $# $<
obj/%.o: %.cpp
$(CXX) $(CC_FLAGS) $(CC_SYMBOLS) -std=c++98 -fno-rtti $(INCLUDE_PATHS) -o $# $<
obj/%.o: %.asm
$(CC) $(CPU) -c -x assembler-with-cpp -o asm/$# $<
#OR HERE
$(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS)
$(LD) $(LD_FLAGS) -T$(LINKER_SCRIPT) $(LIBRARY_PATHS) -o $(DEST)/$# $^ $(LIBRARIES) $(LD_SYS_LIBS) $(LIBRARIES) $(LD_SYS_LIBS)
$(PROJECT).bin: $(PROJECT).elf
$(OBJCOPY) -O binary $< $#
$(PROJECT).hex: $(PROJECT).elf
#$(OBJCOPY) -O ihex $< $#
$(PROJECT).lst: $(PROJECT).elf
#$(OBJDUMP) -Sdh $< > $#
lst: $(PROJECT).lst
size: $(PROJECT).elf
$(SIZE) $(PROJECT).elf
DEPS = $(OBJECTS:.o=.d) $(SYS_OBJECTS:.o=.d)
-include $(DEPS)
Before you ask, I have already tried changing --specs=nano.specs to --specs=nosys.specs. It does nothing. The strange part is that the linker settings above work fine for the automatically generated mbed makefile.
Here is the working makefile. It compiles without errors...
# This file was automagically generated by mbed.org. For more information,
# see http://mbed.org/handbook/Exporting-to-GCC-ARM-Embedded
GCC_BIN =
PROJECT = Nucleo_blink
OBJECTS = ./source/main.o
SYS_OBJECTS = #Long list of object files
INCLUDE_PATHS = -I. -I./source -I./mbed -I./mbed/TARGET_NUCLEO_F446RE -I./mbed/TARGET_NUCLEO_F446RE/TARGET_STM -I./mbed/TARGET_NUCLEO_F446RE/TARGET_STM/TARGET_STM32F4 -I./mbed/TARGET_NUCLEO_F446RE/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F446RE -I./mbed/TARGET_NUCLEO_F446RE/TOOLCHAIN_GCC_ARM
LIBRARY_PATHS = -L./mbed/TARGET_NUCLEO_F446RE/TOOLCHAIN_GCC_ARM
LIBRARIES = -lmbed
LINKER_SCRIPT = ./mbed/TARGET_NUCLEO_F446RE/TOOLCHAIN_GCC_ARM/STM32F446XE.ld
###############################################################################
AS = $(GCC_BIN)arm-none-eabi-as
CC = $(GCC_BIN)arm-none-eabi-gcc
CPP = $(GCC_BIN)arm-none-eabi-g++
LD = $(GCC_BIN)arm-none-eabi-gcc
OBJCOPY = $(GCC_BIN)arm-none-eabi-objcopy
OBJDUMP = $(GCC_BIN)arm-none-eabi-objdump
SIZE = $(GCC_BIN)arm-none-eabi-size
ifeq ($(HARDFP),1)
FLOAT_ABI = hard
else
FLOAT_ABI = softfp
endif
CPU = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=$(FLOAT_ABI)
CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -Wextra -fno-exceptions -ffunction-sections -fdata-sections -fomit-frame-pointer -MMD -MP
CC_SYMBOLS = -DTARGET_M4 -DTARGET_FF_ARDUINO -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -DTARGET_RTOS_M4_M7 -DTARGET_FF_MORPHO -DTARGET_LIKE_MBED -DTARGET_CORTEX_M -D__FPU_PRESENT=1 -DTARGET_LIKE_CORTEX_M4 -DTARGET_NUCLEO_F446RE -D__MBED__=1 -DTARGET_STM -DMBED_BUILD_TIMESTAMP=1468213384.59 -DTARGET_STM32F446RE -DTARGET_STM32F4 -D__CORTEX_M4 -DARM_MATH_CM4
#My makefile above copies these two lines
LD_FLAGS = $(CPU) -Wl,--gc-sections --specs=nano.specs -u _printf_float -u _scanf_float -Wl,--wrap,main -Wl,-Map=$(PROJECT).map,--cref
LD_SYS_LIBS = -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys
ifeq ($(DEBUG), 1)
CC_FLAGS += -DDEBUG -O0
else
CC_FLAGS += -DNDEBUG -Os
endif
.PHONY: all clean lst size
all: $(PROJECT).bin $(PROJECT).hex size
clean:
rm -f $(PROJECT).bin $(PROJECT).elf $(PROJECT).hex $(PROJECT).map $(PROJECT).lst $(OBJECTS) $(DEPS)
.asm.o:
$(CC) $(CPU) -c -x assembler-with-cpp -o $# $<
.s.o:
$(CC) $(CPU) -c -x assembler-with-cpp -o $# $<
.S.o:
$(CC) $(CPU) -c -x assembler-with-cpp -o $# $<
.c.o:
$(CC) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu99 $(INCLUDE_PATHS) -o $# $<
.cpp.o:
$(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu++98 -fno-rtti $(INCLUDE_PATHS) -o $# $<
$(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS)
$(LD) $(LD_FLAGS) -T$(LINKER_SCRIPT) $(LIBRARY_PATHS) -o $# $^ -Wl,--start-group $(LIBRARIES) $(LD_SYS_LIBS) -Wl,--end-group
$(PROJECT).bin: $(PROJECT).elf
$(OBJCOPY) -O binary $< $#
$(PROJECT).hex: $(PROJECT).elf
#$(OBJCOPY) -O ihex $< $#
$(PROJECT).lst: $(PROJECT).elf
#$(OBJDUMP) -Sdh $< > $#
lst: $(PROJECT).lst
size: $(PROJECT).elf
$(SIZE) $(PROJECT).elf
DEPS = $(OBJECTS:.o=.d) $(SYS_OBJECTS:.o=.d)
-include $(DEPS)
I think my problem is some sort of path error...
- The _exit symbol may be defined, but inaccessible by main.o
- There may be some major error in the makefile I'm missing
- Something totally different?
Feel free to comment any suggested changes to this question.
EDIT: All I had to do to fix the error was change CFLAGS to CCFLAGS. The answer I marked as the solution explained what was happening, and a potential way to fix it. Although I didn't need to use the suggested solution, the explanation of why it wasn't working is useful, and the information provided by both answers is useful.
Adding --specs=nosys.specs to your linker options may also solve this issue.
You can see exactly what this does by looking at the nosys.specs file which will be somewhere in your compiler directory.
See also: exit.c:(.text+0x18): undefined reference to `_exit' when using arm-none-eabi-gcc
_exit is a system call, as well as some other functions you probably will need later. When you compile a binary for (for example) Linux, these calls are serviced by the operating system. In bare-metal embedded project you need to define these functions by yourself. The common way is to create a file called syscalls.c or something like that and put all needed system calls there. Take a look at example of such file, rapidly found by google: https://github.com/bjornfor/stm32-test/blob/master/STM32L1xx_StdPeriph_Lib_V1.1.1/syscalls.c
As a bonus, if you properly implement _read and _write to work with UART, you will get a serial console capable to do formatted IO via printf and scanf .
The _exit symbol may be defined, but inaccessible by main.o - There may be some major error in the makefile I'm missing - Something totally different?
This happens when a call to a standard library method indirectly has a dependency on exit(). Often from automatically generated exception unwind code that's supposed to abort your process on exit, which obviously has different semantics in a bare metal application. The division-by-zero floating point exception is one such example. -fno-exceptions does not help with this.
You can of course supply a do-nothing exit() handler but your code would be smaller if the exception unwind code didn't get inserted in the first place.
I discovered by examining the generated assembler that you can replace the exception handlers with do-nothing versions like this in a compilation unit:
extern "C" void __wrap___aeabi_unwind_cpp_pr0() {}
extern "C" void __wrap___aeabi_unwind_cpp_pr1() {}
extern "C" void __wrap___aeabi_unwind_cpp_pr2() {}
and then link those in as replacements at link time with these additional linker arguments.
-Wl,-wrap,__aeabi_unwind_cpp_pr0,
-Wl,-wrap,__aeabi_unwind_cpp_pr1
-Wl,-wrap,__aeabi_unwind_cpp_pr2
Another benefit is that your code should shrink as a result. You may even want to insert your own implementations that reset the MCU.
For me it took both -fno-exceptions and --specs=nosys.specs in compiler flags.
It seems like you use stdlib. System cal exit(int) calls in-system function _exit(int).
For me decision was applying -nostdlib option because I wasn't going to use stdlib.
Thanks, UserHuman, https://stackoverflow.com/a/51657692/8313090

GNU make is adding an extra step not in my Makefile that causes all sorts of linker errors. What's going on?

Given the following makefile for GNU make:
# TODOs so I don't forget:
# - make debugging an option
# - make 64 below an actual option
# - figure out why make test seems to rebuild the DLL
# - __declspec(dllimport)
ifeq ($(MAKECMDGOALS),64)
CC = x86_64-w64-mingw32-gcc
RC = x86_64-w64-mingw32-windres
mflag = -m64
else
CC = i686-w64-mingw32-gcc
RC = i686-w64-mingw32-windres
mflag = -m32
endif
OBJDIR = .objs
OUTDIR = out
BASENAME = wintable
DLLFILE = $(OUTDIR)/$(BASENAME).dll
LIBFILE = $(OUTDIR)/$(BASENAME).lib
TESTEXEFILE = $(OUTDIR)/$(BASENAME).exe
CFILES = \
alloc.c \
api.c \
checkboxdraw.c \
checkboxevents.c \
children.c \
coord.c \
debug.c \
draw.c \
events.c \
header.c \
hscroll.c \
main.c \
metrics.c \
modelhelpers.c \
nullmodel.c \
resize.c \
scroll.c \
select.c \
update.c \
util.c \
visibility.c \
vscroll.c
HFILES = \
table.h \
tablepriv.h
TESTCFILES = \
test.c
OFILES = $(CFILES:%.c=$(OBJDIR)/%.o)
TESTOFILES = $(TESTCFILES:%.c=$(OBJDIR)/%.o)
xCFLAGS = \
--std=c99 \
-Wall \
-Wextra \
-Wno-unused-parameter \
$(mflag) \
$(CFLAGS)
xLDFLAGS = \
-static-libgcc \
-luser32 -lkernel32 -lgdi32 -lcomctl32 -luxtheme -lole32 -loleaut32 -loleacc -luuid -lmsimg32 \
$(mflag) \
$(LDFLAGS)
default:
$(MAKE) clean
$(MAKE) it
$(MAKE) test
it: $(DLLFILE)
$(DLLFILE): $(OFILES)
$(CC) -g -o $(DLLFILE) -shared -Wl,--out-implib,$(LIBFILE) $(OFILES) $(xLDFLAGS)
test: $(TESTEXEFILE)
$(TESTEXEFILE): $(DLLFILE) $(TESTOFILES)
$(CC) -g -o $(TESTEXEFILE) $(TESTOFILES) $(LIBFILE) $(xLDFLAGS)
$(OBJDIR)/%.o: %.c $(HFILES) dirs
$(CC) -g -o $# -c $< $(xCFLAGS)
dirs:
mkdir -p $(OBJDIR) $(OUTDIR)
clean:
rm -rf $(OBJDIR) $(OUTDIR)
make -n test produces
mkdir -p .objs out
i686-w64-mingw32-gcc -g -o .objs/alloc.o -c alloc.c --std=c99 -Wall -Wextra -Wno-unused-parameter -m32
i686-w64-mingw32-gcc -g -o .objs/api.o -c api.c --std=c99 -Wall -Wextra -Wno-unused-parameter -m32
(and so on for all the other C files)
i686-w64-mingw32-gcc -g -o out/wintable.dll -shared -Wl,--out-implib,out/wintable.lib .objs/alloc.o .objs/api.o .objs/checkboxdraw.o .objs/checkboxevents.o .objs/children.o .objs/coord.o .objs/debug.o .objs/draw.o .objs/events.o .objs/header.o .objs/hscroll.o .objs/main.o .objs/metrics.o .objs/modelhelpers.o .objs/nullmodel.o .objs/resize.o .objs/scroll.o .objs/select.o .objs/update.o .objs/util.o .objs/visibility.o .objs/vscroll.o -static-libgcc -luser32 -lkernel32 -lgdi32 -lcomctl32 -luxtheme -lole32 -loleaut32 -loleacc -luuid -lmsimg32 -m32
i686-w64-mingw32-gcc -g -o .objs/test.o -c test.c --std=c99 -Wall -Wextra -Wno-unused-parameter -m32
i686-w64-mingw32-gcc -g -o out/wintable.exe .objs/test.o out/wintable.lib -static-libgcc -luser32 -lkernel32 -lgdi32 -lcomctl32 -luxtheme -lole32 -loleaut32 -loleacc -luuid -lmsimg32 -m32
i686-w64-mingw32-gcc test.c out/wintable.exe -o test
Notice how the last step that GNU make decides to do tries to recompile my test.c with the correct output executable file built before that into a new test executable, which (predictably) fails spectacularly:
out/wintable.exe: In function `WinMainCRTStartup':
/build/buildd/mingw-w64-3.1.0/build/i686-w64-mingw32-i686-w64-mingw32-crt/../../mingw-w64-crt/crt/crtexe.c:171: multiple definition of `WinMainCRTStartup'
/usr/lib/gcc/i686-w64-mingw32/4.9-win32/../../../../i686-w64-mingw32/lib/../lib/crt2.o:/build/buildd/mingw-w64-3.1.0/build/i686-w64-mingw32-i686-w64-mingw32-crt/../../mingw-w64-crt/crt/crtexe.c:171: first defined here
out/wintable.exe: In function `mainCRTStartup':
/build/buildd/mingw-w64-3.1.0/build/i686-w64-mingw32-i686-w64-mingw32-crt/../../mingw-w64-crt/crt/crtexe.c:199: multiple definition of `mainCRTStartup'
/usr/lib/gcc/i686-w64-mingw32/4.9-win32/../../../../i686-w64-mingw32/lib/../lib/crt2.o:/build/buildd/mingw-w64-3.1.0/build/i686-w64-mingw32-i686-w64-mingw32-crt/../../mingw-w64-crt/crt/crtexe.c:199: first defined here
out/wintable.exe:cygming-crtbegin.c:(.text+0x500): multiple definition of `__gcc_register_frame'
/usr/lib/gcc/i686-w64-mingw32/4.9-win32/crtbegin.o:cygming-crtbegin.c:(.text+0x0): first defined here
out/wintable.exe:cygming-crtbegin.c:(.text+0x550): multiple definition of `__gcc_deregister_frame'
/usr/lib/gcc/i686-w64-mingw32/4.9-win32/crtbegin.o:cygming-crtbegin.c:(.text+0x50): first defined here
out/wintable.exe: In function `mainwinCreate':
/home/pietro/src/github.com/andlabs/wintable/test.c:20: multiple definition of `mainwinCreate'
/tmp/cc50VrIz.o:test.c:(.text+0x0): first defined here
out/wintable.exe: In function `mainwinDestroy':
/home/pietro/src/github.com/andlabs/wintable/test.c:66: multiple definition of `mainwinDestroy'
/tmp/cc50VrIz.o:test.c:(.text+0x2ba): first defined here
(and so on for virtually every symbol in my test.c)
/usr/lib/gcc/i686-w64-mingw32/4.9-win32/crtbegin.o:cygming-crtbegin.c:(.text+0x22): undefined reference to `_Jv_RegisterClasses'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'test' failed
make: *** [test] Error 1
Where is this last step coming from? It's nowhere in my makefile, as far as I can tell. (Notice the lack of compiler flags.) Googling the problem was also ineffective here. This only started to happen today, with all the same rules as before (the only change is the addition of modelhelpers.c and nullmodel.c to CFILES), so I'm not sure what's going on.
Does it have to do with the rule being test? If so, why did it work before?
This is GNU make 4.0 on Ubuntu GNOME 14.10.
Thanks.
Make has various built-in implicit rules, and one of them is the pattern rule % : %.c, which tells make how to create an executable (in UNIX systems, executables don't have any extension like .exe etc., they're just words like test, mkdir, etc.) if it has a source file with the same extension.
Your makefile has:
test: $(TESTEXEFILE)
and you provide no recipe for building the target test, so make looks at its built-in rules and finds % : %.c, and then make looks and sees that you DO have a test.c file, so make applies that default recipe to build the target test, which you asked it to do.
If you don't want this to happen you should tell make that test is not a real target: that you're only using it as a handle to build other things, using the .PHONY special target:
.PHONY: test
From the manual:
The implicit rule search is skipped for .PHONY targets.

Make wildcard dependency No rule to make target needed by

I am trying to build my targets with wildcards. Here is my Makefile:
BINARY = main
LDSCRIPT = stm32f4-discovery.ld
PREFIX ?= arm-none-eabi
CC = $(PREFIX)-gcc
LD = $(PREFIX)-gcc
OBJCOPY = $(PREFIX)-objcopy
CFLAGS += -Os -g \
-Wall -Wextra -Wimplicit-function-declaration \
-Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
-Wundef -Wshadow \
-I$(TOOLCHAIN_DIR)/include \
-fno-common -mcpu=cortex-m4 -mthumb \
-mfloat-abi=hard -mfpu=fpv4-sp-d16 -MD -DSTM32F4
LDSCRIPT ?= $(BINARY).ld
LDFLAGS += --static -lc -lnosys -L$(TOOLCHAIN_DIR)/lib \
-L$(TOOLCHAIN_DIR)/lib/stm32/f4 \
-T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \
-mthumb -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
OBJS += $(BINARY).o
all: images
images: $(BINARY).images
%.images: %.bin
##printf "*** $* images generated ***\n"
%.bin: %.elf
##printf " OBJCOPY $(*).bin\n"
$(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin
%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f4.a
##printf " LD $(subst $(shell pwd)/,,$(#))\n"
$(Q)$(LD) -o $(*).elf $(OBJS) -lopencm3_stm32f4 $(LDFLAGS)
%.o: %.c Makefile
##printf " CC $(subst $(shell pwd)/,,$(#))\n"
$(Q)$(CC) $(CFLAGS) -o $# -c $<
clean:
$(Q)rm -f *.o
$(Q)rm -f *.d
$(Q)rm -f *.elf
$(Q)rm -f *.bin
-include $(OBJS:.o=.d)
When I make, I get the error:
make: *** No rule to make target `main.bin', needed by `main.images'. Stop.
I am trying to make a single image, so I can change each % to $(BINARY), and this works, but I would like to figure out why this isn't working.
You are likely missing a dependency somewhere down the chain.
Note: Some people forget that the "Makefile" itself, when placed on the dependency line - is also checked for existance. Double check that you haven't renamed it.
Like #MadScientist recommends, "make -d" will be your friend here. Use that to locate the rule/file that should have been found but was not.
I simplified your example (on Linux) and got the same type of error with:
Makefile:
all: main.out
%.out: %.elf
g++ $^ -o $#
%.elf: %.obj
mv $^ $#
%.obj: %.cpp Makefile
g++ -c $^ -o $#
Create main.cpp, see it work, then rename main.cpp to something else that it can't find, run again, see it fail.
Now rename the Makefile itself, see the same failure.

specifying the compiler in a gnu makefile

I have a gnu makefile template that has served me well, but when I try to specify a compiler other than the first g++ in my path, it fails.
Here's the template.
CXX = g++
CXXFLAGS = $(INC) $(LIB) -Wall
INC = -I./ -I/usr/local/include
LIB = -L/usr/local/lib
SRCS = \
blah1.cpp
blah2.cpp
OBJS = $(SRCS:.cpp=.o)
DEPS = $(SRCS:.cpp=.d)
PROG = myprog
$(PROG): $(OBJS)
$(CXX) $(CXXFLAGS) -o $# $(OBJS)
%.d: %.cpp
#set -e; rm -f $#; \
$(CXX) -MM $(CXXFLAGS) $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
debug: CXXFLAGS += -O0 -DDEBUG -ggdb
debug: $(PROG)
-include $(DEPS)
.PHONY: clean
clean:
rm -f $(DEPS) $(OBJS) $(PROG)
When I change the compiler from g++ to something like /usr/local/bin/g++46, it still compiles with g++ (/usr/bin/g++ to be exact). Why?
P.S. Any criticisms with the template are welcome. I'm not very comfortable with gnu make; I just crammed and searched the web for a day to come up with this.
You haven't specified your own rule for how to build object files, so Make uses the default implicit rule, which is:
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c
Note $(CXX), not $(CC), which specifies the default C compiler.

Makefile sometimes ignores variable in recipe

I have the following Makefile
CXX = g++
CXXFLAGS = -g -Wall
COMPILE = ${CXX} ${CXXFLAGS} -c
LINK = ${CXX} -lpthread
LIB_INC = -Ilib -Iwrappers -Iprocesses
src := $(wildcard lib/*.cpp) $(wildcard wrappers/*.cpp)
obj = $(src:.cpp=.o)
src_1 := processnetwork_part001.cpp sc_application_1.cpp
obj_1 = $(src_1:.cpp=.o)
src_2 := processnetwork_part002.cpp sc_application_2.cpp
obj_2 = $(src_2:.cpp=.o)
all : sc_application_1 sc_application_2
.PHONY : all
sc_application_1 : ${obj} ${obj_1}
${LINK} -o sc_application_1 $(obj) ${obj_1}
sc_application_2 : ${obj} ${obj_2}
${LINK} -o sc_application_2 $(obj) ${obj_2}
%.o : %.cpp %.h
${COMPILE} -o $# $< $(LIB_INC)
clean :
rm sc_application_1 sc_application_2 ${obj} ${obj_1} ${obj_2}
Where lib, wrappers and processes are subdirectories of the directory where the Makefile and the two main applications sc_application_1 and sc_application_2 are stored. When I run make, I get the following output (only the last few lines w/o compiler warnings).
g++ -g -Wall -c -o lib/Scheduler.o lib/Scheduler.cpp -Ilib -Iwrappers -Iprocesses
g++ -g -Wall -c -o wrappers/consumer_wrapper.o wrappers/consumer_wrapper.cpp -Ilib -Iwrappers -Iprocesses
g++ -g -Wall -c -o wrappers/generator_wrapper.o wrappers/generator_wrapper.cpp -Ilib -Iwrappers -Iprocesses
g++ -g -Wall -c -o wrappers/square_wrapper.o wrappers/square_wrapper.cpp -Ilib -Iwrappers -Iprocesses
g++ -g -Wall -c -o processnetwork_part001.o processnetwork_part001.cpp -Ilib -Iwrappers -Iprocesses
g++ -g -Wall -c -o sc_application_1.o sc_application_1.cpp
In file included from wrappers/wrappers.h:4:0,
from sc_application_1.cpp:10:
wrappers/generator_wrapper.h:4:28: fatal error: ProcessWrapper.h: No such file or directory
compilation terminated.
make: *** [sc_application_1.o] Error 1
Compilation fails because for some reason that I don't understand, the variable LIB_INC isn't added anymore to
g++ -g -Wall -c -o sc_application_1.o sc_application_1.cpp
But it is (as I intended) on all previous lines. Can anyone explain me this behaviour? Thank you.
edit: The error doesn't occur when I ommit the "%.h" in the "%.o" target.
I'm going to go out on a limb, and guess that there is no sc_application_1.h, but there is a header file for every previous source (e.g. Scheduler.h, consumer_wrapper.h ...).
Your %.o: %.cpp %.h rule doesn't apply if there is no %.h, so Make falls back on its default rule, which does not use LIB_INC. The simplest way to fix this is to add another %.o rule:
%.o : %.cpp %.h
${COMPILE} -o $# $< $(LIB_INC)
%.o : %.cpp
${COMPILE} -o $# $< $(LIB_INC)

Resources