clang makefile "ar: не указаны члены архива"
Я рефакторинг некоторого кода на C и пытаюсь скомпилировать его как lib на clang на mac вместо gcc на linux.
Прежде всего, если я просто бегу make
Команда я получил ошибку при первом компиляции файла:+++ Compiling [sys_msg.c]
clang: error: unsupported argument '-adhlns=../../src/sys_msg.lst' to option 'Wa,'
Поэтому я удаляю -Wa,-adhlns=$(<:.c=.lst)
вариант, который создает эту ошибку.
После этого все, кажется, компилируется, но сборка последнего файла.a не удалась, и я не понимаю, почему.
Вот мой вывод make:
+++ Creation of [../../hal/stub/obj]
+++ Dependencies of [hal.c]
+++ Dependencies of [target.c]
+++ Dependencies of [robus.c]
+++ Dependencies of [reception.c]
+++ Dependencies of [sys_msg.c]
+++ Compiling [sys_msg.c]
+++ Compiling [reception.c]
+++ Compiling [robus.c]
+++ Compiling [target.c]
+++ Compiling [hal.c]
ar -rv ../../hal/stub/libstub.a
ar: no archive members specified
usage: ar -d [-TLsv] archive file ...
ar -m [-TLsv] archive file ...
ar -m [-abiTLsv] position archive file ...
ar -p [-TLsv] archive [file ...]
ar -q [-cTLsv] archive file ...
ar -r [-cuTLsv] archive file ...
ar -r [-abciuTLsv] position archive file ...
ar -t [-TLsv] archive [file ...]
ar -x [-ouTLsv] archive [file ...]
make: *** [../../hal/stub/libstub.a] Error 1
Вот мой make-файл:
# make all = Make software and program
# make clean = Clean out built project files.
# make program = Download the hex file to the device, using avrdude. Please
# customize the avrdude settings below first!
# make docs = compile with doxygen the code documentation
# Maximum I2C speed (HZ)
SCLFREQ = 400000
#-------------------------------------------------------------------------------
# Tools
#-------------------------------------------------------------------------------
# Set DEBUG variable for once if not coming from command line
ifndef DEBUG
DEBUG = 0
endif
# Tool suffix when cross-compiling
CROSS_COMPILE ?=
# Compilation tools
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
SIZE = $(CROSS_COMPILE)size
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
SIZE = $(CROSS_COMPILE)size
GDB = $(CROSS_COMPILE)gdb
NM = $(CROSS_COMPILE)nm
ROOT_PATH = ../..
HAL_PATH = $(ROOT_PATH)/hal/$(BOARD)
DOC_PATH = $(ROOT_PATH)/../extra/Docs
# Doxygen configuration file name
DOXYFILE = $(ROOT_PATH)/../extra/.Doxyfile
OBJ_PATH = $(HAL_PATH)/obj
OUTPUT_NAME = lib$(BOARD)
OUTPUT_FILE_PATH = $(HAL_PATH)/$(OUTPUT_NAME).a
#|---------------------------------------------------------------------------------------|
#| Source files |
#|---------------------------------------------------------------------------------------|
include ../sources.mk
#|---------------------------------------------------------------------------------------|
#| Extract file names and path |
#|---------------------------------------------------------------------------------------|
PROJ_ASRCS = $(filter %.s,$(foreach file,$(SOURCES),$(file)))
PROJ_ASRCS += $(filter %.S,$(foreach file,$(SOURCES),$(file)))
PROJ_CSRCS = $(filter %.c,$(foreach file,$(SOURCES),$(file)))
PROJ_CPPSRCS = $(filter %.cpp,$(foreach file,$(SOURCES),$(file)))
#|---------------------------------------------------------------------------------------|
#| Set important path variables |
#|---------------------------------------------------------------------------------------|
VPATH = $(foreach path,$(sort $(foreach file,$(SOURCES),$(dir $(file)))),$(path) :)
INC_PATH = $(INCLUDES)
LIB_PATH = -L$(dir $(RESOURCES_LINKER))
#|---------------------------------------------------------------------------------------|
#| Options for compiler binaries |
#|---------------------------------------------------------------------------------------|
COMMON_FLAGS = \
-g -O$(OPT) \
-funsigned-char -fpack-struct -fshort-enums \
-Wall -Wstrict-prototypes \
-DMCU=$(MCU) \
-DMAINCLOCK=$(MAINCLOCK) \
-DSCLFREQ=$(SCLFREQ) \
$(INCLUDES)
ifeq ($(CROSS_COMPILE),avr-)
COMMON_FLAGS += -mmcu=$(MCU)
ASFLAGS = -mmcu=$(MCU)
endif
CFLAGS += $(COMMON_FLAGS) -std=gnu99
CPPFLAGS = $(COMMON_FLAGS) -std=gnu++11 -fno-rtti -fno-exceptions
ASFLAGS += -Wa,-adhlns=$(<:.S=.lst),-gstabs -I. -x assembler-with-cpp
LDFLAGS = -Wl,-Map=$(BOARD).map,--cref
#|---------------------------------------------------------------------------------------|
#| Define targets |
#|---------------------------------------------------------------------------------------|
#AOBJS += $(patsubst %.S,%.o,$(PROJ_ASRCS))
AOBJS = $(patsubst %.s,%.o,$(addprefix $(OBJ_PATH)/, $(notdir $(PROJ_ASRCS))))
COBJS = $(patsubst %.c,%.o,$(addprefix $(OBJ_PATH)/, $(notdir $(PROJ_CSRCS))))
CPPOBJS = $(patsubst %.cpp,%.o,$(addprefix $(OBJ_PATH)/, $(notdir $(PROJ_CPPSRCS))))
.PHONY: all clean print_info packaging
all: $(OUTPUT_FILE_PATH)
print_info:
@echo DEFAULT_GOAL ---------------------------------------------------------------------------------
@echo $(.DEFAULT_GOAL)
@echo VPATH ---------------------------------------------------------------------------------
@echo $(VPATH)
@echo SOURCES -------------------------------------------------------------------------------
@echo $(SOURCES)
# @echo PROJ_ASRCS ----------------------------------------------------------------------------
# @echo $(PROJ_ASRCS)
# @echo AOBJS ---------------------------------------------------------------------------------
# @echo $(AOBJS)
@echo PROJ_CSRCS ----------------------------------------------------------------------------
@echo $(PROJ_CSRCS)
@echo COBJS ---------------------------------------------------------------------------------
@echo $(COBJS)
@echo PROJ_CPPSRCS --------------------------------------------------------------------------
@echo $(PROJ_CPPSRCS)
@echo CPPOBJS -------------------------------------------------------------------------------
@echo $(CPPOBJS)
@echo ---------------------------------------------------------------------------------------
@echo $(CURDIR)
@echo $(OUTPUT_FILE_PATH)
@echo ---------------------------------------------------------------------------------------
$(OUTPUT_FILE_PATH): $(OBJ_PATH) ../rules.mk ../sources.mk $(HAL_PATH)/Makefile $(AOBJS) $(COBJS) $(CPPOBJS)
$(AR) -rv $(OUTPUT_FILE_PATH) $(AOBJS)
$(AR) -rv $(OUTPUT_FILE_PATH) $(COBJS)
$(AR) -rv $(OUTPUT_FILE_PATH) $(CPPOBJS)
$(NM) $(OUTPUT_FILE_PATH) > $(HAL_PATH)/$(OUTPUT_NAME)_symbols.txt
#|---------------------------------------------------------------------------------------|
#| Compile or assemble |
#|---------------------------------------------------------------------------------------|
$(AOBJS): $(OBJ_PATH)/%.o: %.s
@echo +++ Assembling [$(notdir $<)]
@$(AS) $(AFLAGS) $< -o $@
$(AOBJS): $(OBJ_PATH)/%.o: %.S
@echo +++ Assembling [$(notdir $<)]
@$(AS) $(AFLAGS) $< -o $@
$(COBJS): $(OBJ_PATH)/%.o: %.c
@echo +++ Compiling [$(notdir $<)]
@$(CC) $(CFLAGS) -c $< -o $@
$(CPPOBJS): $(OBJ_PATH)/%.o: %.cpp
@echo +++ Compiling [$(notdir $<)]
@$(CC) $(CPPFLAGS) -c $< -o $@
#|---------------------------------------------------------------------------------------|
#| Output folder |
#|---------------------------------------------------------------------------------------|
$(OBJ_PATH):
@echo +++ Creation of [$@]
@-mkdir $(OBJ_PATH)
#|---------------------------------------------------------------------------------------|
#| Cleanup |
#|---------------------------------------------------------------------------------------|
clean:
-rm -f $(OBJ_PATH)/* $(OBJ_PATH)/*.*
-rmdir $(OBJ_PATH)
-rm -f $(OUTPUT_FILE_PATH)
-rm -f $(HAL_PATH)/$(OUTPUT_NAME)_symbols.txt
-rm -rf $(DOC_PATH)
#|---------------------------------------------------------------------------------------|
#| Dependencies |
#|---------------------------------------------------------------------------------------|
$(OBJ_PATH)/%.d: %.s $(OBJ_PATH)
@echo +++ Dependencies of [$(notdir $<)]
@$(CC) $(AFLAGS) -MM -c $< -MT $(basename $@).o -o $@
$(OBJ_PATH)/%.d: %.S $(OBJ_PATH)
@echo +++ Dependencies of [$(notdir $<)]
@$(CC) $(AFLAGS) -MM -c $< -MT $(basename $@).o -o $@
$(OBJ_PATH)/%.d: %.c $(OBJ_PATH)
@echo +++ Dependencies of [$(notdir $<)]
@$(CC) $(CFLAGS) -MM -c $< -MT $(basename $@).o -o $@
$(OBJ_PATH)/%.d: %.cpp $(OBJ_PATH)
@echo +++ Dependencies of [$(notdir $<)]
@$(CC) $(CPPFLAGS) -MM -c $< -MT $(basename $@).o -o $@
#|---------------------------------------------------------------------------------------|
#| Include dependencies, if existing |
#| Little trick to avoid dependencies build for some rules when useless |
#| CAUTION: this won't work as expected with 'make clean all' |
#|---------------------------------------------------------------------------------------|
DEP_EXCLUDE_RULES := clean print_info
ifeq (,$(findstring $(MAKECMDGOALS), $(DEP_EXCLUDE_RULES)))
-include $(AOBJS:%.o=%.d)
-include $(COBJS:%.o=%.d)
-include $(CPPOBJS:%.o=%.d)
endif
#|---------------------------------------------------------------------------------------|
#| Module packaging for Arduino IDE Board Manager |
#|---------------------------------------------------------------------------------------|
packaging: $(OUTPUT_FILE_PATH)
docs: ( cat $(DOXYFILE) ; echo "OUTPUT_DIRECTORY = $(DOC_PATH)" ; echo "INPUT = $(DOC_SOURCES)" ) | doxygen -
# doxygen $(DOXYFILE)
%.d:
Почему лязг поднимает мне это?
Спасибо @MadScientist. Я понимаю, почему у меня возникает эта ошибка, если я напечатаю что-то на моей марке:
$make print_info
DEFAULT_GOAL ---------------------------------------------------------------------------------
all
VPATH ---------------------------------------------------------------------------------
../../hal/stub/ : ../../src/ :
SOURCES -------------------------------------------------------------------------------
../../src/sys_msg.c ../../src/reception.c ../../src/robus.c ../../src/target.c ../../hal/stub/hal.c
PROJ_ASRCS ----------------------------------------------------------------------------
AOBJS ---------------------------------------------------------------------------------
PROJ_CSRCS ----------------------------------------------------------------------------
../../src/sys_msg.c ../../src/reception.c ../../src/robus.c ../../src/target.c ../../hal/stub/hal.c
COBJS ---------------------------------------------------------------------------------
../../hal/stub/obj/sys_msg.o ../../hal/stub/obj/reception.o ../../hal/stub/obj/robus.o ../../hal/stub/obj/target.o ../../hal/stub/obj/hal.o
PROJ_CPPSRCS --------------------------------------------------------------------------
CPPOBJS -------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
/Users/nico/Documents/pollen/Robus/robus/hal/stub
../../hal/stub/libstub.a
---------------------------------------------------------------------------------------
Моя ошибка для этой части моего make-файла:
PROJ_ASRCS = $(filter %.s,$(foreach file,$(SOURCES),$(file)))
PROJ_ASRCS += $(filter %.S,$(foreach file,$(SOURCES),$(file)))
Я не хочу включать все.o, потому что я делаю многократную компиляцию, я просто хочу перечислить необходимые файлы.
У меня тот же процесс компиляции, что и в проекте ExperimentalCore-sam.
Как я могу это сделать?
2 ответа
Я могу только предположить, что переменная AOBJS
пустой. Следуя туда, где он создан, я могу только предположить, что это означает, что нет .s
или же .S
файлы, перечисленные в вашем SOURCES
переменная.
Почему бы вам не запустить ни одного вызова $(AR)
и просто использовать $^
автоматическая переменная и отфильтровывать .o
файлы, а не три разных вызова $(AR)
команда?
$(AR) -rv $(OUTPUT_FILE_PATH) $(filter %.o,$^)
РЕДАКТИРОВАТЬ Чтобы быть ясным, я предлагаю вам изменить целевое правило вывода на это:
$(OUTPUT_FILE_PATH): $(OBJ_PATH) ../rules.mk ../sources.mk $(HAL_PATH)/Makefile $(AOBJS) $(COBJS) $(CPPOBJS)
$(AR) -rv $(OUTPUT_FILE_PATH) $(filter %.o,$^)
$(NM) $(OUTPUT_FILE_PATH) > $(HAL_PATH)/$(OUTPUT_NAME)_symbols.txt
Или, если вы хотите быть более идиоматически правильным:
$(OUTPUT_FILE_PATH): $(OBJ_PATH) ../rules.mk ../sources.mk $(HAL_PATH)/Makefile $(AOBJS) $(COBJS) $(CPPOBJS)
$(AR) -rv $@ $(filter %.o,$^)
$(NM) $@ > $(HAL_PATH)/$(OUTPUT_NAME)_symbols.txt
Как и выше, я бы определенно удалил $(OBJ_PATH)
из списка предпосылок.
Я понимаю разницу между GCC и Clang.
С GCC, если вы запускаете ar
Команда без указания членов архива, он просто пропускает шаг.
Clang выдаст ошибку в этом случае и остановит сборку.
Чтобы исправить это, я просто проверяю, пустой ли мой список:
$(OUTPUT_FILE_PATH): $(OBJ_PATH) ../rules.mk ../sources.mk $(HAL_PATH)/Makefile $(AOBJS) $(COBJS) $(CPPOBJS)
ifneq ($(strip $(AOBJS)),)
$(AR) -rv $(OUTPUT_FILE_PATH) $(AOBJS)
endif
ifneq ($(strip $(COBJS)),)
$(AR) -rv $(OUTPUT_FILE_PATH) $(COBJS)
endif
ifneq ($(strip $(CPPOBJS)),)
$(AR) -rv $(OUTPUT_FILE_PATH) $(CPPOBJS)
endif