2017-02-14 12 views
0

일부 C 코드를 리팩터링하고 리눅스에서 gcc 대신 clang의 lib로 컴파일하려고합니다. 난 그냥 첫 번째 파일 컴파일에서 오류가 발생했습니다 make 명령을 실행하는 모든 경우의clang makefile "ar : 아카이브 멤버가 지정되지 않았습니다"

첫째 : +++ 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 

내 메이크입니다 :

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

왜 그 소리는 저에게이 인상은?

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

내 실수는 내 메이크의이 부분의 오지 :


감사의 난이 오류가 왜 나는 내가 가진 내 메이크업에 물건을 인쇄하는 경우 내가 이해 @MadScientist하는

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] –

+0

미안하지만, 귀하의 의견이나 그것이 내 작업과 관련이 있는지 이해하지 못합니다. 내가 말하고자하는 것은'$ (소스 파일, $ (소스), $ (파일))'은'$ (SOURCES)'를 작성하는 데 비효율적 인 방법이라는 것입니다. 같은 결과가 나옵니다. 당신은'$ (SOURCES)'의 값을 반복하고 있으며리스트의 각 원소에 대해 같은 원소를 얻고있다. – MadScientist

답변

1

변수 AOBJS은 비어 있다고 가정 할 수 있습니다. 생성 된 위치를 다시 살펴보면, SOURCES 변수에 .s 또는 .S 파일이 나열되지 않는다고 가정 할 수 있습니다.

$(AR)의 단일 호출을 실행하지 않고 바로 $^ 자동 변수를 사용하여 .o 파일보다는 $(AR) 명령의 세 가지 다른 호출을 필터링?

$(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 
: 당신이 더 많은 관용구 정확하기를 원한다면,

$(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 

을 또는 :

$(AR) -rv $(OUTPUT_FILE_PATH) $(filter %.o,$^) 

편집 난 당신이 당신의 출력 대상 규칙을 변경 제안하고있어 명확하게하려면

위와 같이 전제 조건 목록에서 $(OBJ_PATH)을 확실히 제거 할 수 있습니다.

+0

이 lib에 모든'.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 '을 3 번 대신에 한 번만 호출하기 때문입니다. – MadScientist

+0

당신의 제안은 좀 더 일반적인 것이지만 제 경우에는 저의 아카이브 회원을 선택해야합니다. 매번이 makefile을 여러 입력 파일로 여러 번 실행합니다. 이 아카이브에 충돌하는 바이너리를 추가하고 싶지 않습니다. –

+0

위의 코멘트를 참조하십시오. 귀하의 메이크 파일은 모든 상황에서 동일하게 작동합니다. – MadScientist