Как скомпилировать несколько исходных файлов C в объектный файл с помощью Makefile

#makefile #gnu-make

#makefile #gnu-make

Вопрос:

Вот код makefile, и я выполняю его с помощью «make».

 CC=arm-none-eabi-gcc
CXX = arm-none-eabi-g  
BUILD_PATH = ../../build
dir_guard=mkdir -p $(@D)
STATIC_OPENTHREAD_LIB = $(BUILD_PATH)/third_party/libopenthread.a
AR = arm-none-eabi-gcc-ar -cr 

TARGET_OPENTHREAD_SRC_PATH = openthread


NRF_802154_MODULE_NAME = nrf_802154
NRF_802154_MODULE_PATH ?= $(PROJECT_ROOT)/third_party/$(NRF_802154_MODULE_NAME)

TARGET_NRF_802154_PATH = $(NRF_802154_MODULE_PATH)



INCLUDE_DIRS := openthread/include/
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice 
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/drivers/radio/rsch/raal
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/drivers/radio/hal
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/drivers/radio
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/nrfx/mdk
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/nrfx
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/dependencies
INCLUDE_DIRS := openthread/include/openthread
INCLUDE_DIRS := openthread/include/openthread/platform
INCLUDE_DIRS := $(TARGET_NRF_802154_PATH)/nrf_802154/src
INCLUDE_DIRS := $(TARGET_NRF_802154_PATH)/nrf_802154/src
INCLUDE_DIRS := $(TARGET_NRF_802154_PATH)/nrf_802154/src/fem
INCLUDE_DIRS := $(TARGET_NRF_802154_PATH)/nrf_802154/src/hal
INCLUDE_DIRS := $(TARGET_NRF_802154_PATH)/nrf_802154/src/mac_features
INCLUDE_DIRS := $(TARGET_NRF_802154_PATH)/nrf_802154/src/platform/clock
INCLUDE_DIRS := $(TARGET_NRF_802154_PATH)/nrf_802154/src/platform/temperature
INCLUDE_DIRS := $(TARGET_NRF_802154_PATH)/nrf_802154/src/platform/timer
INCLUDE_DIRS := $(TARGET_NRF_802154_PATH)/nrf_802154/src/raal
INCLUDE_DIRS := $(TARGET_NRF_802154_PATH)/nrf_802154/src/raal/softdevice
INCLUDE_DIRS := $(TARGET_NRF_802154_PATH)/nrf_802154/src/timer_scheduler
INCLUDE_DIRS := $(TARGET_OPENTHREAD_SRC_PATH)/examples/platforms
INCLUDE_DIRS := $(TARGET_OPENTHREAD_SRC_PATH)/include/openthread
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/drivers/clock
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/nrfx/hal
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/nrfx/drivers/include
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/libraries/app_error
INCLUDE_DIRS := openthread/src/core
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/cmsis
INCLUDE_DIRS := openthread/third_party/NordicSemiconductor/nrfx/mdk/

CFLAGS  = -DENABLE_DEBUG_LOG=1 -DENABLE_DEBUG_GPIO=0 -DENABLE_DEBUG_ASSERT=0  
CFLAGS  = -DSTM32_DEVICE -DnRF52840 -DNRF52840_XXAA -DPLATFORM_THREADING=1 -DPLATFORM_ID=14 -DPLATFORM_NAME=xenon -DUSBD_VID_SPARK=0x2B04 -DUSBD_PID_DFU=0xD00E -DUSBD_PID_CDC=0xC00E -g3 -gdwarf-2 -Os -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DSOFTDEVICE_PRESENT=1 -DS140 -DINCLUDE_PLATFORM=1 -DOPENTHREAD_PROJECT_CORE_CONFIG_FILE="openthread-config-project.h" -DENABLE_FEM=1 -DNRF_802154_PROJECT_CONFIG="openthread-platform-config.h" -DRAAL_SOFTDEVICE=1 -D_WIZCHIP_=W5500 -fno-builtin -DUSE_STDPERIPH_DRIVER -DDFU_BUILD_ENABLE -DLFS_CONFIG=lfs_config.h -DSYSTEM_VERSION_STRING=0.8.0-rc.27 -DRELEASE_BUILD 

CFLAGS  = -DENABLE_FEM=1 -Werror
CFLAGS  = -DNRF_802154_PROJECT_CONFIG="openthread-platform-config.h"
CFLAGS  = -DRAAL_SOFTDEVICE=1
CFLAGS  = -DNRF52840_AAAA=0 -DNRF52840_AABA=0

CFLAGS  = -DNRF52840_AAAA=0 -DNRF52840_AABA=0
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification_swi.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop_swi.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_swi.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rssi.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rx_buffer.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_802154_clock_sdk.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.c
CSRC  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.c

ALLOBJ := $(addprefix $(BUILD_PATH)/, $(CSRC:.c=.o))

all:$(ALLOBJ)

%.o: %.c
    echo $^

clean:
    rm -rf $(BUILD_PATH)
  

Но это не удается с этим сообщением об ошибке:

 make: *** No rule to make target '../../build/openthread/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification_swi.o', needed by 'all'.  Stop
  

Похоже, что он не распознает шаблон.

Шаблон % должен распознавать вызываемое правило, но оно не работает

Что я хочу сделать, так это то, что мой исходный код находится в другом каталоге, и я хочу создать makefile, который может компилировать C и создавать объекты в другом каталоге, а затем хочет создавать.библиотека, использующая AR.

Комментарии:

1. Мне кажется, что все ваши INCLUDE_DIRS утверждения неверны. Они используют := вместо = .

2. разница между:= и = ? короче говоря

3. Второй является аддитивным (он дополняет предыдущий). Первый заменяет (второй заменяет первый, что означает, что первый потерян). Смотрите использование в CSRC в вашем собственном сообщении. В коде a = 1; a = 2 означает a == 2 , в то время как a = 1; a = 1; означает a == 3 .

4. и значение: =

Ответ №1:

Ваше правило шаблона не может совпадать, потому что вы сопоставляете полные имена путей с обеих сторон. Но ваши префиксы пути не совпадают, например

  • исходный файл $(TARGET_OPENTHREAD_SRC_PATH)/third_party/...
  • объектный файл ../../build/$(TARGET_OPENTHREAD_SRC_PATH)/third_party/...

Простым решением было бы:

 ALLOBJ := $(addprefix $(BUILD_PATH)/, $(CSRC:.c=.o))

$(ALLOBJ): $(BUILD_PATH)/%.o: %.c
        .... compiler command line goes in here ....
  

Но гораздо более простым подходом было бы использовать VPATH вместо этого, т.е. указать make, где искать исходные файлы, и полностью удалить пути из исходных файлов:

 # location of the source files (you can have multiple source directories too)
VPATH  = $(TARGET_OPENTHREAD_SRC_PATH)/third_party/NordicSemiconductor/drivers/radio

CSRC  = nrf_802154_notification_swi.c

ALLOBJ := $(addprefix $(BUILD_PATH)/, $(CSRC:.c=.o))

$(ALLOBJ): $(BUILD_PATH)/%.o: %.c
        .... compiler command line goes in here ....
  

Комментарии:

1. Сэр, но проблема в том, что мои исходные коды находятся в разных каталогах, я должен указать все разные каталоги и файл .c, не слишком ли это длительная задача? потому что я должен сопоставить файл исходного кода с этим путем

2. Как я упоминал, вы можете назначить несколько каталогов VPATH . Второй вариант — назначить исходный корневой каталог VPATH и удалить корневую часть из имен исходных файлов. И пока вы этим занимаетесь: вы можете использовать тот же список каталогов для создания -I списка для CFLAGS .

3. о, это означает, что мне не нужно указывать абсолютный путь к исходному файлу, все, что мне нужно сделать это. назначьте корневой каталог исходного кода, и он найдет исходный файл, который указан правильно?

4. Точно. Я бы посоветовал прочитать раздел руководства GNU make, на который я дал ссылку в своем ответе.