Как сгенерировать файлы зависимостей при генерации объектных файлов c источников с помощью make - PullRequest
1 голос
/ 17 апреля 2020

Я внедряю систему сборки с использованием инструментов GNU G CC и make для компиляции нескольких целей, связывания их вместе и создания окончательного исполняемого файла. Все они поддерживают две платформы; среда хоста и встроенная система MSP432.

Я прохожу вводный курс по встроенным системам и выполняю задание, с которым я борюсь в течение нескольких дней go. Я сам пытался прочитать inte rnet, также читая здесь в stackoverflow, но я еще не понял, я все еще ладья ie по этому вопросу, поэтому я надеюсь, что кто-то может объяснить мне или дать мне подсказку о том, как решить проблему

Как уже говорилось, система сборки должна поддерживать две платформы, поэтому на первом этапе я сосредоточусь на том, чтобы убедиться, что все работает в среде хоста.

В make-файле я создал правила для следующих целей:

  1. build - Создает исполняемый файл, объектные файлы, файлы зависимостей и файл карты
  2. %.o: %.c ... - генерирует объектные файлы и их зависимости
  3. compile-all - компилирует все объекты, но не связывает их
  4. %.i: %.c - генерирует предварительно обработанные выходные данные C исходных файлов
  5. %.asm: %.C - генерирует выходные данные сборки C исходных файлов
  6. clean - очищает все сгенерированные файлы

Проблема заключается в выполнении make build PLATFORM=HOST

Запустив команду, мы получим:

.../src$ sudo make build PLATFORM=HOST
gcc -Wall -Werror -g -std=c99 -DHOST -Wl,-O0,-Map=c1m2.map main.c memory.c -I../includes/common -o c1m2.out
make: *** No rule to make target 'main.o', needed by 'build'.  Stop.

Я замечаю, что ошибка возникает из-за строки 132, в которой мы имеем

%.o: %.c

Эта строка предназначена для отключения встроенное правило, использующее пользовательское правило, которое следует за следующей строкой, но оно этого не делает, поэтому я пытаюсь прокомментировать эту строку и выполнить сборку снова, и мы получим:

.../src$ sudo make build PLATFORM=HOST
gcc -Wall -Werror -g -std=c99 -DHOST -Wl,-O0,-Map=c1m2.map main.c memory.c -I../includes/common -o c1m2.out
gcc -Wall -Werror -g -std=c99 -DHOST -E  -c -o main.o main.c
main.c:23:22: fatal error: platform.h: No such file or directory
compilation terminated.
< builtin >: recipe for target 'main.o' failed
make: *** [main.o] Error 1

Теперь он говорит, что он не находит «platform.h», несмотря на то, что это указано т он включает переменную, которая содержит местоположение файла заголовка. Кроме того, он использует встроенный рецепт для генерации объектных файлов и дает сбой.

Так что я застрял на этом этапе, идея заключается в создании выходного исполняемого файла, файла карты, объектных файлов и их зависимостей файлы при выполнении «make build PLATFORM = HOST».

Вначале я написал цель сборки только для генерации выходных файлов, файлов карты и объектов и работал, а затем после внесения изменений для генерации файлов зависимостей. Я заблудился с этой ошибкой.

Другие рецепты для создания предварительно обработанных файлов, файлов сборки и выполнения очистки работали нормально.

Вы можете клонировать папку со всеми необходимыми файлами из: https://github.com/Fornaso/C1M2.git

Спасибо всем заранее.

Вот мой Makefile:

</p>

<code>#******************************************************************************
# Copyright (C) 2017 by Alex Fosdick - University of Colorado
#
# Redistribution, modification or use of this software in source or binary
# forms is permitted as long as the files maintain this copyright. Users are 
# permitted to modify this and use it to learn about the field of embedded
# software. Alex Fosdick and the University of Colorado are not liable for any
# misuse of this material. 
#
#******************************************************************************

# Modified on April 2020 by Adrián Fornaso

#------------------------------------------------------------------------------
# Simple Makefile for multitarget build system
#
# Use: make [TARGET] [PLATFORM-OVERRIDES]
#
# Build Targets:
#
# build                 - Builds and links all source files and genereates:
#
#                       c1m2.map - Map file for the full build
#                       *.d      - Dependency Files for each source file
#                       *.o      - Individual object files
#                       c1m2.out - Output Executable file
#
#<FILE>.i               - Builds <FILE>.i preprocessed file.
#<FILE>.asm             - Builds <FILE>.i assembly file.
#<FILE>.o               - Builds <FILE>.o object file.
#compile-all            - Compile all objects but do NOT link them.
#clean                  - Removes all generated files.
#
# Platform Overrides: Conditionally assign the appropriate compiler flags,
#                     linker flags, and architecture flags. The target platform
#                     must be provided at the command line with the make
#                     command to set the platform you are compiling for.
#       
#                     PLATFORM = MSP432 - The target embedded system will use
#                                         the cross compiler, arm-none-eabi-gcc.
#                     PLATFORM = HOST   - The host embedded system will use the
#                                         native compiler, gcc.
#
#------------------------------------------------------------------------------

#------------------------------------------------------------------------------
#General Flags (Both Platforms)
#
#   -Wall           Enable All Warning Messages (CFLAGS)
#   -Werror         Treats All Warnings as Errors(CFLAGS)
#   -g              Generate Debugging Info in Executable (CFLAGS)
#   -O0             The level of optimization (-O0, -O1, -O2, -O3)) (LDFLAGS)
#   -std=c99        The C standard set (CFLAGS)
#
#------------------------------------------------------------------------------

#Target name
BASENAME = c1m2
TARGET = $(BASENAME).out

#General Flags
COMMONCFLAGS = -Wall -Werror -g -std=c99
COMMONLDFLAGS = -Wl,-O0,-Map=$(BASENAME).map
#No spaces after commas after -Wl option.

CPPFLAGS = -E
# -E flag makes the compiler stop in the preprocessed output

#Compile time switches
ifeq ($(PLATFORM), MSP432)
    INCLUDES =  -I../includes/common    \
                -I../includes/msp432    \
                -I../includes/CMSIS
    SOURCES =   main.c                          \
                memory.c                        \
                interrupts_msp432p401r_gcc.c    \
                startup_msp432p401r_gcc.c       \
                system_msp432p401r.c

    LINKER_FILE = msp432p401r.lds
    CPU = cortex-m4
    ARCH = armv7e-m
    SPECS = nosys.specs

    CC = arm-none-eabi-gcc
    LD = arm-none-eabi-ld

    LDFLAGS = $(COMMONLDFLAGS), -T=$(LINKER_FILE)

    CFLAGS =    $(COMMONCFLAGS) -D$(PLATFORM) -mcpu=$(CPU)  \
                        -march=$(ARCH) --specs=$(SPECS)
    OBJDUMP = arm-none-eabi-objdump
endif
ifeq ($(PLATFORM), HOST)
    INCLUDES = -I../includes/common

    SOURCES =   main.c  \
                memory.c

    CC = gcc
    LD = ld
    LDFLAGS = $(COMMONLDFLAGS)
    CFLAGS = $(COMMONCFLAGS) -D$(PLATFORM)
    OBJDUMP = objdump
endif

#Listing object files:
OBJECTS = $(SOURCES:.c=.o)

# 1. --------------------------------------------------------------------------
# Complete build:        c1m2.map - Map file for the full build
#                        *.d      - Dependency Files for each source file
#                        *.o      - Individual object files
#                        c1m2.out - Output Executable file

# LDFLAGS contains the flags for creating the *.map file

.PHONY: build
build: $(TARGET) $(OBJECTS)
$(TARGET):
    $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCES) $(INCLUDES) -o $@


# 2. --------------------------------------------------------------------------
# //// Generates the object files of all c-program implementation files and its
#      dependecies. ///////////////////////////////////////////////////////////

#This implementation places dependency files into a subdirectory named .deps.
DEPDIR := .deps
DEPFLAGS = -MT $@ -MD -MP -MF $(DEPDIR)/$*.d

# Delete the built-in rules for building object files from .c files, so that
# our rule is used instead.
#%.o: %.c
# Our rule for building object files with its dependency
%.o: %.c $(DEPDIR)/%.d | $(DEPDIR)
    $(CC) $(DEPFLAGS) -c $(CFLAGS) $(INCLUDES) -o $@ $^

# Declare a rule for creating the dependency directory if it doesn’t exist.
$(DEPDIR): ; @mkdir -p $@

# Generate a list of all the dependency files that could exist.
DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d)

# Mention each dependency file as a target, so that make won’t fail if the file
# doesn’t exist.
$(DEPFILES):


# 2 bis. ----------------------------------------------------------------------
# /// Generates the object file of all c-program implementation files. ////////
#%.o: %.c
#   $(CC) -c $(CFLAGS) $(INCLUDES) -o $@ $^


# 3. --------------------------------------------------------------------------
# /// Compile all objects but do NOT link them. ///////////////////////////////
.PHONY: compile-all
compile-all: $(SOURCES)
    $(CC) -c $(CFLAGS) $(INCLUDES) $^


# 4. --------------------------------------------------------------------------
# /// Generates the preprocessed output of all c-program implementation files. 
%.i: %.c
    $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -o $@ $^    


# 5. --------------------------------------------------------------------------
# /// Create assembler file of a C source. ////////////////////////////////////
%.asm: %.c
    $(CC) -S $(CFLAGS) $(INCLUDES) $< -o $@
# -S flag tells the compiler just generate the assembly file


# 6. --------------------------------------------------------------------------
# /// Removes all compiled objects, preprocessed outputs, assembly outputs,
#     executable files and build output files. ////////////////////////////////
.PHONY: clean
clean:
    rm -f $(OBJECTS) $(TARGET) $(BASENAME).map *.asm *.i
    rm -r .dep

#End of file
</code>

1 Ответ

1 голос
/ 17 апреля 2020

Есть две небольшие ошибки, которые я потратил много времени, чтобы увидеть:

  • DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d) должно быть DEPFILES := $(SOURCES:%.c=$(DEPDIR)/%.d) - иначе DEPFILES пусто, поскольку SRCS не определено.
  • В $(CC) $(DEPFLAGS) -c $(CFLAGS) $(INCLUDES) -o $@ $^ $^ ( все предпосылки ) расширяется до, например, main.c .deps/main.d, поэтому еще не существующий .deps/main.d передается в качестве входного файла; мы хотим $*.c вместо $^.

Другая незначительная ошибка:

  • rm -r .dep должно быть rm -r .deps или rm -r $(DEPDIR).
...