I am using autotools to build a project. I have a configure.ac, makefile.am and autogen.sh. This all works great. My Jenkins pipeline can pick this up and run it. My issue is the makefile.am is getting longer and longer. Recently I added some 3rd part vendor code to my project.
This is the current makefile.am
AUTOMAKE_OPTIONS = foreign subdir-objects
bin_PROGRAMS = MAIN_Application
MAIN_Application_LDADD = -lsocketcan -lpthread -lm
AM_CPPFLAGS = \
-I$(srcdir)/include \
-I$(srcdir)/include/utilities \
-I$(srcdir)/include/comms \
-I$(srcdir)/include/config_parsing \
-I$(srcdir)/vendor/my_vendor/host/include \
-I$(srcdir)/vendor/my_vendor/host/source/lib/comm_mgr/inc \
-I$(srcdir)/vendor/my_vendor/host/source/lib/mem_pool/inc \
-I$(srcdir)/vendor/my_vendor/host/source/lib/osal/inc \
-I$(srcdir)/vendor/my_vendor/production/source/lib/FFT \
-I$(srcdir)/vendor/my_vendor/public/common \
-I$(srcdir)/vendor/my_vendor/public/host \
-I$(srcdir)/vendor/my_vendor/public/production
MAIN_Application_SOURCES = \
src/main.cpp \
src/scheduler.c \
src/thread_health.c \
src/signal_handler.c \
src/utilities/time_conversions.c \
src/utilities/ring_buffer.c \
src/utilities/logger.c \
src/utilities/string_operations.c \
src/config_parsing/file_operations.c \
src/config_parsing/config_parser.c \
src/comms/can.c \
src/comms/can_ring_buffer.c \
vendor/my_vendor/production/source/lib/FFT/FFT.c \
vendor/my_vendor/production/source/PROD_lib.c \
vendor/my_vendor/host/source/HLB_helper.c \
vendor/my_vendor/host/source/HLB_nscm.c \
vendor/my_vendor/host/source/HLB_apcm.c \
vendor/my_vendor/host/source/HLB_fwload.c \
vendor/my_vendor/host/source/HLB_host.c \
vendor/my_vendor/host/source/HLB_noise_floor.c \
vendor/my_vendor/host/source/lib/mem_pool/src/mem_pool.c \
vendor/my_vendor/host/source/lib/comm_mgr/src/comm_mgr_lib.c \
vendor/my_vendor/host/source/lib/osal/src/osal.c \
vendor/my_vendor/host/source/HLB_legacy_commands.c \
vendor/my_vendor/host/source/HLB_protocol.c
Do I really have to include each .c file individually? Why does vendor/my_vendor/host/*/** not work? How can I compress this makefile.am?
Autotools developers consider it to be best practice to explicitly list all the source files. This avoids things like test or debug sources etc. creeping into distribution packages.
You can't use ** because this syntax is a non-standard extension available specifically in shells like bash and zsh, that is not supported by standard POSIX globbing (which is what make uses for its glob expansion).
I think it would work to use simple globbing (that is, *.c) in Makefile.am but of course you'd still need to use each directory.
Just to add:
You can also make your makefile "tidier" by breaking up the sources into sections. So for example you might have something like:
MAIN_Application_SOURCES = \
src/main.cpp \
src/scheduler.c \
src/thread_health.c \
src/signal_handler.c
MAIN_Application_SOURCES += \
src/utilities/time_conversions.c \
src/utilities/ring_buffer.c \
src/utilities/logger.c \
src/utilities/string_operations.c
MAIN_Application_SOURCES += \
src/config_parsing/file_operations.c \
src/config_parsing/config_parser.c
MAIN_Application_SOURCES += \
src/comms/can.c \
src/comms/can_ring_buffer.c
MAIN_Application_SOURCES += \
vendor/my_vendor/production/source/lib/FFT/FFT.c \
vendor/my_vendor/production/source/PROD_lib.c \
vendor/my_vendor/host/source/HLB_helper.c \
vendor/my_vendor/host/source/HLB_nscm.c \
vendor/my_vendor/host/source/HLB_apcm.c \
vendor/my_vendor/host/source/HLB_fwload.c \
vendor/my_vendor/host/source/HLB_host.c \
vendor/my_vendor/host/source/HLB_noise_floor.c \
vendor/my_vendor/host/source/lib/mem_pool/src/mem_pool.c \
vendor/my_vendor/host/source/lib/comm_mgr/src/comm_mgr_lib.c \
vendor/my_vendor/host/source/lib/osal/src/osal.c \
vendor/my_vendor/host/source/HLB_legacy_commands.c \
vendor/my_vendor/host/source/HLB_protocol.c
or something like that, or you could even use other variables and then add them together. Maybe that helps with readability.
When I click on Run on my VeinsTutorial (the one that Christoph Sommer made and you might be familiar with it), I get error shown below. Do you have any idea? I really need to get over this error.
Error refreshing Makefiles
Reason:
you have both .cc and .cpp files -- specify -e cc or -e cpp option to select which set of files to use
make MODE=release all
make: *** No rule to make target 'all'. Stop.
"make MODE=release all" terminated with exit code 2. Build might be incomplete.
'
'Simulation terminated with exit code: 1
<!> Error: NED type 'veinstutorial.src.TutorialAppl' could not be fully resolved due to a missing base type or interface, at C:\Users\konra\git\repository\carlogicapi-master\carlogicapi-master\tutorials\VeinsTutorial\src\TutorialAppl.ned:19
End.
This is the MAKEFILES FILE where I should change something, but I cannot see where it should be changed.
#
# OMNeT++/OMNEST Makefile for $(LIB_PREFIX)veins
#
# This file was generated with the command:
# opp_makemake --make-so -f --deep -o veins -O out -pVEINS -I. -I.
#
# Name of target to be created (-o option)
TARGET = $(LIB_PREFIX)veins$(D)$(SHARED_LIB_SUFFIX)
TARGET_DIR = .
# C++ include paths (with -I)
INCLUDE_PATH = -I. -I.
# Additional object and library files to link with
EXTRA_OBJS =
# Additional libraries (-L, -l options)
LIBS =
# Output directory
PROJECT_OUTPUT_DIR = ../out
PROJECTRELATIVE_PATH = src
O = $(PROJECT_OUTPUT_DIR)/$(CONFIGNAME)/$(PROJECTRELATIVE_PATH)
# Object files for local .cc, .msg and .sm files
OBJS = \
$O/veins/base/connectionManager/BaseConnectionManager.o \
$O/veins/base/connectionManager/ChannelAccess.o \
$O/veins/base/connectionManager/ConnectionManager.o \
$O/veins/base/connectionManager/NicEntryDebug.o \
$O/veins/base/connectionManager/NicEntryDirect.o \
$O/veins/base/modules/BaseApplLayer.o \
$O/veins/base/modules/BaseBattery.o \
$O/veins/base/modules/BaseLayer.o \
$O/veins/base/modules/BaseMacLayer.o \
$O/veins/base/modules/BaseMobility.o \
$O/veins/base/modules/BaseModule.o \
$O/veins/base/modules/BaseWorldUtility.o \
$O/veins/base/modules/BatteryAccess.o \
$O/veins/base/phyLayer/Antenna.o \
$O/veins/base/phyLayer/BaseDecider.o \
$O/veins/base/phyLayer/BasePhyLayer.o \
$O/veins/base/phyLayer/ChannelInfo.o \
$O/veins/base/phyLayer/Decider.o \
$O/veins/base/phyLayer/PhyUtils.o \
$O/veins/base/toolbox/Signal.o \
$O/veins/base/toolbox/SignalUtils.o \
$O/veins/base/toolbox/Spectrum.o \
$O/veins/base/utils/Coord.o \
$O/veins/base/utils/Heading.o \
$O/veins/base/utils/NetwToMacControlInfo.o \
$O/veins/base/utils/SimpleAddress.o \
$O/veins/base/utils/winsupport.o \
$O/veins/modules/analogueModel/BreakpointPathlossModel.o \
$O/veins/modules/analogueModel/NakagamiFading.o \
$O/veins/modules/analogueModel/PERModel.o \
$O/veins/modules/analogueModel/SimpleObstacleShadowing.o \
$O/veins/modules/analogueModel/SimplePathlossModel.o \
$O/veins/modules/analogueModel/TwoRayInterferenceModel.o \
$O/veins/modules/analogueModel/VehicleObstacleShadowing.o \
$O/veins/modules/application/ieee80211p/DemoBaseApplLayer.o \
$O/veins/modules/application/traci/MyVeinsApp.o \
$O/veins/modules/application/traci/TraCIDemo11p.o \
$O/veins/modules/application/traci/TraCIDemoRSU11p.o \
$O/veins/modules/mac/ieee80211p/Mac1609_4.o \
$O/veins/modules/mobility/LinearMobility.o \
$O/veins/modules/mobility/traci/TraCIBuffer.o \
$O/veins/modules/mobility/traci/TraCIColor.o \
$O/veins/modules/mobility/traci/TraCICommandInterface.o \
$O/veins/modules/mobility/traci/TraCIConnection.o \
$O/veins/modules/mobility/traci/TraCICoordinateTransformation.o \
$O/veins/modules/mobility/traci/TraCILauncher.o \
$O/veins/modules/mobility/traci/TraCIMobility.o \
$O/veins/modules/mobility/traci/TraCIRegionOfInterest.o \
$O/veins/modules/mobility/traci/TraCIScenarioManager.o \
$O/veins/modules/mobility/traci/TraCIScenarioManagerForker.o \
$O/veins/modules/mobility/traci/TraCIScenarioManagerLaunchd.o \
$O/veins/modules/mobility/traci/TraCIScreenRecorder.o \
$O/veins/modules/mobility/traci/TraCIVehicleInserter.o \
$O/veins/modules/obstacle/MobileHostObstacle.o \
$O/veins/modules/obstacle/Obstacle.o \
$O/veins/modules/obstacle/ObstacleControl.o \
$O/veins/modules/obstacle/VehicleObstacleControl.o \
$O/veins/modules/phy/Decider80211p.o \
$O/veins/modules/phy/NistErrorRate.o \
$O/veins/modules/phy/PhyLayer80211p.o \
$O/veins/modules/phy/SampledAntenna1D.o \
$O/veins/modules/utility/BBoxLookup.o \
$O/veins/modules/utility/HasLogProxy.o \
$O/veins/modules/utility/TimerManager.o \
$O/veins/modules/world/annotations/AnnotationDummy.o \
$O/veins/modules/world/annotations/AnnotationManager.o \
$O/veins/modules/world/traci/trafficLight/TraCITrafficLightInterface.o \
$O/veins/modules/world/traci/trafficLight/TraCITrafficLightProgram.o \
$O/veins/modules/world/traci/trafficLight/logics/TraCITrafficLightAbstractLogic.o \
$O/veins/modules/world/traci/trafficLight/logics/TraCITrafficLightSimpleLogic.o \
$O/veins/base/messages/AirFrame_m.o \
$O/veins/base/messages/BorderMsg_m.o \
$O/veins/base/messages/MacPkt_m.o \
$O/veins/modules/application/traci/TraCIDemo11pMessage_m.o \
$O/veins/modules/messages/AckTimeOutMessage_m.o \
$O/veins/modules/messages/AirFrame11p_m.o \
$O/veins/modules/messages/BaseFrame1609_4_m.o \
$O/veins/modules/messages/DemoSafetyMessage_m.o \
$O/veins/modules/messages/DemoServiceAdvertisement_m.o \
$O/veins/modules/messages/Mac80211Ack_m.o \
$O/veins/modules/messages/Mac80211Pkt_m.o \
$O/veins/modules/messages/PhyControlMessage_m.o \
$O/veins/modules/messages/TraCITrafficLightMessage_m.o \
$O/veins/modules/messages/WaveShortMessage_m.o
# Message files
MSGFILES = \
veins/base/messages/AirFrame.msg \
veins/base/messages/BorderMsg.msg \
veins/base/messages/MacPkt.msg \
veins/modules/application/traci/TraCIDemo11pMessage.msg \
veins/modules/messages/AckTimeOutMessage.msg \
veins/modules/messages/AirFrame11p.msg \
veins/modules/messages/BaseFrame1609_4.msg \
veins/modules/messages/DemoSafetyMessage.msg \
veins/modules/messages/DemoServiceAdvertisement.msg \
veins/modules/messages/Mac80211Ack.msg \
veins/modules/messages/Mac80211Pkt.msg \
veins/modules/messages/PhyControlMessage.msg \
veins/modules/messages/TraCITrafficLightMessage.msg \
veins/modules/messages/WaveShortMessage.msg
# SM files
SMFILES =
#------------------------------------------------------------------------------
# Pull in OMNeT++ configuration (Makefile.inc)
ifneq ("$(OMNETPP_CONFIGFILE)","")
CONFIGFILE = $(OMNETPP_CONFIGFILE)
else
ifneq ("$(OMNETPP_ROOT)","")
CONFIGFILE = $(OMNETPP_ROOT)/Makefile.inc
else
CONFIGFILE = $(shell opp_configfilepath)
endif
endif
ifeq ("$(wildcard $(CONFIGFILE))","")
$(error Config file '$(CONFIGFILE)' does not exist -- add the OMNeT++ bin directory to the path so that opp_configfilepath can be found, or set the OMNETPP_CONFIGFILE variable to point to Makefile.inc)
endif
include $(CONFIGFILE)
# Simulation kernel and user interface libraries
OMNETPP_LIBS = -loppenvir$D $(KERNEL_LIBS) $(SYS_LIBS)
COPTS = $(CFLAGS) $(IMPORT_DEFINES) -DVEINS_EXPORT $(INCLUDE_PATH) -I$(OMNETPP_INCL_DIR)
MSGCOPTS = $(INCLUDE_PATH) -PVEINS_API
SMCOPTS =
# we want to recompile everything if COPTS changes,
# so we store COPTS into $COPTS_FILE and have object
# files depend on it (except when "make depend" was called)
COPTS_FILE = $O/.last-copts
ifneq ("$(COPTS)","$(shell cat $(COPTS_FILE) 2>/dev/null || echo '')")
$(shell $(MKPATH) "$O" && echo "$(COPTS)" >$(COPTS_FILE))
endif
#------------------------------------------------------------------------------
# User-supplied makefile fragment(s)
# >>>
# inserted from file 'makefrag':
#
# Copyright (C) 2017 Rudolf Hornig <rudi#omnetpp.org>
#
# Documentation for these modules is at http://veins.car2x.org/
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# on windows we have to link with the ws2_32 (winsock2) library as it is no longer added to the omnetpp system libraries by default (as of OMNeT++ 5.1)
# copied from INET Framework (inet-3.6.0) makefrag
#
ifeq ($(PLATFORM),win32.x86_64)
LIBS += -lws2_32
DEFINES += -DVEINS_EXPORT
ENABLE_AUTO_IMPORT=-Wl,--enable-auto-import
LDFLAGS := $(filter-out $(ENABLE_AUTO_IMPORT), $(LDFLAGS))
endif
# <<<
#------------------------------------------------------------------------------
# Main target
all: $(TARGET_DIR)/$(TARGET)
$(TARGET_DIR)/% :: $O/%
#mkdir -p $(TARGET_DIR)
$(Q)$(LN) $< $#
ifeq ($(TOOLCHAIN_NAME),clangc2)
$(Q)-$(LN) $(<:%.dll=%.lib) $(#:%.dll=%.lib)
endif
$O/$(TARGET): $(OBJS) $(wildcard $(EXTRA_OBJS)) Makefile $(CONFIGFILE)
#$(MKPATH) $O
#echo Creating shared library: $#
$(Q)echo >.tmp$$$$ $(OBJS) $(EXTRA_OBJS) && $(AR) .tmplib$$$$ #.tmp$$$$ && $(SHLIB_LD) -o $O/$(TARGET) $(AS_NEEDED_OFF) $(WHOLE_ARCHIVE_ON) .tmplib$$$$ $(LIBS) $(WHOLE_ARCHIVE_OFF) $(OMNETPP_LIBS) $(LDFLAGS) && rm .tmp$$$$ && rm .tmplib$$$$
$(Q)$(SHLIB_POSTPROCESS) $O/$(TARGET)
.PHONY: all clean cleanall depend msgheaders smheaders
.SUFFIXES: .cc
$O/%.o: %.cc $(COPTS_FILE) | msgheaders smheaders
#$(MKPATH) $(dir $#)
$(qecho) "$<"
$(Q)$(CXX) -c $(CXXFLAGS) $(COPTS) -o $# $<
%_m.cc %_m.h: %.msg
$(qecho) MSGC: $<
$(Q)$(MSGC) -s _m.cc -MD -MP -MF $O/$(basename $<)_m.h.d $(MSGCOPTS) $?
%_sm.cc %_sm.h: %.sm
$(qecho) SMC: $<
$(Q)$(SMC) -c++ -suffix cc $(SMCOPTS) $?
msgheaders: $(MSGFILES:.msg=_m.h)
smheaders: $(SMFILES:.sm=_sm.h)
clean:
$(qecho) Cleaning $(TARGET)
$(Q)-rm -rf $O
$(Q)-rm -f $(TARGET_DIR)/$(TARGET)
$(Q)-rm -f $(TARGET_DIR)/$(TARGET:%.dll=%.lib)
$(Q)-rm -f $(call opp_rwildcard, . , *_m.cc *_m.h *_sm.cc *_sm.h)
cleanall:
$(Q)$(MAKE) -s clean MODE=release
$(Q)$(MAKE) -s clean MODE=debug
$(Q)-rm -rf $(PROJECT_OUTPUT_DIR)
# include all dependencies
-include $(OBJS:%=%.d) $(MSGFILES:%.msg=$O/%_m.h.d) ```
I just had to change the extension of the TutorialAppl.cpp to CC.
I guess sometimes we look for the difficult way to solve problems and it is actually the easy way you have to take :)
Thanks for your attention.
When I run make clean then make DEBUG=1, it correctly compiles my file. If I want to add another argument I should be able to type make DEBUG=1 SIMULATE=1 but it doesn't recompile with the new C_FLAG.
This is the spot in the makefile where object files are created. When I specify %.c.o: $(C_FLAGS) it still doesn't recompile.
# $1 command
# $2 flags
# $3 message
define run
$(info $(call PROGRESS,$(3) file: $(notdir $($#)))) \
$(NO_ECHO)$(1) -MP -MD -c -o $# $(call get_path,$($#)) $(2) $(INC_PATHS)
endef
# Create object files from C source files
%.c.o:
$(call run,$(CC) -std=c99,$(CFLAGS),Compiling)
# Create object files from C++ source files
%.cpp.o:
$(call run,$(CXX),$(CFLAGS) $(CXXFLAGS),Compiling)
# Create object files from assembly source files
%.S.o %.s.o.o:
$(call run,$(CC) -x assembler-with-cpp,$(ASMFLAGS),Assembling)
makefile
PROJECT_NAME := ble_app_hts_pca10040_s132
TARGETS := nrf52832_xxaa
OUTPUT_DIRECTORY := _build
SDK_ROOT := ../../../../../..
PROJ_DIR := ../../..
$(OUTPUT_DIRECTORY)/nrf52832_xxaa.out: \
LINKER_SCRIPT := ble_app_hts_gcc_nrf52.ld
######################################
# building variables
######################################
# debug build?
DEBUG ?= 0
DEBUG_PIN ?= 0
BAUDRATE ?= 0
# simulation build?
SIMULATE ?= 0
# devkit build?
DEVKIT ?= 0
# optimization
OPT = -O3
# Source files common to all targets
SRC_FILES += \
$(PROJ_DIR)/Src/main.c \
$(PROJ_DIR)/Src/battery.c \
$(PROJ_DIR)/Src/tension.c \
$(PROJ_DIR)/Src/temperature.c \
$(PROJ_DIR)/Src/ble_hts_custom.c \
$(PROJ_DIR)/Src/accelerometer.c \
$(PROJ_DIR)/Src/bma2x2.c \
$(SDK_ROOT)/components/ble/ble_services/ble_nus/ble_nus.c \
$(SDK_ROOT)/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_saadc.c \
$(SDK_ROOT)/modules/nrfx/mdk/gcc_startup_nrf52.S \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_backend_rtt.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_backend_serial.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_backend_uart.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_default_backends.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_frontend.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_str_formatter.c \
$(SDK_ROOT)/components/libraries/button/app_button.c \
$(SDK_ROOT)/components/libraries/util/app_error.c \
$(SDK_ROOT)/components/libraries/util/app_error_handler_gcc.c \
$(SDK_ROOT)/components/libraries/util/app_error_weak.c \
$(SDK_ROOT)/components/libraries/scheduler/app_scheduler.c \
$(SDK_ROOT)/components/libraries/timer/app_timer.c \
$(SDK_ROOT)/components/libraries/util/app_util_platform.c \
$(SDK_ROOT)/components/libraries/crc16/crc16.c \
$(SDK_ROOT)/components/libraries/fds/fds.c \
$(SDK_ROOT)/components/libraries/hardfault/hardfault_implementation.c \
$(SDK_ROOT)/components/libraries/util/nrf_assert.c \
$(SDK_ROOT)/components/libraries/atomic_fifo/nrf_atfifo.c \
$(SDK_ROOT)/components/libraries/atomic_flags/nrf_atflags.c \
$(SDK_ROOT)/components/libraries/atomic/nrf_atomic.c \
$(SDK_ROOT)/components/libraries/balloc/nrf_balloc.c \
$(SDK_ROOT)/external/fprintf/nrf_fprintf.c \
$(SDK_ROOT)/external/fprintf/nrf_fprintf_format.c \
$(SDK_ROOT)/components/libraries/fstorage/nrf_fstorage.c \
$(SDK_ROOT)/components/libraries/fstorage/nrf_fstorage_sd.c \
$(SDK_ROOT)/components/libraries/memobj/nrf_memobj.c \
$(SDK_ROOT)/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c \
$(SDK_ROOT)/components/libraries/ringbuf/nrf_ringbuf.c \
$(SDK_ROOT)/components/libraries/experimental_section_vars/nrf_section_iter.c \
$(SDK_ROOT)/components/libraries/strerror/nrf_strerror.c \
$(SDK_ROOT)/components/libraries/sensorsim/sensorsim.c \
$(SDK_ROOT)/modules/nrfx/mdk/system_nrf52.c \
$(SDK_ROOT)/components/boards/boards.c \
$(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_clock.c \
$(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_uart.c \
$(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_spi.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_clock.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_gpiote.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_power_clock.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/prs/nrfx_prs.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_uart.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_uarte.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_spim.c \
$(SDK_ROOT)/components/libraries/bsp/bsp.c \
$(SDK_ROOT)/components/libraries/bsp/bsp_btn_ble.c \
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT.c \
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_Syscalls_GCC.c \
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_printf.c \
$(SDK_ROOT)/components/ble/peer_manager/auth_status_tracker.c \
$(SDK_ROOT)/components/ble/common/ble_advdata.c \
$(SDK_ROOT)/components/ble/ble_advertising/ble_advertising.c \
$(SDK_ROOT)/components/ble/common/ble_conn_params.c \
$(SDK_ROOT)/components/ble/common/ble_conn_state.c \
$(SDK_ROOT)/components/ble/common/ble_srv_common.c \
$(SDK_ROOT)/components/ble/peer_manager/gatt_cache_manager.c \
$(SDK_ROOT)/components/ble/peer_manager/gatts_cache_manager.c \
$(SDK_ROOT)/components/ble/peer_manager/id_manager.c \
$(SDK_ROOT)/components/ble/nrf_ble_gatt/nrf_ble_gatt.c \
$(SDK_ROOT)/components/ble/nrf_ble_qwr/nrf_ble_qwr.c \
$(SDK_ROOT)/components/ble/peer_manager/peer_data_storage.c \
$(SDK_ROOT)/components/ble/peer_manager/peer_database.c \
$(SDK_ROOT)/components/ble/peer_manager/peer_id.c \
$(SDK_ROOT)/components/ble/peer_manager/peer_manager.c \
$(SDK_ROOT)/components/ble/peer_manager/peer_manager_handler.c \
$(SDK_ROOT)/components/ble/peer_manager/pm_buffer.c \
$(SDK_ROOT)/components/ble/peer_manager/security_dispatcher.c \
$(SDK_ROOT)/components/ble/peer_manager/security_manager.c \
$(SDK_ROOT)/external/utf_converter/utf.c \
$(SDK_ROOT)/components/ble/ble_services/ble_bas/ble_bas.c \
$(SDK_ROOT)/components/ble/ble_services/ble_dis/ble_dis.c \
$(SDK_ROOT)/components/softdevice/common/nrf_sdh.c \
$(SDK_ROOT)/components/softdevice/common/nrf_sdh_ble.c \
$(SDK_ROOT)/components/softdevice/common/nrf_sdh_soc.c \
# Include folders common to all targets
INC_FOLDERS += \
$(PROJ_DIR)/Inc \
$(SDK_ROOT)/components/ble/ble_services/ble_nus \
$(SDK_ROOT)/components/ble/ble_link_ctx_manager \
$(SDK_ROOT)/components/nfc/ndef/generic/message \
$(SDK_ROOT)/components/nfc/t2t_lib \
$(SDK_ROOT)/components/nfc/t4t_parser/hl_detection_procedure \
$(SDK_ROOT)/components/ble/ble_services/ble_ancs_c \
$(SDK_ROOT)/components/ble/ble_services/ble_ias_c \
$(SDK_ROOT)/components/libraries/pwm \
$(SDK_ROOT)/components/softdevice/s132/headers/nrf52 \
$(SDK_ROOT)/components/libraries/usbd/class/cdc/acm \
$(SDK_ROOT)/components/libraries/usbd/class/hid/generic \
$(SDK_ROOT)/components/libraries/usbd/class/msc \
$(SDK_ROOT)/components/libraries/usbd/class/hid \
$(SDK_ROOT)/modules/nrfx/hal \
$(SDK_ROOT)/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser \
$(SDK_ROOT)/components/libraries/log \
$(SDK_ROOT)/components/ble/ble_services/ble_gls \
$(SDK_ROOT)/components/libraries/fstorage \
$(SDK_ROOT)/components/nfc/ndef/text \
$(SDK_ROOT)/components/libraries/mutex \
$(SDK_ROOT)/components/libraries/gpiote \
$(SDK_ROOT)/components/libraries/bootloader/ble_dfu \
$(SDK_ROOT)/components/nfc/ndef/connection_handover/common \
$(SDK_ROOT)/components/boards \
$(SDK_ROOT)/components/nfc/ndef/generic/record \
$(SDK_ROOT)/components/nfc/t4t_parser/cc_file \
$(SDK_ROOT)/components/ble/ble_advertising \
$(SDK_ROOT)/external/utf_converter \
$(SDK_ROOT)/components/ble/ble_services/ble_bas_c \
$(SDK_ROOT)/modules/nrfx/drivers/include \
$(SDK_ROOT)/components/libraries/experimental_task_manager \
$(SDK_ROOT)/components/ble/ble_services/ble_hrs_c \
$(SDK_ROOT)/components/nfc/ndef/connection_handover/le_oob_rec \
$(SDK_ROOT)/components/libraries/queue \
$(SDK_ROOT)/components/libraries/pwr_mgmt \
$(SDK_ROOT)/components/ble/ble_dtm \
$(SDK_ROOT)/components/toolchain/cmsis/include \
$(SDK_ROOT)/components/ble/ble_services/ble_rscs_c \
$(SDK_ROOT)/components/ble/common \
$(SDK_ROOT)/components/ble/ble_services/ble_lls \
$(SDK_ROOT)/components/libraries/bsp \
$(SDK_ROOT)/components/nfc/ndef/connection_handover/ac_rec \
$(SDK_ROOT)/components/ble/ble_services/ble_bas \
$(SDK_ROOT)/components/libraries/mpu \
$(SDK_ROOT)/components/libraries/experimental_section_vars \
$(SDK_ROOT)/components/softdevice/s132/headers \
$(SDK_ROOT)/components/ble/ble_services/ble_ans_c \
$(SDK_ROOT)/components/libraries/slip \
$(SDK_ROOT)/components/libraries/delay \
$(SDK_ROOT)/components/libraries/mem_manager \
$(SDK_ROOT)/components/libraries/csense_drv \
$(SDK_ROOT)/components/libraries/memobj \
$(SDK_ROOT)/components/ble/ble_services/ble_nus_c \
$(SDK_ROOT)/components/softdevice/common \
$(SDK_ROOT)/components/ble/ble_services/ble_ias \
$(SDK_ROOT)/components/libraries/usbd/class/hid/mouse \
$(SDK_ROOT)/components/libraries/low_power_pwm \
$(SDK_ROOT)/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser \
$(SDK_ROOT)/components/ble/ble_services/ble_dfu \
$(SDK_ROOT)/external/fprintf \
$(SDK_ROOT)/components/libraries/svc \
$(SDK_ROOT)/components/libraries/atomic \
$(SDK_ROOT)/components \
$(SDK_ROOT)/components/libraries/scheduler \
$(SDK_ROOT)/components/libraries/cli \
$(SDK_ROOT)/components/ble/ble_services/ble_lbs \
$(SDK_ROOT)/components/libraries/crc16 \
$(SDK_ROOT)/components/nfc/t4t_parser/apdu \
$(SDK_ROOT)/components/libraries/util \
../config \
$(SDK_ROOT)/components/libraries/usbd/class/cdc \
$(SDK_ROOT)/components/libraries/csense \
$(SDK_ROOT)/components/libraries/balloc \
$(SDK_ROOT)/components/libraries/ecc \
$(SDK_ROOT)/components/libraries/hardfault \
$(SDK_ROOT)/components/ble/ble_services/ble_cscs \
$(SDK_ROOT)/components/libraries/hci \
$(SDK_ROOT)/components/libraries/usbd/class/hid/kbd \
$(SDK_ROOT)/components/libraries/timer \
$(SDK_ROOT)/integration/nrfx \
$(SDK_ROOT)/components/nfc/t4t_parser/tlv \
$(SDK_ROOT)/components/libraries/sortlist \
$(SDK_ROOT)/components/libraries/spi_mngr \
$(SDK_ROOT)/components/libraries/led_softblink \
$(SDK_ROOT)/components/nfc/ndef/conn_hand_parser \
$(SDK_ROOT)/components/libraries/sdcard \
$(SDK_ROOT)/components/nfc/ndef/parser/record \
$(SDK_ROOT)/modules/nrfx/mdk \
$(SDK_ROOT)/components/ble/ble_services/ble_cts_c \
$(SDK_ROOT)/components/ble/ble_services/ble_nus \
$(SDK_ROOT)/components/libraries/twi_mngr \
$(SDK_ROOT)/components/ble/ble_services/ble_hids \
$(SDK_ROOT)/components/libraries/strerror \
$(SDK_ROOT)/components/libraries/crc32 \
$(SDK_ROOT)/components/nfc/ndef/connection_handover/ble_oob_advdata \
$(SDK_ROOT)/components/nfc/t2t_parser \
$(SDK_ROOT)/components/nfc/ndef/connection_handover/ble_pair_msg \
$(SDK_ROOT)/components/libraries/usbd/class/audio \
$(SDK_ROOT)/components/nfc/t4t_lib/hal_t4t \
$(SDK_ROOT)/components/libraries/sensorsim \
$(SDK_ROOT)/components/nfc/t4t_lib \
$(SDK_ROOT)/components/ble/peer_manager \
$(SDK_ROOT)/components/drivers_nrf/usbd \
$(SDK_ROOT)/components/libraries/ringbuf \
$(SDK_ROOT)/components/ble/ble_services/ble_tps \
$(SDK_ROOT)/components/nfc/ndef/parser/message \
$(SDK_ROOT)/components/ble/ble_services/ble_dis \
$(SDK_ROOT)/components/nfc/ndef/uri \
$(SDK_ROOT)/components/ble/nrf_ble_gatt \
$(SDK_ROOT)/components/ble/nrf_ble_qwr \
$(SDK_ROOT)/components/libraries/gfx \
$(SDK_ROOT)/components/libraries/button \
$(SDK_ROOT)/modules/nrfx \
$(SDK_ROOT)/components/libraries/twi_sensor \
$(SDK_ROOT)/integration/nrfx/legacy \
$(SDK_ROOT)/components/libraries/usbd \
$(SDK_ROOT)/components/nfc/ndef/connection_handover/ep_oob_rec \
$(SDK_ROOT)/external/segger_rtt \
$(SDK_ROOT)/components/libraries/atomic_fifo \
$(SDK_ROOT)/components/ble/ble_services/ble_lbs_c \
$(SDK_ROOT)/components/nfc/ndef/connection_handover/ble_pair_lib \
$(SDK_ROOT)/components/libraries/crypto \
$(SDK_ROOT)/components/ble/ble_racp \
$(SDK_ROOT)/components/libraries/fds \
$(SDK_ROOT)/components/nfc/ndef/launchapp \
$(SDK_ROOT)/components/libraries/atomic_flags \
$(SDK_ROOT)/components/ble/ble_services/ble_hrs \
$(SDK_ROOT)/components/ble/ble_services/ble_rscs \
$(SDK_ROOT)/components/nfc/ndef/connection_handover/hs_rec \
$(SDK_ROOT)/components/nfc/t2t_lib/hal_t2t \
$(SDK_ROOT)/components/nfc/ndef/conn_hand_parser/ac_rec_parser \
$(SDK_ROOT)/components/libraries/stack_guard \
$(SDK_ROOT)/components/libraries/log/src \
# Libraries common to all targets
LIB_FILES += \
# Debug option
ifeq ($(DEBUG), 1)
# use 'make sdk_config -> nRF_Log -> NRF_LOG_BACKEND_UART_ENABLED' to see default params
C_DEFS += -DDEBUG
C_DEFS += -DNRF_LOG_ENABLED=1
C_DEFS += -DNRF_LOG_BACKEND_UART_ENABLED=1
ifneq ($(DEBUG_PIN), 0)
C_DEFS += -DNRF_LOG_BACKEND_UART_TX_PIN=$(DEBUG_PIN)
endif
ifneq ($(BAUDRATE), 0)
C_DEFS += -DNRF_LOG_BACKEND_UART_BAUDRATE=$(BAUDRATE)
endif
OPT = -Og
endif
ifeq ($(SIMULATE), 1)
C_DEFS += -DSIMULATE
endif
ifeq ($(DEVKIT), 1)
C_DEFS += -DDEVKIT
endif
# C flags common to all targets
CFLAGS += $(OPT)
CFLAGS += -DBOARD_PCA10040
CFLAGS += -DCONFIG_GPIO_AS_PINRESET
CFLAGS += -DCONFIG_NFCT_PINS_AS_GPIOS
CFLAGS += -DFLOAT_ABI_HARD
CFLAGS += -DNRF52
CFLAGS += -DNRF52832_XXAA
CFLAGS += -DNRF52_PAN_74
CFLAGS += -DNRF_SD_BLE_API_VERSION=6
CFLAGS += -DS132
CFLAGS += -DSOFTDEVICE_PRESENT
CFLAGS += -DSWI_DISABLE0
CFLAGS += -mcpu=cortex-m4
CFLAGS += -mthumb -mabi=aapcs
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
# keep every function in a separate section, this allows linker to discard unused ones
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
CFLAGS += -fno-builtin -fshort-enums
CFLAGS += -Wall -g3
CFLAGS += $(C_DEFS)
# CFLAGS += -Werror # if you want warnings treated as errors
# C++ flags common to all targets
CXXFLAGS += $(OPT) -std=c++1z
# Assembler flags common to all targets
ASMFLAGS += -g3
ASMFLAGS += -mcpu=cortex-m4
ASMFLAGS += -mthumb -mabi=aapcs
ASMFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
ASMFLAGS += -DBOARD_PCA10040
ASMFLAGS += -DCONFIG_GPIO_AS_PINRESET
ASMFLAGS += -DFLOAT_ABI_HARD
ASMFLAGS += -DNRF52
ASMFLAGS += -DNRF52832_XXAA
ASMFLAGS += -DNRF52_PAN_74
ASMFLAGS += -DNRF_SD_BLE_API_VERSION=6
ASMFLAGS += -DS132
ASMFLAGS += -DSOFTDEVICE_PRESENT
ASMFLAGS += -DSWI_DISABLE0
# Linker flags
LDFLAGS += $(OPT)
LDFLAGS += -mthumb -mabi=aapcs -L$(SDK_ROOT)/modules/nrfx/mdk -T$(LINKER_SCRIPT)
LDFLAGS += -mcpu=cortex-m4
LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
# let linker dump unused sections
LDFLAGS += -Wl,--gc-sections
# use newlib in nano version
LDFLAGS += --specs=nano.specs
nrf52832_xxaa: CFLAGS += -D__HEAP_SIZE=8192
nrf52832_xxaa: CFLAGS += -D__STACK_SIZE=8192
nrf52832_xxaa: ASMFLAGS += -D__HEAP_SIZE=8192
nrf52832_xxaa: ASMFLAGS += -D__STACK_SIZE=8192
# Add standard libraries at the very end of the linker input, after all objects
# that may need symbols provided by these libraries.
LIB_FILES += -lc -lnosys -lm
.PHONY: default help
# Default target - first one defined
default: nrf52832_xxaa
# Print all targets that can be built
help:
#echo following targets are available:
#echo nrf52832_xxaa
#echo flash_softdevice
#echo sdk_config - starting external tool for editing sdk_config.h
#echo flash - flashing binary
TEMPLATE_PATH := $(SDK_ROOT)/components/toolchain/gcc
include $(TEMPLATE_PATH)/Makefile.common
$(foreach target, $(TARGETS), $(call define_target, $(target)))
.PHONY: flash flash_softdevice erase
UNAME := $(shell uname)
clean:
ifeq ($(UNAME), Linux)
sudo rm -rf _build
else
#echo os not supported for clean target
endif
flash: clean
sudo $(MAKE) -j8 DEBUG=$(DEBUG) DEBUG_PIN=$(DEBUG_PIN) SIMULATE=$(SIMULATE) DEVKIT=$(DEVKIT) default
#echo Flashing: $(OUTPUT_DIRECTORY)/nrf52832_xxaa.hex
nrfjprog -f nrf52 --program $(OUTPUT_DIRECTORY)/nrf52832_xxaa.hex --sectorerase
nrfjprog -f nrf52 --reset
flash_noclean: default
#echo Flashing: $(OUTPUT_DIRECTORY)/nrf52832_xxaa.hex
nrfjprog -f nrf52 --program $(OUTPUT_DIRECTORY)/nrf52832_xxaa.hex --sectorerase
nrfjprog -f nrf52 --reset
flash_softdevice:
#echo Flashing: s132_nrf52_6.1.0_softdevice.hex
nrfjprog -f nrf52 --program $(SDK_ROOT)/components/softdevice/s132/hex/s132_nrf52_6.1.0_softdevice.hex --sectorerase
nrfjprog -f nrf52 --reset
erase:
nrfjprog -f nrf52 --eraseall
SDK_CONFIG_FILE := ../config/sdk_config.h
CMSIS_CONFIG_TOOL := $(SDK_ROOT)/external_tools/cmsisconfig/CMSIS_Configuration_Wizard.jar
sdk_config:
java -jar $(CMSIS_CONFIG_TOOL) $(SDK_CONFIG_FILE)
makefile.common (invoked from the above makefile)
# Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form, except as embedded into a Nordic
# Semiconductor ASA integrated circuit in a product or a software update for
# such product, must reproduce the above copyright notice, this list of
# conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# 3. Neither the name of Nordic Semiconductor ASA nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# 4. This software, with or without modification, must only be used with a
# Nordic Semiconductor ASA integrated circuit.
#
# 5. Any software provided in binary form under this license must not be reverse
# engineered, decompiled, modified and/or disassembled.
#
# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Options:
# VERBOSE=1 (default is 0) - print each executed command
# PRETTY=1 (default is 0) - show progress, in percentage
# ABSOLUTE_PATHS=1 (default is 0) - convert all include folders and source
# file paths to their absolute forms
# PASS_INCLUDE_PATHS_VIA_FILE=1 (default is 0) - use <target>.inc file
# to pass include paths to gcc
# PASS_LINKER_INPUT_VIA_FILE=0 (default is 1) - don't use <target>.in file
# to pass the list of linker input files
VERBOSE ?= 0
PRETTY ?= 0
ABSOLUTE_PATHS ?= 0
PASS_INCLUDE_PATHS_VIA_FILE ?= 0
PASS_LINKER_INPUT_VIA_FILE ?= 1
.SUFFIXES: # ignore built-in rules
%.d: # don't try to make .d files
.PRECIOUS: %.d %.o
MK := mkdir
RM := rm -rf
# echo suspend
ifeq ($(VERBOSE),1)
NO_ECHO :=
else
NO_ECHO := #
endif
ifneq (,$(filter clean, $(MAKECMDGOALS)))
OTHER_GOALS := $(filter-out clean, $(MAKECMDGOALS))
ifneq (, $(OTHER_GOALS))
$(info Cannot make anything in parallel with "clean".)
$(info Execute "$(MAKE) clean \
$(foreach goal, $(OTHER_GOALS),&& $(MAKE) $(goal))" instead.)
$(error Cannot continue)
else
.PHONY: clean
clean:
$(RM) $(OUTPUT_DIRECTORY)
endif # ifneq(, $(OTHER_GOALS))
else # ifneq (,$(filter clean, $(MAKECMDGOALS)))
ifndef PROGRESS
ifeq ($(PRETTY),1)
X := #
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
TOTAL := $(subst $(SPACE),,$(filter $(X), \
$(shell "$(MAKE)" $(MAKECMDGOALS) --dry-run \
--no-print-directory PROGRESS=$(X))))
5 := $(X)$(X)$(X)$(X)$(X)
25 := $(5)$(5)$(5)$(5)$(5)
100 := $(25)$(25)$(25)$(25)
C :=
COUNTER = $(eval C := $(C)$(100))$(C)
P :=
count = $(if $(filter $1%,$2),$(eval \
P += 1)$(call count,$1,$(2:$1%=%)),$(eval \
C := $2))
print = [$(if $(word 99,$1),99,$(if $(word 10,$1),, )$(words $1))%]
PROGRESS = $(call count,$(TOTAL),$(COUNTER))$(call print,$(P)) $1
else
PROGRESS = $1
endif # ifeq ($(PRETTY),1)
PLATFORM_SUFFIX := $(if $(filter Windows%,$(OS)),windows,posix)
TOOLCHAIN_CONFIG_FILE := $(TEMPLATE_PATH)/Makefile.$(PLATFORM_SUFFIX)
include $(TOOLCHAIN_CONFIG_FILE)
# $1 path
define quote
'$(subst ','\'',$(1))'
endef
# Toolchain commands
CC := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-gcc)
CXX := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-c++)
AS := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-as)
AR := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-ar) -r
LD := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-ld)
NM := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-nm)
OBJDUMP := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-objdump)
OBJCOPY := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-objcopy)
SIZE := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-size)
$(if $(shell $(CC) --version),,$(info Cannot find: $(CC).) \
$(info Please set values in: "$(abspath $(TOOLCHAIN_CONFIG_FILE))") \
$(info according to the actual configuration of your system.) \
$(error Cannot continue))
# Use ccache on linux if available
CCACHE := $(if $(filter Windows%,$(OS)),, \
$(if $(wildcard /usr/bin/ccache),ccache))
CC := $(CCACHE) $(CC)
endif # ifndef PROGRESS
# $1 type of item
# $2 items paths to check
define ensure_exists_each
$(foreach item, $(2), \
$(if $(wildcard $(item)),, $(warning Cannot find $(1): $(item))))
endef
ifeq ($(PASS_INCLUDE_PATHS_VIA_FILE),1)
INC_PATHS = #$($#_INC)
GENERATE_INC_FILE := 1
else
INC_PATHS = $(call target_specific, INC_PATHS, $($#_TGT))
GENERATE_INC_FILE :=
endif
# $1 object file
# $2 source file
# $3 include paths container file
# $4 target name
define bind_obj_with_src
$(eval $(1) := $(2)) \
$(eval $(1)_INC := $(3)) \
$(eval $(1)_TGT := $(4)) \
$(eval $(1): Makefile | $(dir $(1)).) \
$(if $(GENERATE_INC_FILE), $(eval $(1): $(3)))
endef
# $1 target name
# $2 source file name
# Note: this additional .o for .s files is a workaround for issues with make 4.1
# from MinGW (it does nothing to remake .s.o files when a rule for .S.o
# files is defined as well).
define get_object_file_name
$(OUTPUT_DIRECTORY)/$(strip $(1))/$(notdir $(2:%.s=%.s.o)).o
endef
# $1 target name
# $2 include paths container file
# $3 list of source files
define get_object_files
$(call ensure_exists_each,source file, $(3)) \
$(foreach src_file, $(3), \
$(eval obj_file := $(call get_object_file_name, $(1), $(src_file))) \
$(eval DEPENDENCIES += $(obj_file:.o=.d)) \
$(call bind_obj_with_src, $(obj_file), $(src_file), $(2), $(1)) \
$(obj_file))
endef
# $1 variable name
# $2 target name
define target_specific
$($(addsuffix _$(strip $(2)), $(1)))
endef
ifeq ($(ABSOLUTE_PATHS),1)
get_path = $(call quote,$(abspath $1))
else
get_path = $1
endif
# $1 list of include folders
define get_inc_paths
$(call ensure_exists_each,include folder,$(1)) \
$(foreach folder,$(1),-I$(call get_path,$(folder)))
endef
# $1 target name
# $2 include paths container file
# $3 build goal name
define prepare_build
$(eval DEPENDENCIES :=) \
$(eval $(3): \
$(call get_object_files, $(1), $(2), \
$(SRC_FILES) $(call target_specific, SRC_FILES, $(1)))) \
$(eval -include $(DEPENDENCIES)) \
$(eval INC_PATHS_$(strip $(1)) := \
$(call get_inc_paths, \
$(INC_FOLDERS) $(call target_specific, INC_FOLDERS, $(1))))
endef
# $1 target name
define define_target
$(eval OUTPUT_FILE := $(OUTPUT_DIRECTORY)/$(strip $(1))) \
$(eval $(1): $(OUTPUT_FILE).out $(OUTPUT_FILE).hex $(OUTPUT_FILE).bin \
; #echo DONE $(strip $(1))) \
$(call prepare_build, $(1), $(OUTPUT_FILE).inc, $(OUTPUT_FILE).out)
endef
# $1 target name
# $2 library file name
define define_library
$(eval OUTPUT_FILE := $(OUTPUT_DIRECTORY)/$(strip $(1))) \
$(eval $(1) := $(2)) \
$(call prepare_build, $(1), $(OUTPUT_FILE).inc, $(1))
endef
# $1 content to be dumped
# Invokes another instance of MAKE to dump the specified content to stdout,
# which may be then redirected in shell to a file and this way stored there.
# MAKE in version prior to 4.0 does not provide the $(file ...) function.
define dump
$(eval CONTENT_TO_DUMP := $(1)) \
"$(MAKE)" -s --no-print-directory \
-f "$(TEMPLATE_PATH)/dump.mk" VARIABLE=CONTENT_TO_DUMP
endef
export CONTENT_TO_DUMP
.PHONY: $(TARGETS) all
all: $(TARGETS)
# Create build directories
$(OUTPUT_DIRECTORY):
$(MK) $#
$(OUTPUT_DIRECTORY)/%/.: | $(OUTPUT_DIRECTORY)
cd $(OUTPUT_DIRECTORY) && $(MK) $*
$(OUTPUT_DIRECTORY)/%.inc: Makefile | $(OUTPUT_DIRECTORY)
$(info Generating $#)
$(NO_ECHO)$(call dump, $(call target_specific, INC_PATHS, $*)) > $#
# $1 command
# $2 flags
# $3 message
define run
$(info $(call PROGRESS,$(3) file: $(notdir $($#)))) \
$(NO_ECHO)$(1) -MP -MD -c -o $# $(call get_path,$($#)) $(2) $(INC_PATHS)
endef
# Create object files from C source files
%.c.o:
$(call run,$(CC) -std=c99,$(CFLAGS),Compiling)
# Create object files from C++ source files
%.cpp.o:
$(call run,$(CXX),$(CFLAGS) $(CXXFLAGS),Compiling)
# Create object files from assembly source files
%.S.o %.s.o.o:
$(call run,$(CC) -x assembler-with-cpp,$(ASMFLAGS),Assembling)
ifeq ($(PASS_LINKER_INPUT_VIA_FILE),1)
GENERATE_LD_INPUT_FILE = $(call dump, $^ $(LIB_FILES)) > $(#:.out=.in)
LD_INPUT = #$(#:.out=.in)
else
GENERATE_LD_INPUT_FILE =
LD_INPUT = $^ $(LIB_FILES)
endif
# Link object files
%.out:
$(info $(call PROGRESS,Linking target: $#))
$(NO_ECHO)$(GENERATE_LD_INPUT_FILE)
$(NO_ECHO)$(CC) $(LDFLAGS) $(LD_INPUT) -Wl,-Map=$(#:.out=.map) -o $#
$(NO_ECHO)$(SIZE) $#
# Create binary .bin file from the .out file
%.bin: %.out
$(info Preparing: $#)
$(NO_ECHO)$(OBJCOPY) -O binary $< $#
# Create binary .hex file from the .out file
%.hex: %.out
$(info Preparing: $#)
$(NO_ECHO)$(OBJCOPY) -O ihex $< $#
endif # ifneq (,$(filter clean, $(MAKECMDGOALS)))
I want make to recompile whenever I use a new argument.
I think the easiest way in this Makefile would be to use different OUTPUT_DIRECTORY for each switch configuration that you care about. You can make different variants yourself or generalize, like so:
OUTPUT_DIRECTORY = $(shell echo $(CFLAGS) $(CXXFLAGS) | sha1sum | cut -f1 -d\ )
$(info Using output directory: $(OUTPUT_DIRECTORY))
.PHONY: all
all: $(OUTPUT_DIRECTORY)/foo
$(OUTPUT_DIRECTORY)/.:
mkdir -p $#
$(OUTPUT_DIRECTORY)/%: | $(OUTPUT_DIRECTORY)/.
touch $#
Output:
$ make
Using output directory: adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
mkdir -p adc83b19e793491b1c6ea0fd8b46cd9f32e592fc/.
touch adc83b19e793491b1c6ea0fd8b46cd9f32e592fc/foo
$ make CFLAGS=-g
Using output directory: 4e3223fc5750f1d1ef94845b09843555aee23f69
mkdir -p 4e3223fc5750f1d1ef94845b09843555aee23f69/.
touch 4e3223fc5750f1d1ef94845b09843555aee23f69/foo
$ make CFLAGS=-g
Using output directory: 4e3223fc5750f1d1ef94845b09843555aee23f69
make: Nothing to be done for 'all'.
$ make CFLAGS="-g -O2"
Using output directory: 29020c30ba848fbbf4c208ae78b5ed0362b24ce3
mkdir -p 29020c30ba848fbbf4c208ae78b5ed0362b24ce3/.
touch 29020c30ba848fbbf4c208ae78b5ed0362b24ce3/foo
Might require fine-tuning since $(OUTPUT_DIRECTORY) will be resolved when expanded (and therefore sha1sum counted many times - costly), but actual solution depends on where exactly variables are set.
below code from AOSP build/core/Makefile
If someone set INSTALLED_RAMDISK_TARGET as empty(by accident) then recoveryimage will have no RAMDISK
How can I check if each of the dependencies is empty or not?
or is there any other suggestion?
1016 $(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
1017 $(INSTALLED_RAMDISK_TARGET) \
1018 $(INSTALLED_BOOTIMAGE_TARGET) \
1019 $(INTERNAL_RECOVERYIMAGE_FILES) \
1020 $(recovery_initrc) $(recovery_sepolicy) $(recovery_kernel) \
1021 $(INSTALLED_2NDBOOTLOADER_TARGET) \
1022 $(recovery_build_prop) $(recovery_resource_deps) \
1023 $(recovery_fstab) \
1024 $(RECOVERY_INSTALL_OTA_KEYS)
1025 $(call build-recoveryimage-target, $#)
I tried below method but in vain because foreach will skip variable which is empty
1016 RECOVERYIMAGE_REQUIRED := $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
1017 $(INSTALLED_RAMDISK_TARGET) \
1018 $(INSTALLED_BOOTIMAGE_TARGET) \
1019 $(INTERNAL_RECOVERYIMAGE_FILES) \
1020 $(recovery_initrc) $(recovery_sepolicy) $(recovery_kernel) \
1021 $(INSTALLED_2NDBOOTLOADER_TARGET) \
1022 $(recovery_build_prop) $(recovery_resource_deps) \
1023 $(recovery_fstab) \
1024 $(RECOVERY_INSTALL_OTA_KEYS)
1025 $(call build-recoveryimage-target, $#)
1026 $(foreach item,$(HOSDIMAGE_REQUIRED), \
1027 $(eval _item := $(strip $(item))) \
1028 $(if $(_item),$(info $(_item) checked),$(error dependency is empty)) \
1029 )
1030 $(INSTALLED_RECOVERYIMAGE_TARGET): $(RECOVERYIMAGE_REQUIRED)
Oh how I wish for a --error-undefined-variables to match the existing --warn-undefined-variables. In the mean time you can just use something like:
depvarnames := \
MKBOOTFS \
MKBOOTIMG \
MINIGZIP \
⋮
deps := $(foreach _,${depvarnames},$(or $_,$(error $$$_ is empty!)))
${INSTALLED_RECOVERYIMAGE_TARGET}: ${deps}
recipe
⋮
below is my solution, looks stupid but it really help me a lot
NULL :=
SPACE := $(NULL) $(NULL)
DQUOTE = "
RECOVERYIMAGE_REQUIRED := \
"$(MKBOOTFS)" \
"$(MKBOOTIMG)" \
"$(MINIGZIP)" \
"$(PRODUCT_OUT)/ramdisk.img" \
"$(PRODUCT_OUT)/boot.img" \
"$(rec_initrc)" \
"$(rec_kernel)" \
"$(rec_build_prop)" \
"$(rec_resource_deps)" \
"$(rec_fstab)"
$(foreach item, $(RECOVERYIMAGE_REQUIRED), \
$(eval _item := $(strip $(item))) \
$(if $(filter "", $(_item)),$(error dependency is empty),) \
)
RECOVERYIMAGE_OPTIONAL := \
"$(INSTALLED_2NDBOOTLOADER_TARGET)" \
$(foreach item, $(RECOVERYIMAGE_REQUIRED) $(RECOVERYIMAGE_OPTIONAL), \
$(if $(strip $(subst $(DQUOTE),$(SPACE),$(item))), \
$(eval RECOVERYIMAGE_FINAL_LIST += $(strip $(subst $(DQUOTE),$(SPACE),$(item)))), \
) \
)
$(INSTALLED_RECOVERYIMAGE_TARGET): $(RECOVERYIMAGE_FINAL_LIST)