Set project root folder - c++

I have c++ Makefile project. Project simplified folder looks as below:
tmp|
|--Makefile
|--lvgl
| |--lvgl.h
|--lv_drivers
| |--display
| |--fbdev.h
Unit fbdev.h contains include:
#include "lvgl/lvgl.h"
I have error while build related to this include:
lvgl/lvgl.h: No such file or directory
How to ask build system to find lvgl/lvgl.h by searching from from project root folder. Should I somehow define in Makefile project root location?
Autogenerated Makefile:
#Generated by VisualGDB project wizard.
#Note: VisualGDB will automatically update this file when you add new sources to the project.
#All other changes you make in this file will be preserved.
#Visit http://visualgdb.com/makefiles for more details
#VisualGDB: AutoSourceFiles #<--- remove this line to disable auto-updating of SOURCEFILES and EXTERNAL_LIBS
TARGETNAME := boilerX
#TARGETTYPE can be APP, STATIC or SHARED
TARGETTYPE := APP
to_lowercase = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
macros-to-preprocessor-directives = $(foreach __macro, $(strip $1), \
$(if $(findstring =,$(__macro)), \
--pd "$(firstword $(subst =, ,$(__macro))) SETA $(subst ",\",$(lastword $(subst =, ,$(__macro))))", \
--pd "$(__macro) SETA 1")) \
CONFIG ?= DEBUG
CONFIGURATION_FLAGS_FILE := $(call to_lowercase,$(CONFIG)).mak
TOOLCHAIN_ROOT ?= $(toolchain_root)
include $(CONFIGURATION_FLAGS_FILE)
#LINKER_SCRIPT defined inside the configuration file (e.g. debug.mak) should override any linker scripts defined in shared .mak files
CONFIGURATION_LINKER_SCRIPT := $(LINKER_SCRIPT)
include $(ADDITIONAL_MAKE_FILES)
ifneq ($(CONFIGURATION_LINKER_SCRIPT),)
LINKER_SCRIPT := $(CONFIGURATION_LINKER_SCRIPT)
endif
ifneq ($(LINKER_SCRIPT),)
ifeq ($(TOOLCHAIN_SUBTYPE),iar)
LDFLAGS += --config $(LINKER_SCRIPT)
else
LDFLAGS += -T$(LINKER_SCRIPT)
endif
endif
ifeq ($(AS),)
AS := as
endif
ifeq ($(AS),as)
AS := $(CC)
ASFLAGS := $(CFLAGS) $(ASFLAGS)
endif
ifeq ($(TOOLCHAIN_SUBTYPE),iar)
CC_DEPENDENCY_FILE_SPECIFIER := --dependencies=m
ASM_DEPENDENCY_FILE_SPECIFIER := && echo >
CXXFLAGS += --c++
COMMONFLAGS += --silent
else ifeq ($(TOOLCHAIN_SUBTYPE),armcc)
CC_DEPENDENCY_FILE_SPECIFIER := --depend
ASM_DEPENDENCY_FILE_SPECIFIER := --depend
USING_KEIL_TOOLCHAIN := 1
else ifeq ($(TOOLCHAIN_SUBTYPE),armclang)
CC_DEPENDENCY_FILE_SPECIFIER := -MD -MF
ASM_DEPENDENCY_FILE_SPECIFIER := --depend
USING_KEIL_TOOLCHAIN := 1
else
CC_DEPENDENCY_FILE_SPECIFIER := -MD -MF
ASM_DEPENDENCY_FILE_SPECIFIER := -MD -MF
endif
ifeq ($(BINARYDIR),)
error:
$(error Invalid configuration, please check your inputs)
endif
SOURCEFILES := boiler.cpp boilerX.cpp boiler_ui.cpp lvgl/examples/porting/lv_port_disp_template.c lvgl/examples/porting/lv_port_fs_template.c lvgl/examples/porting/lv_port_indev_template.c lvgl/src/lv_core/lv_disp.c lvgl/src/lv_core/lv_group.c lvgl/src/lv_core/lv_indev.c lvgl/src/lv_core/lv_obj.c lvgl/src/lv_core/lv_refr.c lvgl/src/lv_core/lv_style.c lvgl/src/lv_draw/lv_draw_arc.c lvgl/src/lv_draw/lv_draw_blend.c lvgl/src/lv_draw/lv_draw_img.c lvgl/src/lv_draw/lv_draw_label.c lvgl/src/lv_draw/lv_draw_line.c lvgl/src/lv_draw/lv_draw_mask.c lvgl/src/lv_draw/lv_draw_rect.c lvgl/src/lv_draw/lv_draw_triangle.c lvgl/src/lv_draw/lv_img_buf.c lvgl/src/lv_draw/lv_img_cache.c lvgl/src/lv_draw/lv_img_decoder.c lvgl/src/lv_font/lv_font.c lvgl/src/lv_font/lv_font_dejavu_16_persian_hebrew.c lvgl/src/lv_font/lv_font_fmt_txt.c lvgl/src/lv_font/lv_font_loader.c lvgl/src/lv_font/lv_font_montserrat_10.c lvgl/src/lv_font/lv_font_montserrat_12.c lvgl/src/lv_font/lv_font_montserrat_12_subpx.c lvgl/src/lv_font/lv_font_montserrat_14.c lvgl/src/lv_font/lv_font_montserrat_16.c lvgl/src/lv_font/lv_font_montserrat_18.c lvgl/src/lv_font/lv_font_montserrat_20.c lvgl/src/lv_font/lv_font_montserrat_22.c lvgl/src/lv_font/lv_font_montserrat_24.c lvgl/src/lv_font/lv_font_montserrat_26.c lvgl/src/lv_font/lv_font_montserrat_28.c lvgl/src/lv_font/lv_font_montserrat_28_compressed.c lvgl/src/lv_font/lv_font_montserrat_30.c lvgl/src/lv_font/lv_font_montserrat_32.c lvgl/src/lv_font/lv_font_montserrat_34.c lvgl/src/lv_font/lv_font_montserrat_36.c lvgl/src/lv_font/lv_font_montserrat_38.c lvgl/src/lv_font/lv_font_montserrat_40.c lvgl/src/lv_font/lv_font_montserrat_42.c lvgl/src/lv_font/lv_font_montserrat_44.c lvgl/src/lv_font/lv_font_montserrat_46.c lvgl/src/lv_font/lv_font_montserrat_48.c lvgl/src/lv_font/lv_font_montserrat_8.c lvgl/src/lv_font/lv_font_simsun_16_cjk.c lvgl/src/lv_font/lv_font_unscii_16.c lvgl/src/lv_font/lv_font_unscii_8.c lvgl/src/lv_gpu/lv_gpu_nxp_pxp.c lvgl/src/lv_gpu/lv_gpu_nxp_pxp_osa.c lvgl/src/lv_gpu/lv_gpu_nxp_vglite.c lvgl/src/lv_gpu/lv_gpu_stm32_dma2d.c lvgl/src/lv_hal/lv_hal_disp.c lvgl/src/lv_hal/lv_hal_indev.c lvgl/src/lv_hal/lv_hal_tick.c lvgl/src/lv_misc/lv_anim.c lvgl/src/lv_misc/lv_area.c lvgl/src/lv_misc/lv_async.c lvgl/src/lv_misc/lv_bidi.c lvgl/src/lv_misc/lv_color.c lvgl/src/lv_misc/lv_debug.c lvgl/src/lv_misc/lv_fs.c lvgl/src/lv_misc/lv_gc.c lvgl/src/lv_misc/lv_ll.c lvgl/src/lv_misc/lv_log.c lvgl/src/lv_misc/lv_math.c lvgl/src/lv_misc/lv_mem.c lvgl/src/lv_misc/lv_printf.c lvgl/src/lv_misc/lv_task.c lvgl/src/lv_misc/lv_templ.c lvgl/src/lv_misc/lv_txt.c lvgl/src/lv_misc/lv_txt_ap.c lvgl/src/lv_misc/lv_utils.c lvgl/src/lv_themes/lv_theme.c lvgl/src/lv_themes/lv_theme_empty.c lvgl/src/lv_themes/lv_theme_material.c lvgl/src/lv_themes/lv_theme_mono.c lvgl/src/lv_themes/lv_theme_template.c lvgl/src/lv_widgets/lv_arc.c lvgl/src/lv_widgets/lv_bar.c lvgl/src/lv_widgets/lv_btn.c lvgl/src/lv_widgets/lv_btnmatrix.c lvgl/src/lv_widgets/lv_calendar.c lvgl/src/lv_widgets/lv_canvas.c lvgl/src/lv_widgets/lv_chart.c lvgl/src/lv_widgets/lv_checkbox.c lvgl/src/lv_widgets/lv_cont.c lvgl/src/lv_widgets/lv_cpicker.c lvgl/src/lv_widgets/lv_dropdown.c lvgl/src/lv_widgets/lv_gauge.c lvgl/src/lv_widgets/lv_img.c lvgl/src/lv_widgets/lv_imgbtn.c lvgl/src/lv_widgets/lv_keyboard.c lvgl/src/lv_widgets/lv_label.c lvgl/src/lv_widgets/lv_led.c lvgl/src/lv_widgets/lv_line.c lvgl/src/lv_widgets/lv_linemeter.c lvgl/src/lv_widgets/lv_list.c lvgl/src/lv_widgets/lv_msgbox.c lvgl/src/lv_widgets/lv_objmask.c lvgl/src/lv_widgets/lv_objx_templ.c lvgl/src/lv_widgets/lv_page.c lvgl/src/lv_widgets/lv_roller.c lvgl/src/lv_widgets/lv_slider.c lvgl/src/lv_widgets/lv_spinbox.c lvgl/src/lv_widgets/lv_spinner.c lvgl/src/lv_widgets/lv_switch.c lvgl/src/lv_widgets/lv_table.c lvgl/src/lv_widgets/lv_tabview.c lvgl/src/lv_widgets/lv_textarea.c lvgl/src/lv_widgets/lv_tileview.c lvgl/src/lv_widgets/lv_win.c lvgl/tests/lv_test_assert.c lvgl/tests/lv_test_core/lv_test_core.c lvgl/tests/lv_test_core/lv_test_font_loader.c lvgl/tests/lv_test_core/lv_test_obj.c lvgl/tests/lv_test_core/lv_test_style.c lvgl/tests/lv_test_fonts/font_1.c lvgl/tests/lv_test_fonts/font_2.c lvgl/tests/lv_test_fonts/font_3.c lvgl/tests/lv_test_main.c lvgl/tests/lv_test_widgets/lv_test_label.c
EXTERNAL_LIBS :=
EXTERNAL_LIBS_COPIED := $(foreach lib, $(EXTERNAL_LIBS),$(BINARYDIR)/$(notdir $(lib)))
CFLAGS += $(COMMONFLAGS)
CXXFLAGS += $(COMMONFLAGS)
ASFLAGS += $(COMMONFLAGS)
LDFLAGS += $(COMMONFLAGS)
CFLAGS += $(addprefix -I,$(INCLUDE_DIRS))
CXXFLAGS += $(addprefix -I,$(INCLUDE_DIRS))
CFLAGS += $(addprefix -D,$(PREPROCESSOR_MACROS))
CXXFLAGS += $(addprefix -D,$(PREPROCESSOR_MACROS))
ifeq ($(USING_KEIL_TOOLCHAIN),1)
ASFLAGS +=$(call macros-to-preprocesor-directives, $(PREPROCESSOR_MACROS))
else ifeq ($(TOOLCHAIN_SUBTYPE),iar)
ASFLAGS := $(subst --cpu=,--cpu ,$(ASFLAGS))
ASFLAGS := $(subst --fpu=,--fpu ,$(ASFLAGS))
ASFLAGS := $(subst --silent,-S ,$(ASFLAGS))
ASFLAGS += $(addprefix -D,$(PREPROCESSOR_MACROS))
else
ASFLAGS += $(addprefix -D,$(PREPROCESSOR_MACROS))
endif
CXXFLAGS += $(addprefix -framework ,$(MACOS_FRAMEWORKS))
CFLAGS += $(addprefix -framework ,$(MACOS_FRAMEWORKS))
LDFLAGS += $(addprefix -framework ,$(MACOS_FRAMEWORKS))
LDFLAGS += $(addprefix -L,$(LIBRARY_DIRS))
ifeq ($(GENERATE_MAP_FILE),1)
LDFLAGS += -Wl,-Map=$(BINARYDIR)/$(basename $(TARGETNAME)).map
endif
LIBRARY_LDFLAGS = $(addprefix -l,$(LIBRARY_NAMES))
ifeq ($(IS_LINUX_PROJECT),1)
RPATH_PREFIX := -Wl,--rpath='$$ORIGIN/../
LIBRARY_LDFLAGS += $(EXTERNAL_LIBS)
LIBRARY_LDFLAGS += -Wl,--rpath='$$ORIGIN'
LIBRARY_LDFLAGS += $(addsuffix ',$(addprefix $(RPATH_PREFIX),$(dir $(EXTERNAL_LIBS))))
ifeq ($(TARGETTYPE),SHARED)
CFLAGS += -fPIC
CXXFLAGS += -fPIC
ASFLAGS += -fPIC
LIBRARY_LDFLAGS += -Wl,-soname,$(TARGETNAME)
endif
ifneq ($(LINUX_PACKAGES),)
PACKAGE_CFLAGS := $(foreach pkg,$(LINUX_PACKAGES),$(shell pkg-config --cflags $(pkg)))
PACKAGE_LDFLAGS := $(foreach pkg,$(LINUX_PACKAGES),$(shell pkg-config --libs $(pkg)))
CFLAGS += $(PACKAGE_CFLAGS)
CXXFLAGS += $(PACKAGE_CFLAGS)
LIBRARY_LDFLAGS += $(PACKAGE_LDFLAGS)
endif
else
LIBRARY_LDFLAGS += $(EXTERNAL_LIBS)
endif
LIBRARY_LDFLAGS += $(ADDITIONAL_LINKER_INPUTS)
all_make_files := $(firstword $(MAKEFILE_LIST)) $(CONFIGURATION_FLAGS_FILE) $(ADDITIONAL_MAKE_FILES)
ifeq ($(STARTUPFILES),)
all_source_files := $(SOURCEFILES)
else
all_source_files := $(STARTUPFILES) $(filter-out $(STARTUPFILES),$(SOURCEFILES))
endif
source_obj1 := $(all_source_files:.cpp=.o)
source_obj2 := $(source_obj1:.c=.o)
source_obj3 := $(source_obj2:.s=.o)
source_obj4 := $(source_obj3:.S=.o)
source_obj5 := $(source_obj4:.cc=.o)
source_objs := $(source_obj5:.cxx=.o)
all_objs := $(addprefix $(BINARYDIR)/, $(notdir $(source_objs)))
PRIMARY_OUTPUTS :=
ifeq ($(GENERATE_BIN_FILE),1)
PRIMARY_OUTPUTS += $(BINARYDIR)/$(basename $(TARGETNAME)).bin
endif
ifeq ($(GENERATE_IHEX_FILE),1)
PRIMARY_OUTPUTS += $(BINARYDIR)/$(basename $(TARGETNAME)).ihex
endif
ifeq ($(PRIMARY_OUTPUTS),)
PRIMARY_OUTPUTS := $(BINARYDIR)/$(TARGETNAME)
endif
all: $(PRIMARY_OUTPUTS)
ifeq ($(USING_KEIL_TOOLCHAIN),1)
$(BINARYDIR)/$(basename $(TARGETNAME)).bin: $(BINARYDIR)/$(TARGETNAME)
$(OBJCOPY) --bin $< --output $#
$(BINARYDIR)/$(basename $(TARGETNAME)).ihex: $(BINARYDIR)/$(TARGETNAME)
$(OBJCOPY) --i32 $< --output $#
else ifeq ($(TOOLCHAIN_SUBTYPE),iar)
$(BINARYDIR)/$(basename $(TARGETNAME)).bin: $(BINARYDIR)/$(TARGETNAME)
$(OBJCOPY) --silent --bin $< $#
$(BINARYDIR)/$(basename $(TARGETNAME)).ihex: $(BINARYDIR)/$(TARGETNAME)
$(OBJCOPY) --silent --bin $< $#
else
$(BINARYDIR)/$(basename $(TARGETNAME)).bin: $(BINARYDIR)/$(TARGETNAME)
$(OBJCOPY) -O binary $< $#
$(BINARYDIR)/$(basename $(TARGETNAME)).ihex: $(BINARYDIR)/$(TARGETNAME)
$(OBJCOPY) -O ihex $< $#
endif
EXTRA_DEPENDENCIES :=
ifneq ($(LINKER_SCRIPT),)
EXTRA_DEPENDENCIES += $(LINKER_SCRIPT)
endif
ifeq ($(TARGETTYPE),APP)
$(BINARYDIR)/$(TARGETNAME): $(all_objs) $(EXTERNAL_LIBS) $(EXTRA_DEPENDENCIES)
ifeq ($(DETACH_CODE_COVERAGE),1)
$(VISUALGDB_DIR)/VisualGDB.exe /decover $# $(all_objs)
endif
$(LD) -o $# $(LDFLAGS) $(START_GROUP) $(all_objs) $(LIBRARY_LDFLAGS) $(END_GROUP)
endif
ifeq ($(TARGETTYPE),SHARED)
$(BINARYDIR)/$(TARGETNAME): $(all_objs) $(EXTERNAL_LIBS) $(EXTRA_DEPENDENCIES)
$(LD) -shared -o $# $(LDFLAGS) $(START_GROUP) $(all_objs) $(LIBRARY_LDFLAGS) $(END_GROUP)
endif
ifeq ($(TARGETTYPE),STATIC)
$(BINARYDIR)/$(TARGETNAME): $(all_objs) $(EXTRA_DEPENDENCIES)
$(AR) -r $# $^
endif
-include $(all_objs:.o=.dep)
clean:
ifeq ($(USE_DEL_TO_CLEAN),1)
cmd /C del /S /Q $(BINARYDIR)
else
rm -rf $(BINARYDIR)
endif
$(BINARYDIR):
mkdir $(BINARYDIR)
#VisualGDB: FileSpecificTemplates #<--- VisualGDB will use the following lines to define rules for source files in subdirectories
$(BINARYDIR)/%.o : %.cpp $(all_make_files) |$(BINARYDIR)
$(CXX) $(CXXFLAGS) -c $< -o $# $(CC_DEPENDENCY_FILE_SPECIFIER) $(#:.o=.dep)
$(BINARYDIR)/%.o : %.c $(all_make_files) |$(BINARYDIR)
$(CC) $(CFLAGS) -c $< -o $# $(CC_DEPENDENCY_FILE_SPECIFIER) $(#:.o=.dep)
$(BINARYDIR)/%.o : %.S $(all_make_files) |$(BINARYDIR)
$(AS) $(ASFLAGS) -c $< -o $# $(ASM_DEPENDENCY_FILE_SPECIFIER) $(#:.o=.dep)
$(BINARYDIR)/%.o : %.s $(all_make_files) |$(BINARYDIR)
$(AS) $(ASFLAGS) -c $< -o $# $(ASM_DEPENDENCY_FILE_SPECIFIER) $(#:.o=.dep)
$(BINARYDIR)/%.o : %.cc $(all_make_files) |$(BINARYDIR)
$(CC) $(CFLAGS) $(CXXFLAGS) -c $< -o $# $(CC_DEPENDENCY_FILE_SPECIFIER) $(#:.o=.dep)
$(BINARYDIR)/%.o : %.cxx $(all_make_files) |$(BINARYDIR)
$(CC) $(CFLAGS) $(CXXFLAGS) -c $< -o $# $(CC_DEPENDENCY_FILE_SPECIFIER)F $(#:.o=.dep)
#VisualGDB: GeneratedRules #<--- All lines below are auto-generated. Remove this line to suppress auto-generation of file rules.
$(BINARYDIR)/lv_port_disp_template.o : lvgl/examples/porting/lv_port_disp_template.c $(all_make_files) |$(BINARYDIR)
$(CC) $(CFLAGS) -c $< -o $# $(CC_DEPENDENCY_FILE_SPECIFIER) $(#:.o=.dep)
$(BINARYDIR)/lv_port_fs_template.o : lvgl/examples/porting/lv_port_fs_template.c $(all_make_files) |$(BINARYDIR)
$(CC) $(CFLAGS) -c $< -o $# $(CC_DEPENDENCY_FILE_SPECIFIER) $(#:.o=.dep)
$(BINARYDIR)/lv_port_indev_template.o : lvgl/examples/porting/lv_port_indev_template.c $(all_make_files) |$(BINARYDIR)
$(CC) $(CFLAGS) -c $< -o $# $(CC_DEPENDENCY_FILE_SPECIFIER) $(#:.o=.dep)
$(BINARYDIR)/lv_disp.o : lvgl/src/lv_core/lv_disp.c $(all_make_files) |$(BINARYDIR)
$(CC) $(CFLAGS) -c $< -o $# $(CC_DEPENDENCY_FILE_SPECIFIER) $(#:.o=.dep)
$(BINARYDIR)/lv_group.o : lvgl/src/lv_core/lv_group.c $(all_make_files) |$(BINARYDIR)
$(CC) $(CFLAGS) -c $< -o $# $(CC_DEPENDENCY_FILE_SPECIFIER) $(#:.o=.dep)
$(BINARYDIR)/lv_indev.o : lvgl/src/lv_core/lv_indev.c $(all_make_files) |$(BINARYDIR)
$(CC) $(CFLAGS) -c $< -o $# $(CC_DEPENDENCY_FILE_SPECIFIER) $(#:.o=.dep)
.............

Related

Makefile doesn't compile all files when I change it

I wrote makefile which seems to works fine except for one case:
When I change the makefile itself it does not recompile all files.
I've done all those steps:
make clean
make all
make all (it returns "Nothing to be done for all") - ok
change makefile (add empty line etc.)
make all (still it returns "Nothing to be done for all" - not ok at all
In my opinion, it should recompile when the makefile file was changed.
What can be improved to force makefile to recompile all files when I make modifications in makefile?
Makefile:
################################### VARIABLES ############################################
# Output settings:
BUILD_DIR := ./build
BIN_DIR := $(BUILD_DIR)/bin
TARGET_FOLDER := $(BUILD_DIR)
TARGET_NAME := app.exe
# Input settings:
SOURCE_DIR = ./
SOURCES := $(SOURCE_DIR)/main.cpp
INCLUDES := $(SOURCE_DIR)
# Compilator settings:
CC := gcc
CXX := g++
# Compilation flags:
COMMON_FLAGS := -Wall -Werror
CFLAGS := $(COMMON_FLAGS)
CXXFLAGS := $(COMMON_FLAGS)
LDFLAGS :=
# VERBOSE OPTION
VERBOSE ?= 0 # Set to zero to silent makefile output
ifeq ($(VERBOSE),1)
NO_ECHO :=
else
NO_ECHO := #
endif
############################### MAGID PART START #########################################
TARGET := $(abspath $(TARGET_FOLDER)/$(TARGET_NAME))
# Remove double slash (//) from path, it can make issue with vpath.
# Just use abspath :)
SOURCES_ABS := $(abspath $(SOURCES) )
INCLUDES_ABS := $(abspath $(INCLUDES) )
SOURCES_C := $(filter %.c, $(SOURCES_ABS) )
SOURCES_CC := $(filter %.cc, $(SOURCES_ABS) )
SOURCES_CPP := $(filter %.cpp, $(SOURCES_ABS) )
OBJECTS_LIST := $(notdir $(patsubst %.c, %.o, $(SOURCES_C) ) )
OBJECTS_LIST += $(notdir $(patsubst %.cc, %.o, $(SOURCES_CC) ) )
OBJECTS_LIST += $(notdir $(patsubst %.cpp, %.o, $(SOURCES_CPP) ) )
OBJECTS := $(addprefix $(BIN_DIR)/, $(OBJECTS_LIST) )
DEPENDENCIES := $(patsubst %.o, %.d, $(OBJECTS) )
INCLUDES_FLAG := $(addprefix -I, $(INCLUDES_ABS) )
COMMON_FLAGS += $(INCLUDES_FLAG)
COMMON_FLAGS += -MMD -MP # Generate dependency files
CFLAGS += $(COMMON_FLAGS)
CXXFLAGS += $(COMMON_FLAGS)
# Use vpath to search sources:
VPATH += $(sort $(dir $(SOURCES_C) ) )
VPATH += $(sort $(dir $(SOURCES_CC) ) )
VPATH += $(sort $(dir $(SOURCES_CPP) ) )
all: app
app: $(TARGET)
$(TARGET): $(OBJECTS) | $(BUILD_DIR)
$(info Preparing: $#)
$(NO_ECHO) $(CXX) $(CXXFLAGS) -o $# $^
$(BIN_DIR)/%.o : %.c | $(BIN_DIR)
$(info Preparing: $#)
$(NO_ECHO) $(CC) -c $(CFLAGS) $< -o $#
$(BIN_DIR)/%.o : %.cc | $(BIN_DIR)
$(info Preparing: $#)
$(NO_ECHO) $(CXX) -c $(CXXFLAGS) $< -o $#
$(BIN_DIR)/%.o : %.cpp | $(BIN_DIR)
$(info Preparing: $#)
$(NO_ECHO) $(CXX) -c $(CXXFLAGS) $< -o $#
$(BIN_DIR): |$(BUILD_DIR)
$(NO_ECHO) -mkdir $#
$(BUILD_DIR):
$(NO_ECHO) -mkdir $#
.PHONY : clean
clean:
-rm -fr $(TARGET) $(BUILD_DIR) *.o *.d
-include $(DEPENDENCIES)
main.cpp
#include <iostream>
using namespace std;
int main(void)
{
cout<<"HA HA"<<endl;
return 0;
}

How to output .o files into one specific folder?

I'm currently using MinGW64, G++, and a makefile to compile my c++ project on VSCode. I have two src directories src and src/vendor/imGui containing .cpp files that I compile. As of now, the makefile is able to compile both src folders. However, the .o files are outputted in their respective src folders. How can I make it so that every .o file generated gets sent to one specific folder/directory?
Current Makefile:
CXX = g++
CXXFLAGS := -std=c++17 -Wall -Wextra -g
LFLAGS += -LC:/mingw64/x86_64-w64-mingw32/bin
LFLAGS += -LC:/mingw64/x86_64-w64-mingw32/lib
OUTPUT := output
SRC := src
SRC += src/vendor/imGui
INCLUDE := include
LIB := lib
ifeq ($(OS),Windows_NT)
MAIN := main.exe
SOURCEDIRS := $(SRC)
INCLUDEDIRS := $(INCLUDE)
LIBDIRS := $(LIB)
FIXPATH = $(subst /,\,$1)
RM := del /q /f
MD := mkdir
else
MAIN := main
SOURCEDIRS := $(shell find $(SRC) -type d)
INCLUDEDIRS := $(shell find $(INCLUDE) -type d)
LIBDIRS := $(shell find $(LIB) -type d)
FIXPATH = $1
RM = rm -f
MD := mkdir -p
endif
INCLUDES := $(patsubst %,-I%, $(INCLUDEDIRS:%/=%))
INCLUDES += -IC:/Users/kimda/Desktop/Projects/C++/Libraries/glm
INCLUDES += -IC:/mingw64/x86_64-w64-mingw32/include
INCLUDES += -IC:/Users/kimda/Desktop/Projects/C++/OpenGL/src/vendor/imGui
LIBS := $(patsubst %,-L%, $(LIBDIRS:%/=%))
LIBS += -lglew32
LIBS += -lopengl32
LIBS += -lglfw3
LIBS += -lgdi32
LIBS += -lglu32
SOURCES := $(wildcard $(patsubst %,%/*.cpp, $(SOURCEDIRS)))
OBJECTS := $(SOURCES:.cpp=.o)
OUTPUTMAIN := $(call FIXPATH,$(OUTPUT)/$(MAIN))
all: $(OUTPUT) $(MAIN)
#echo Building complete!
$(OUTPUT):
#$(MD) $(OUTPUT)
$(MAIN): $(OBJECTS)
#$(CXX) $(CXXFLAGS) $(INCLUDES) -o $(OUTPUTMAIN) $(OBJECTS) $(LFLAGS) $(LIBS)
.cpp.o:
#$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $#
.PHONY: clean
clean:
#$(RM) $(OUTPUTMAIN)
#$(RM) $(call FIXPATH,$(OBJECTS))
#echo Cleanup complete!
run: clean all
#./$(OUTPUTMAIN)
#echo Executing complete!
If I understand you correctly you want to send all object files to some 'build' directory.
I usually do something like this
BUILDDIR := build
[...]
OBJECTS := $(addprefix $(BUILDDIR)/,$(SOURCES:.cpp=.o))
[...]
and then change your
.cpp.o:
#$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $#
to
$(BUILDDIR)/%.o: %.cpp
#$(MD) $(dir $#)
#$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $#

Project is not linking GLFW

so I have a project with multiple dependencies of the following structure:
Dependencies
- Glad
- GLFW
- ImGui
Engine
Sandbox
Engine includes the dependencies and Sandbox includes Engine
Project files are generated by premake5.
This compiles and runs perfectly under Windows, but today i tried to port it to linux.
I generated makefiles by using the linux version of premake.
All files do compile successfully, but when the linking process starts i get the following error:
==== Building Sandbox (debug) ====
Linking Sandbox
../Engine/vendor/GLFW/bin/Debug-linux-x86_64/GLFW/libGLFW.a(context.o): In function _glfwRefreshContextAttribs':
/home/netcode/Engine/Engine/vendor/GLFW/src/context.c:361: undefined reference to_glfwPlatformGetTls'
../Engine/vendor/GLFW/bin/Debug-linux-x86_64/GLFW/libGLFW.a(context.o): In function glfwMakeContextCurrent':<br>
/home/netcode/Engine/Engine/vendor/GLFW/src/context.c:614: undefined reference to_glfwPlatformGetTls'
../Engine/vendor/GLFW/bin/Debug-linux-x86_64/GLFW/libGLFW.a(context.o): In function glfwGetCurrentContext':
/home/netcode/Engine/Engine/vendor/GLFW/src/context.c:638: undefined reference to_glfwPlatformGetTls'
../Engine/vendor/GLFW/bin/Debug-linux-x86_64/GLFW/libGLFW.a(context.o): In function glfwSwapInterval':
/home/netcode/Engine/Engine/vendor/GLFW/src/context.c:664: undefined reference to_glfwPlatformGetTls'
../Engine/vendor/GLFW/bin/Debug-linux-x86_64/GLFW/libGLFW.a(context.o): In function glfwExtensionSupported':
/home/netcode/Engine/Engine/vendor/GLFW/src/context.c:682: undefined reference to_glfwPlatformGetTls'...
and so on...
this is the final makefile:
# Alternative GNU Make project makefile autogenerated by Premake
ifndef config
config=debug
endif
ifndef verbose
SILENT = #
endif
.PHONY: clean prebuild
SHELLTYPE := posix
ifeq (.exe,$(findstring .exe,$(ComSpec)))
SHELLTYPE := msdos
endif
# Configurations
# #############################################
RESCOMP = windres
INCLUDES += -I../Engine/vendor/spdlog/include -I../Engine/src -I../Engine/vendor -I../Engine/vendor/glm -Isrc
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LINKCMD = $(CXX) -o "$#" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
define PREBUILDCMDS
endef
define PRELINKCMDS
endef
define POSTBUILDCMDS
endef
ifeq ($(config),debug)
TARGETDIR = ../bin/Debug-linux-x86_64/Sandbox
TARGET = $(TARGETDIR)/Sandbox
OBJDIR = ../bin-int/Debug-linux-x86_64/Sandbox
DEFINES += -DENGINE_DEBUG
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m64 -g
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS) -m64 -g -std=c++17
LIBS += ../bin/Debug-linux-x86_64/Engine/libEngine.a ../Engine/vendor/GLFW/bin/Debug-linux-x86_64/GLFW/libGLFW.a ../Engine/vendor/Glad/bin/Debug-linux-x86_64/Glad/libGlad.a ../Engine/vendor/imgui/bin/Debug-linux-x86_64/ImGui/libImGui.a -lXrandr -lXi -lGLEW -lGLU -lGL -lX11 -ldl -lpthread -lstdc++fs
LDDEPS += ../bin/Debug-linux-x86_64/Engine/libEngine.a ../Engine/vendor/GLFW/bin/Debug-linux-x86_64/GLFW/libGLFW.a ../Engine/vendor/Glad/bin/Debug-linux-x86_64/Glad/libGlad.a ../Engine/vendor/imgui/bin/Debug-linux-x86_64/ImGui/libImGui.a
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib64 -m64
else ifeq ($(config),release)
TARGETDIR = ../bin/Release-linux-x86_64/Sandbox
TARGET = $(TARGETDIR)/Sandbox
OBJDIR = ../bin-int/Release-linux-x86_64/Sandbox
DEFINES += -DENGINE_RELEASE
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m64 -O2
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS) -m64 -O2 -std=c++17
LIBS += ../bin/Release-linux-x86_64/Engine/libEngine.a ../Engine/vendor/GLFW/bin/Release-linux-x86_64/GLFW/libGLFW.a ../Engine/vendor/Glad/bin/Release-linux-x86_64/Glad/libGlad.a ../Engine/vendor/imgui/bin/Release-linux-x86_64/ImGui/libImGui.a -lXrandr -lXi -lGLEW -lGLU -lGL -lX11 -ldl -lpthread -lstdc++fs
LDDEPS += ../bin/Release-linux-x86_64/Engine/libEngine.a ../Engine/vendor/GLFW/bin/Release-linux-x86_64/GLFW/libGLFW.a ../Engine/vendor/Glad/bin/Release-linux-x86_64/Glad/libGlad.a ../Engine/vendor/imgui/bin/Release-linux-x86_64/ImGui/libImGui.a
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib64 -m64 -s
else ifeq ($(config),dist)
TARGETDIR = ../bin/Dist-linux-x86_64/Sandbox
TARGET = $(TARGETDIR)/Sandbox
OBJDIR = ../bin-int/Dist-linux-x86_64/Sandbox
DEFINES += -DENGINE_DIST
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m64 -O2
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS) -m64 -O2 -std=c++17
LIBS += ../bin/Dist-linux-x86_64/Engine/libEngine.a ../Engine/vendor/GLFW/bin/Dist-linux-x86_64/GLFW/libGLFW.a ../Engine/vendor/Glad/bin/Dist-linux-x86_64/Glad/libGlad.a ../Engine/vendor/imgui/bin/Dist-linux-x86_64/ImGui/libImGui.a -lXrandr -lXi -lGLEW -lGLU -lGL -lX11 -ldl -lpthread -lstdc++fs
LDDEPS += ../bin/Dist-linux-x86_64/Engine/libEngine.a ../Engine/vendor/GLFW/bin/Dist-linux-x86_64/GLFW/libGLFW.a ../Engine/vendor/Glad/bin/Dist-linux-x86_64/Glad/libGlad.a ../Engine/vendor/imgui/bin/Dist-linux-x86_64/ImGui/libImGui.a
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib64 -m64 -s
else
$(error "invalid configuration $(config)")
endif
# Per File Configurations
# #############################################
# File sets
# #############################################
OBJECTS :=
OBJECTS += $(OBJDIR)/Sandbox2D.o
OBJECTS += $(OBJDIR)/SandboxApp.o
# Rules
# #############################################
all: $(TARGET)
#:
$(TARGET): $(OBJECTS) $(LDDEPS) | $(TARGETDIR)
$(PRELINKCMDS)
#echo Linking Sandbox
$(SILENT) $(LINKCMD)
$(POSTBUILDCMDS)
$(TARGETDIR):
#echo Creating $(TARGETDIR)
ifeq (posix,$(SHELLTYPE))
$(SILENT) mkdir -p $(TARGETDIR)
else
$(SILENT) mkdir $(subst /,\\,$(TARGETDIR))
endif
$(OBJDIR):
#echo Creating $(OBJDIR)
ifeq (posix,$(SHELLTYPE))
$(SILENT) mkdir -p $(OBJDIR)
else
$(SILENT) mkdir $(subst /,\\,$(OBJDIR))
endif
clean:
#echo Cleaning Sandbox
ifeq (posix,$(SHELLTYPE))
$(SILENT) rm -f $(TARGET)
$(SILENT) rm -rf $(OBJDIR)
else
$(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET))
$(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR))
endif
prebuild: | $(OBJDIR)
$(PREBUILDCMDS)
ifneq (,$(PCH))
$(OBJECTS): $(GCH) | $(PCH_PLACEHOLDER)
$(GCH): $(PCH) | prebuild
#echo $(notdir $<)
$(SILENT) $(CXX) -x c++-header $(ALL_CXXFLAGS) -o "$#" -MF "$(#:%.gch=%.d)" -c "$<"
$(PCH_PLACEHOLDER): $(GCH) | $(OBJDIR)
ifeq (posix,$(SHELLTYPE))
$(SILENT) touch "$#"
else
$(SILENT) echo $null >> "$#"
endif
else
$(OBJECTS): | prebuild
endif
# File Rules
# #############################################
$(OBJDIR)/Sandbox2D.o: src/Sandbox2D.cpp
#echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$#" -MF "$(#:%.o=%.d)" -c "$<"
$(OBJDIR)/SandboxApp.o: src/SandboxApp.cpp
#echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$#" -MF "$(#:%.o=%.d)" -c "$<"
-include $(OBJECTS:%.o=%.d)
ifneq (,$(PCH))
-include $(PCH_PLACEHOLDER).d
endif
any guesses?

Recursive Makefile to build .o files

I am writing a simple kernel and all is going well so far.
I am using a Makefile to build the system through the shell.
However, I wish to move and reorganise the file structure but, my the makefile uses absolute linking.
How can I refactor this to compile all .cpp/.c files and .s files to an out folder and link them, without needing to define each folder path?
CC = ~/opt/cross/bin/i386-elf-g++
AS = ~/opt/cross/bin/i386-elf-as
LNFLAGS = -T linker.ld -melf_i386
CCFLAGS = -c -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions
ASFLAGS = -c
CTMP = $(wildcard src/kernel/*.cpp)
ATMP = $(wildcard src/kernel/arch/i386/*.s)
CFILE = $(subst src/kernel/, ,$(CTMP))
AFILE = $(subst src/kernel/arch/i386/, ,$(ATMP))
CSRC = $(CFILE:.c=)
ASRC = $(AFILE:.s=)
OUT = $(wildcard out/*.o)
all: ccompile acompile link
ccompile:
for file in $(CSRC) ; do \
$(CC) $(CCFLAGS) src/kernel/$$file -o out/$$file.o ; \
done
acompile:
for file in $(ASRC) ; do \
$(AS) $(ASFLAGS) src/kernel/arch/i386/$$file.s -o out/$$file.o ; \
done
link:
ld $(LNFLAGS) -o latest.bin $(OUT)
Use the vpath directive to specifiy the source directories.
TARGETS := latest.bin
LD := ld
LDFLAGS := -T linker.ld -melf_i386
CC := ~/opt/cross/bin/i386-elf-g++
CCFLAGS := -c -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions
AS := ~/opt/cross/bin/i386-elf-as
ASFLAGS := -c
vpath %.cpp src/kernel
vpath %.s src/kernel/arch/i386
SOURCES := $(wildcard *.cpp) $(wildcard *.s)
OBJECTS := $(addsuffix .o, $(basename $(notdir $(SOURCES))))
all: $(TARGETS)
out/%.o: %.cpp
$(CC) $(CCFLAGS) -o $# $<
out/%.o: %.s
$(AS) $(ASFLAGS) -o $# $<
latest.bin: $(OBJECTS)
$(LD) $(LDFLAGS) -o $# $^

Adding c++ to complex C makefile

I would like to add a cpp file to use the c functions. I made the file but the problem becomes how to include the file in the makefile.All I know is that I should compile with c++ after C. and then link it together.
May someone point me in the right direction.
This is a snippet of testcpp.cpp
extern "C" {
#include "darknet.h"
}
Below is the makefile but i keep getting No rule to make target 'obj/test.cpp', needed by 'darknet'.
GPU=0
CUDNN=0
OPENCV=0
NNPACK=1
NNPACK_FAST=1
ARM_NEON=1
OPENMP=0
DEBUG=0
QPU_GEMM=1
ARCH= -gencode arch=compute_30,code=sm_30 \
-gencode arch=compute_35,code=sm_35 \
-gencode arch=compute_50,code=[sm_50,compute_50] \
-gencode arch=compute_52,code=[sm_52,compute_52]
# -gencode arch=compute_20,code=[sm_20,sm_21] \ This one is deprecated?
# This is what I use, uncomment if you know your arch and want to specify
# ARCH= -gencode arch=compute_52,code=compute_52
VPATH=./src/:./examples
SLIB=libdarknet.so
ALIB=libdarknet.a
EXEC=darknet
OBJDIR=./obj/
CC=gcc
NVCC=nvcc
AR=ar
ARFLAGS=rcs
OPTS=-Ofast
LDFLAGS= -lm -pthread
COMMON= -Iinclude/ -Isrc/
#CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC
#CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC -march=native -mfpmath=sse
CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC -mcpu=cortex-a53
ifeq ($(OPENMP), 1)
CFLAGS+= -fopenmp
endif
ifeq ($(DEBUG), 1)
OPTS=-O0 -g
endif
CFLAGS+=$(OPTS)
ifeq ($(OPENCV), 1)
COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv`
COMMON+= `pkg-config --cflags opencv`
endif
ifeq ($(GPU), 1)
COMMON+= -DGPU -I/usr/local/cuda/include/
CFLAGS+= -DGPU
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endif
ifeq ($(CUDNN), 1)
COMMON+= -DCUDNN
CFLAGS+= -DCUDNN
LDFLAGS+= -lcudnn
endif
ifeq ($(QPU_GEMM), 1)
COMMON+= -DQPU_GEMM
CFLAGS+= -DQPU_GEMM
LDFLAGS+= -lqmkl
endif
ifeq ($(NNPACK), 1)
COMMON+= -DNNPACK
CFLAGS+= -DNNPACK
LDFLAGS+= -lnnpack -lpthreadpool
endif
ifeq ($(NNPACK_FAST), 1)
COMMON+= -DNNPACK_FAST
CFLAGS+= -DNNPACK_FAST
endif
ifeq ($(ARM_NEON), 1)
COMMON+= -DARM_NEON
CFLAGS+= -DARM_NEON -mfpu=neon-vfpv4 -funsafe-math-optimizations -ftree-vectorize
endif
OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o detection_layer.o route_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o lstm_layer.o
EXECOBJA=captcha.o lsd.o super.o art.o tag.o cifar.o go.o rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o attention.o darknet.o
EXECOBJA1=testcpp.cpp
ifeq ($(GPU), 1)
LDFLAGS+= -lstdc++
OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o avgpool_layer_kernels.o
endif
EXECOBJ = $(addprefix $(OBJDIR), $(EXECOBJA))
EXECOBJ1 = $(addprefix $(OBJDIR), $(EXECOBJA1))
OBJS = $(addprefix $(OBJDIR), $(OBJ))
DEPS = $(wildcard src/*.h) Makefile include/darknet.h
CPP=g++
#all: obj backup results $(SLIB) $(ALIB) $(EXEC)
all: obj results $(SLIB) $(ALIB) $(EXEC)
$(EXEC): $(EXECOBJ) $(ALIB)
$(CC) $(COMMON) $(CFLAGS) $^ -o $# $(LDFLAGS) $(ALIB)
$(EXEC): $(EXECOBJ1)
$(CPP) -Wall $^ -o $# $(LDFLAGS)
$(ALIB): $(OBJS)
$(AR) $(ARFLAGS) $# $^
$(SLIB): $(OBJS)
$(CPP) $(CFLAGS) -shared $^ -o $#
$(OBJDIR)%.o: %.c $(DEPS)
$(CC) $(COMMON) $(CFLAGS) -c $< -o $#
$(OBJDIR)%.o: %.cu $(DEPS)
$(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $#
obj:
mkdir -p obj
backup:
mkdir -p backup
results:
mkdir -p results
.PHONY: clean
clean:
rm -rf $(OBJS) $(SLIB) $(ALIB) $(EXEC) $(EXECOBJ)
I thought
$(EXEC): $(EXECOBJ1)
$(CPP) -Wall $^ -o $# $(LDFLAGS)
would compile the cpp file and
$(OBJDIR)%.o: %.c $(DEPS)
$(CC) $(COMMON) $(CFLAGS) -c $< -o $#
would link it
I think you need a recipe to compile object files from .cpp file:
$(OBJDIR)%.o: %.cpp $(DEPS)
$(CXX) $(COMMON) $(CFLAGS) -c $< -o $#
The error you describe probably comes from an incorrect usage of vpath: I don't think its usage is necessary here.
But basically I agree with #Basile Starynkevitch : you might be better rewriting from scratch. I have a few suggestions:
1 - Clearly separate in different folders programs (C or C++ files that hold a main() function) and library files (C or C++ files that hold functions). This will be useful for linking.
For example:
|
+--lib // holds "library" code
+--app // holds programs
+--headers
+--BUILD
|
+-- obj
| |
| +-- app
| +-- lib
|
+-- bin
2 - Automatically generate both object files and programs from source files:
SRC_FILES_LIB = $(wildcard lib/*.cpp)
SRC_FILES_APP = $(wildcard app/*.cpp)
OBJ_FILES_LIB = $(patsubst lib/%.cpp,BUILD/obj/lib/%.o,$(SRC_FILES_LIB))
OBJ_FILES_APP = $(patsubst app/%.cpp,BUILD/obj/app/%.o,$(SRC_FILES_APP))
EXEC_FILES = $(patsubst app/%.cpp,BUILD/bin/%,$(SRC_FILES_APP))
3 - add a target that builds the programs:
all: $(EXEC_FILES)
#echo "done"
After that, its just a matter of providing the sufficient pattern rule.
(sorry, no more time for that)