2017-02-14 61 views
0

我重構了一些C代碼,我嘗試將它編譯爲mac上的clang而不是linux上的gcc。鏗鏘makefile「ar:沒有指定存檔成員」

首先,如果我只是運行make命令我在第一個文件編譯得到了一個錯誤:
+++ Compiling [sys_msg.c] clang: error: unsupported argument '-adhlns=../../src/sys_msg.lst' to option 'Wa,'

所以我刪除了-Wa,-adhlns=$(<:.c=.lst)選項創建此錯誤。

之後,一切似乎編譯,但最後.a文件的程序集失敗,我不明白爲什麼。

這裏是我的化妝輸出:

+++ 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 

這裏是我的makefile:

# 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 [email protected] 

$(AOBJS): $(OBJ_PATH)/%.o: %.S 
    @echo +++ Assembling [$(notdir $<)] 
    @$(AS) $(AFLAGS) $< -o [email protected] 

$(COBJS): $(OBJ_PATH)/%.o: %.c 
    @echo +++ Compiling [$(notdir $<)] 
    @$(CC) $(CFLAGS) -c $< -o [email protected] 

$(CPPOBJS): $(OBJ_PATH)/%.o: %.cpp 
    @echo +++ Compiling [$(notdir $<)] 
    @$(CC) $(CPPFLAGS) -c $< -o [email protected] 

#|---------------------------------------------------------------------------------------| 
#| Output folder                   | 
#|---------------------------------------------------------------------------------------| 
$(OBJ_PATH): 
    @echo +++ Creation of [[email protected]] 
    @-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 [email protected]).o -o [email protected] 

$(OBJ_PATH)/%.d: %.S $(OBJ_PATH) 
    @echo +++ Dependencies of [$(notdir $<)] 
    @$(CC) $(AFLAGS) -MM -c $< -MT $(basename [email protected]).o -o [email protected] 

$(OBJ_PATH)/%.d: %.c $(OBJ_PATH) 
    @echo +++ Dependencies of [$(notdir $<)] 
    @$(CC) $(CFLAGS) -MM -c $< -MT $(basename [email protected]).o -o [email protected] 

$(OBJ_PATH)/%.d: %.cpp $(OBJ_PATH) 
    @echo +++ Dependencies of [$(notdir $<)] 
    @$(CC) $(CPPFLAGS) -MM -c $< -MT $(basename [email protected]).o -o [email protected] 

#|---------------------------------------------------------------------------------------| 
#| 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 
--------------------------------------------------------------------------------------- 

我的錯誤來爲我的生成文件的這一部分:

PROJ_ASRCS = $(filter %.s,$(foreach file,$(SOURCES),$(file))) 
PROJ_ASRCS += $(filter %.S,$(foreach file,$(SOURCES),$(file))) 

我不想包含所有.o因爲我做了多個編譯,我只想列出所需的文件。

我有和ExperimentalCore-sam項目相同的編譯過程。

我該怎麼做?

+0

您的循環'$(的foreach文件,$(源),$(文件))'沒有做任何事情;你正在循環查看'SOURCES'中的每個單詞,並且每個單詞都將其展開爲該單詞......這是一種非常耗費資源的方式來恢復原始列表。除非你試圖做一些非常棘手的雙重評估事情。 – MadScientist

+0

是的,這是因爲我用不同的文件版本編譯不同的lib。我不想包含所有對象。我使用與此項目相同的構建系統:[ExperimentalCore-sam](https://github.com/aethaniel/ExperimentalCore-sam) –

+0

對不起,但我不理解您的評論或與我的相關內容。我只是說'$(foreach file,$(SOURCES),$(file))'不過是編寫'$(SOURCES)'的非常低效的方式。你會得到相同的結果。您循環訪問'$(SOURCES)'的值,併爲列表中的每個元素獲取相同的元素。 – MadScientist

回答

1

我只能假設變量AOBJS爲空。回到創建它的位置後,我只能假設這意味着您的SOURCES變量中沒有列出.s.S文件。

你爲什麼不跑的$(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 [email protected] $(filter %.o,$^) 
     $(NM) [email protected] > $(HAL_PATH)/$(OUTPUT_NAME)_symbols.txt 

與上面一樣,我一定會從必備項列表中刪除$(OBJ_PATH)

+0

我這樣做是因爲我不想在這個庫中包含所有'.o',所以SOURCES列表中確實沒有包含任何.s或.S。 –

+0

如果SOURCES列表中不包含任何'.s'或'.S'文件,那麼'AOBJS'的值將是空的(因爲我們發現:這就是導致原始問題的原因),所以'$( AOBJS)'在先決條件列表中將是空的,所以'$ ^'自動變量的值將不包含任何對象。我的改變給你以前的行爲。 – MadScientist

1

我瞭解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 
+0

我真的不明白爲什麼你不想在下面使用我建議的解決方案。它更簡單,更高效,因爲你只調用一次'ar'而不是三次。 – MadScientist

+0

你的建議是更通用的建議,但在我的情況下,我必須選擇我的檔案成員。我每次都用不同的輸入文件多次運行這個makefile。我不想在此存檔中添加衝突的二進制文件。 –

+0

看到我上面的評論。你的makefile在任何情況下的行爲都與我的行爲相同。 – MadScientist