check variable is empty before add into dependency - makefile

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)

Related

Using ifndef in the makefile inside a variable defined by export

I want to insert ifndef in the makefile inside export
And it seems that there is no possibility
export LINKER_INCLUDE_FILES:=$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/platform/one/r4/cr4_cpu.o \
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/platform/one/r4/cr4_fpinit.o \
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/platform/one/r4/cr4_startup.o \
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/platform/one/r4/cr4_vfpinit.o \
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/platform/one/r4_0/cr4_mpu.o \
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/platform/one/r4_0/isr.o \
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/config/one/bmw/r4_0/sys_resource_tables.o \
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/app/unit_tests/cantata_infra/invz_printf.o \
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/infra/hw/hw_access.o \
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/infra/hw/regs.o \
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/drivers/uart/uart_drv.o \
ifndef TEST_TIMER
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/drivers/timers/timer.o \
endif
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/drivers/vic/vic.o \
$(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/drivers/clock_and_reset/clock_and_reset.o
Certainly that can't work.
You can just use:
export LINKER_INCLUDE_FILES := ... \
ifndef TEST_TIMER
LINKER_INCLUDE_FILES += $(BASE_PATH)/build/one/bmw/r4_0_cantata/Deploy/src/drivers/timers/timer.o
endif
E.g., put all the values into the variable, then use ifndef to += extra variables.

Condense Makefile.am

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.

Makefile not compiling when new argument passed

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.

How to avoid running all targets every time a makefile is run?

How can I avoid rebuilding of targets every time even though there are no changes to them? I have looked at these answers: answer1, answer2, answer3, but I still could not solve my problem. I think I understand conceptually why this problem occurs. It is just that I was unable to apply the solutions to my case.
Here is my makefile:
.PHONY: all dircreate dircreate_sub
# Create shortcuts to directories ##############################################
DAT4 = data/4-Year/
RES4 = data/results/4-Year/
FIG4 = figures/4-Year/
DAT2 = data/2-Year/
RES2 = data/results/2-Year/
FIG2 = figures/2-Year/
DEPVARS = \
ret.1st.2nd.term.left \
ret.1st.2nd.year.left \
ret.1st.7th.year.grad \
ret.1st.5th.year.grad
# Create directories ###########################################################
dircreate:
mkdir -p \
data/ \
data/4-Year/ \
data/2-Year/ \
data/results/ \
data/results/4-Year \
data/results/2-Year \
figures/ \
figures/4-Year/ \
figures/2-Year/
dircreate_sub:
for d in $(DEPVARS); do \
mkdir -p data/4-Year/$$d ; \
mkdir -p data/2-Year/$$d ; \
mkdir -p data/results/4-Year/$$d ; \
mkdir -p data/results/2-Year/$$d ; \
mkdir -p figures/4-Year/$$d ; \
mkdir -p figures/2-Year/$$d ; \
done;
#TARGETS_DATAPREP := \
#$(foreach dat, $(DAT4) $(DAT2), $\
# $(foreach filename, \
# train_index_outer.RDS \
# train_outer.RDS \
# train_inter_outer.RDS, $\
# $(foreach depvar, $(DEPVARS),$(dat)$(depvar)/$(filename))))
# Data prep:####################################################################
TARGETS_DATAPREP := \
$(foreach filename, $\
train_index_outer.RDS \
train_outer.RDS \
train_inter_outer.RDS \
entire_data.RDS \
entire_inter_data.RDS, $\
$(foreach depvar, $(DEPVARS),$(DAT4)$(depvar)/$(filename)))
$(TARGETS_DATAPREP): \
dataprep.R \
funcs.R \
../core/data/analysis.data.RDS
Rscript $<
# benchmark:####################################################################
DEPENDENCIES_BENCHMARK := \
$(foreach filename, $\
train_index_outer.RDS \
train_outer.RDS \
train_inter_outer.RDS \
entire_data.RDS \
entire_inter_data.RDS, $\
$(foreach depvar, $(DEPVARS),$(DAT4)$(depvar)/$(filename)))
TARGETS_BENCHMARK := \
$(foreach filename, $\
logreg_inner.RDS \
l1logreg_inner.RDS \
l1logreg.int_inner.RDS \
rf_inner.RDS \
xgb_inner.RDS \
logreg_outer.RDS \
l1logreg_outer.RDS \
l1logreg.int_outer.RDS \
rf_outer.RDS \
xgb_outer.RDS, $\
$(foreach depvar, $(DEPVARS),$(RES4)$(depvar)/$(filename)))
$(TARGETS_BENCHMARK): \
benchmark.R \
funcs.R \
$(DEPENDENCIES_BENCHMARK)
Rscript $<
# Process:######################################################################
TARGETS_PROCESS := \
$(foreach filename, $\
processed_inner.RDS \
processed_inner_outer.RDS, $\
$(foreach depvar, $(DEPVARS),$(RES4)$(depvar)/$(filename)))
$(TARGETS_PROCESS): \
process.R \
funcs.R \
$(TARGETS_BENCHMARK)
Rscript $<
# Graphs:#######################################################################
TARGETS_GRAPHS := \
$(foreach filename, $\
ave_auc_inner.png \
ave_ppv10_inner.png \
dist_auc_inner.png \
dist_ppv10_inner.png \
roc_inner.png \
ave_auc_outer.png \
ave_ppv10_outer.png \
dist_auc_outer.png \
dist_ppv10_outer.png \
roc_outer.png \
ave_auc_ppv10_inner_outer.png \
roc_inner_outer.png \
thresh_inner_outer.png, $\
$(foreach depvar, $(DEPVARS),$(FIG4)$(depvar)/$(filename)))
$(TARGETS_GRAPHS): \
graphs.R \
funcs.R \
$(TARGETS_PROCESS)
Rscript $<
# Make all
all: $(TARGETS_PROCESS)
So, the make -nd tells me dircreate needs to be remade every time. That's why I also tried adding a variable called, say, OUTDIRS and also created a rule for it. So, instead of dircreate, I added this bit:
OUTDIRS: $(DAT4) $(RES4) $(FIG4) $(DAT2) $(RES2) $(FIG2)
OUTDIRS := \
for d in $(DEPVARS); do \
$(DAT4)$$d ; \
$(DAT2)$$d ; \
$(RES4)$$d ; \
$(RES2)$$d ; \
$(FIG4)$$d ; \
$(FIG2)$$d ; \
done;
$(OUTDIRS):
mkdir -p $#
But, this time I get a missing separator error at $(OUTDIRS): mkdir -p $#, which, I know, is unrelated to the main question, but I am wondering if the way I am going about is at least on the right track?
Suppose you have
DIRS := 2-Year 4-Year
DEPVARS := term year
and you want to construct:
2-Year/term 2-Year/year 4-Year/term 4-Year/year
You can do it this way:
OUTDIRS := $(foreach d,$(DIRS),$(addprefix $(d)/,$(DEPVARS)))
And once you have that working you can abstract it into a function:
Multiply= $(foreach d,$(1),$(addprefix $(d)/,$(2)))
OUTDIRS:=$(call Multiply, $(DIRS), $(DEPVARS))
And one you have that working you can use it to construct those trees of yours:
DIRS := data data/results figures
DIRS := $(DIRS) $(call Multiply, $(DIRS), 4-Year 2-Year)
DEPVARS := $(addprefix ret.1st., 2nd.term.left 2nd.year.left 7th.year.grad 5th.year.grad)
OUTDIRS:=$(call Multiply, $(DIRS), $(DEPVARS))
$(OUTDIRS):
mkdir -p $#
Note that if you want Make to create whichever of those directories don't exist, you must add another rule before the $(OUTDIRS) rule:
.PHONY: all-dirs
all-dirs: $(OUTDIRS)

undefined reference while linking

i have added a module to ns2 and i am compiling it when i get undefined reference error.
g++ -o ns \
-lXext -lX11 -lnsl -ldl -lm -lm -lrt -lneoclassic -lxml
maser/mamas.o: In function `mamasReasoner::mamasReasoner()':
mamas.cc:(.text+0x95): undefined reference to `NeoEnvironment::initFromNs(std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >&, std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >&, int)'
maser/mamas.o: In function `mamasReasoner::build_ontology_tree(knBase&)':
mamas.cc:(.text+0x1c84): undefined reference to `NeoEnvironment::evaluateCommand(String const&)'
maser/mamas.o: In function `NeoEnvironment::readXmlFromMemory(char const*, char const*)':
mamas.cc:(.text._ZN14NeoEnvironment17readXmlFromMemoryEPKcS1_[NeoEnvironment::readXmlFromMemory(char const*, char const*)]+0x14): undefined reference to `Parser::readXmlFromMemory(char const*, char const*)'
collect2: ld returned 1 exit status
make: *** [ns] Error
the library which it is asking for is present at the /usr/local/lib/libneoclassic.so and the makefile can be seen here http://pastebin.com/NZWPxKht
which use the following code for linking.
LINK = g++
LDFLAGS = -lneoclassic -lrt -lxml2
LDOUT = -o $(BLANK)
LIB = \
-L/usr/local/lib -ltclcl -L/usr/local/lib -lotcl -L/usr/local/lib -ltk8.4 -L/usr/local/lib -ltcl8.4 \
-lXext -lX11 \
-lnsl -ldl \
-lm -lm
OBJ_CC = \
tools/random.o tools/rng.o tools/ranvar.o common/misc.o common/timer-handler.o \
common/scheduler.o common/object.o common/packet.o \
common/ip.o routing/route.o common/connector.o common/ttl.o \
trace/trace.o trace/trace-ip.o \
classifier/classifier.o classifier/classifier-addr.o \
classifier/classifier-hash.o \
classifier/classifier-virtual.o \
classifier/classifier-mcast.o \
classifier/classifier-bst.o \
classifier/classifier-mpath.o mcast/replicator.o \
classifier/classifier-mac.o \
classifier/classifier-qs.o \
classifier/classifier-port.o src_rtg/classifier-sr.o \
src_rtg/sragent.o src_rtg/hdr_src.o adc/ump.o \
qs/qsagent.o qs/hdr_qs.o \
apps/app.o apps/telnet.o tcp/tcplib-telnet.o \
tools/trafgen.o trace/traffictrace.o tools/pareto.o \
tools/expoo.o tools/cbr_traffic.o \
adc/tbf.o adc/resv.o adc/sa.o tcp/saack.o \
tools/measuremod.o adc/estimator.o adc/adc.o adc/ms-adc.o \
adc/timewindow-est.o adc/acto-adc.o \
adc/pointsample-est.o adc/salink.o adc/actp-adc.o \
adc/hb-adc.o adc/expavg-est.o\
adc/param-adc.o adc/null-estimator.o \
adc/adaptive-receiver.o apps/vatrcvr.o adc/consrcvr.o \
common/agent.o common/message.o apps/udp.o \
common/session-rtp.o apps/rtp.o tcp/rtcp.o \
common/ivs.o \
common/messpass.o common/tp.o common/tpm.o apps/worm.o \
tcp/tcp.o tcp/tcp-sink.o tcp/tcp-reno.o \
tcp/tcp-newreno.o \
tcp/tcp-vegas.o tcp/tcp-rbp.o tcp/tcp-full.o tcp/rq.o \
baytcp/tcp-full-bay.o baytcp/ftpc.o baytcp/ftps.o \
tcp/scoreboard.o tcp/scoreboard-rq.o tcp/tcp-sack1.o tcp/tcp-fack.o \
tcp/tcp-asym.o tcp/tcp-asym-sink.o tcp/tcp-fs.o \
tcp/tcp-asym-fs.o \
tcp/tcp-int.o tcp/chost.o tcp/tcp-session.o \
tcp/nilist.o \
sctp/sctp.o apps/sctp_app1.o\
sctp/sctp-timestamp.o sctp/sctp-hbAfterRto.o \
sctp/sctp-multipleFastRtx.o sctp/sctp-mfrHbAfterRto.o \
sctp/sctp-mfrTimestamp.o \
sctp/sctp-cmt.o \
sctp/sctpDebug.o \
tools/integrator.o tools/queue-monitor.o \
tools/flowmon.o tools/loss-monitor.o \
queue/queue.o queue/drop-tail.o \
adc/simple-intserv-sched.o queue/red.o \
queue/semantic-packetqueue.o queue/semantic-red.o \
tcp/ack-recons.o \
queue/sfq.o queue/fq.o queue/drr.o queue/srr.o queue/cbq.o \
queue/jobs.o queue/marker.o queue/demarker.o \
link/hackloss.o queue/errmodel.o queue/fec.o\
link/delay.o tcp/snoop.o \
gaf/gaf.o \
link/dynalink.o routing/rtProtoDV.o common/net-interface.o \
mcast/ctrMcast.o mcast/mcast_ctrl.o mcast/srm.o \
common/sessionhelper.o queue/delaymodel.o \
mcast/srm-ssm.o mcast/srm-topo.o \
routing/alloc-address.o routing/address.o \
$(LIB_DIR)int.Vec.o $(LIB_DIR)int.RVec.o \
$(LIB_DIR)dmalloc_support.o \
webcache/http.o webcache/tcp-simple.o webcache/pagepool.o \
webcache/inval-agent.o webcache/tcpapp.o webcache/http-aux.o \
webcache/mcache.o webcache/webtraf.o \
webcache/webserver.o \
webcache/logweb.o \
empweb/empweb.o \
empweb/empftp.o \
realaudio/realaudio.o \
mac/lanRouter.o classifier/filter.o \
common/pkt-counter.o \
common/Decapsulator.o common/Encapsulator.o \
common/encap.o \
mac/channel.o mac/mac.o mac/ll.o mac/mac-802_11.o \
mac/mac-802_3.o mac/mac-tdma.o mac/smac.o \
mobile/mip.o mobile/mip-reg.o mobile/gridkeeper.o \
mobile/propagation.o mobile/tworayground.o \
mobile/antenna.o mobile/omni-antenna.o \
mobile/shadowing.o mobile/shadowing-vis.o mobile/dumb-agent.o \
common/bi-connector.o common/node.o \
common/mobilenode.o \
mac/arp.o mobile/god.o mobile/dem.o \
mobile/topography.o mobile/modulation.o \
queue/priqueue.o queue/dsr-priqueue.o \
mac/phy.o mac/wired-phy.o mac/wireless-phy.o \
mac/mac-timers.o trace/cmu-trace.o mac/varp.o \
mac/mac-simple.o \
satellite/sat-hdlc.o \
dsdv/dsdv.o dsdv/rtable.o queue/rtqueue.o \
routing/rttable.o \
imep/imep.o imep/dest_queue.o imep/imep_api.o \
imep/imep_rt.o imep/rxmit_queue.o imep/imep_timers.o \
imep/imep_util.o imep/imep_io.o \
tora/tora.o tora/tora_api.o tora/tora_dest.o \
tora/tora_io.o tora/tora_logs.o tora/tora_neighbor.o \
dsr/dsragent.o dsr/hdr_sr.o dsr/mobicache.o dsr/path.o \
dsr/requesttable.o dsr/routecache.o dsr/add_sr.o \
dsr/dsr_proto.o dsr/flowstruct.o dsr/linkcache.o \
dsr/simplecache.o dsr/sr_forwarder.o \
aodv/aodv_logs.o aodv/aodv.o \
aodv/aodv_rtable.o aodv/aodv_rqueue.o \
common/ns-process.o \
satellite/satgeometry.o satellite/sathandoff.o \
satellite/satlink.o satellite/satnode.o \
satellite/satposition.o satellite/satroute.o \
satellite/sattrace.o \
rap/raplist.o rap/rap.o rap/media-app.o rap/utilities.o \
common/fsm.o tcp/tcp-abs.o \
diffusion/diffusion.o diffusion/diff_rate.o diffusion/diff_prob.o \
diffusion/diff_sink.o diffusion/flooding.o diffusion/omni_mcast.o \
diffusion/hash_table.o diffusion/routing_table.o diffusion/iflist.o \
tcp/tfrc.o tcp/tfrc-sink.o mobile/energy-model.o apps/ping.o tcp/tcp-rfc793edu.o \
queue/rio.o queue/semantic-rio.o tcp/tcp-sack-rh.o tcp/scoreboard-rh.o \
plm/loss-monitor-plm.o plm/cbr-traffic-PP.o \
linkstate/hdr-ls.o \
mpls/classifier-addr-mpls.o mpls/ldp.o mpls/mpls-module.o \
routing/rtmodule.o classifier/classifier-hier.o \
routing/addr-params.o \
nix/hdr_nv.o nix/classifier-nix.o \
nix/nixnode.o \
routealgo/rnode.o \
routealgo/bfs.o \
routealgo/rbitmap.o \
routealgo/rlookup.o \
routealgo/routealgo.o \
nix/nixvec.o \
nix/nixroute.o \
diffserv/dsred.o diffserv/dsredq.o \
diffserv/dsEdge.o diffserv/dsCore.o \
diffserv/dsPolicy.o diffserv/ew.o diffserv/dewp.o \
queue/red-pd.o queue/pi.o queue/vq.o queue/rem.o \
queue/gk.o \
pushback/rate-limit.o pushback/rate-limit-strategy.o \
pushback/ident-tree.o pushback/agg-spec.o \
pushback/logging-data-struct.o \
pushback/rate-estimator.o \
pushback/pushback-queue.o pushback/pushback.o \
common/parentnode.o trace/basetrace.o \
common/simulator.o asim/asim.o \
common/scheduler-map.o common/splay-scheduler.o \
linkstate/ls.o linkstate/rtProtoLS.o \
pgm/classifier-pgm.o pgm/pgm-agent.o pgm/pgm-sender.o \
pgm/pgm-receiver.o mcast/rcvbuf.o \
mcast/classifier-lms.o mcast/lms-agent.o mcast/lms-receiver.o \
mcast/lms-sender.o \
queue/delayer.o \
xcp/xcpq.o xcp/xcp.o xcp/xcp-end-sys.o \
wpan/p802_15_4csmaca.o wpan/p802_15_4fail.o \
wpan/p802_15_4hlist.o wpan/p802_15_4mac.o \
wpan/p802_15_4nam.o wpan/p802_15_4phy.o \
wpan/p802_15_4sscs.o wpan/p802_15_4timer.o \
wpan/p802_15_4trace.o wpan/p802_15_4transac.o \
maser/maser.o maser/mamas.o \
$(OBJ_STL)
$(LINK) $(LDFLAGS) $(LDOUT)$# \
common/tclAppInit.o $(OBJ) $(LIB)
I figured out that the functions were declared but not implemented. As soon as I implemented them, the problem was solved.

Resources