Компиляция файлов .c и .s из разных подкаталогов - PullRequest
0 голосов
/ 20 августа 2010

Вот мой make-файл http://pastie.org/1104332. Я пытаюсь скомпилировать разные файлы .c и .s (файлы сборок) из разных подкаталогов в E: / em35x / build / mfg-sample-app-cortexm3- iar-em357-em3xx-dev0680 / тогда компоновщик должен связать все файлы .o из каталога сборки (E: / em35x / build / mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680) в файл с именем MFG-образец-app.out. Когда я запускаю make-файл, который я разместил выше, компилятор компилирует все исходные файлы в объектные файлы в каталоге сборки, но компоновщик не может открыть объектные файлы, потому что он не ищет их в каталоге сборки E: / em35x / строить / MFG-образец-приложение-cortexm3-IAR-em357-em3xx-dev0680. Я не знаю, как, почему компоновщик не выглядит там? вот ошибка, которую я получаю:

E:\IARSystems\EmbeddedWorkbench5.4Evaluation\arm\bin\ilinkarm.exe"      -o E:/e
m35x/build/mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680/mfg-sample-app.out --
map E:/em35x/build/mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680/mfg-sample-ap
p.map --log initialization,modules,sections,veneers --log_file E:/em35x/build/mf
g-sample-app-cortexm3-iar-em357-em3xx-dev0680/mfg-sample-app.log --config E:/em3
5x/app/mfglib/ewb-em357/../../../hal/micro/cortexm3/em35x/em357/iar-cfg.icf --di
ag_suppress Lp012 --entry halEntryPoint  E:/em35x/build/alarm-library-cortexm3-i
ar-em357-em3xx/alarm-library.a E:/em35x/build/binding-table-stub-library-cortexm
3-iar-em357-em3xx/binding-table-stub-library.a  E:/em35x/build/cbke-stub-library
-cortexm3-iar-em357-em3xx/cbke-stub-library.a E:/em35x/build/end-device-bind-stu
b-library-cortexm3-iar-em357-em3xx/end-device-bind-stub-library.a  E:/em35x/buil
d/hal-library-cortexm3-iar-em357-em3xx/hal-library.a E:/em35x/build/mfglib-libra
ry-cortexm3-iar-em357-em3xx/mfglib-library.a  E:/em35x/build/security-library-co
re-cortexm3-iar-em357-em3xx/security-library-core.a E:/em35x/build/security-libr
ary-link-keys-stub-cortexm3-iar-em357-em3xx/security-library-link-keys-stub.a E:
/em35x/build/zigbee-pro-stack-cortexm3-iar-em357-em3xx/zigbee-pro-stack.a E:/em3
5x/app/mfglib/mfg-sample.o E:/em35x/hal/ember-configuration.o E:/em35x/hal/micro
/cortexm3/adc.o E:/em35x/hal/micro/cortexm3/bootloader-interface-app.o E:/em35x/
hal/micro/cortexm3/bootloader-interface-standalone.o E:/em35x/hal/micro/cortexm3
/bootloader-interface.o E:/em35x/hal/micro/cortexm3/button.o E:/em35x/hal/micro/
cortexm3/buzzer.o E:/em35x/hal/micro/cortexm3/cstartup-iar-common.o E:/em35x/hal
/micro/cortexm3/diagnostic.o E:/em35x/hal/micro/cortexm3/led.o E:/em35x/hal/micr
o/cortexm3/mfg-token.o E:/em35x/hal/micro/cortexm3/micro-common.o E:/em35x/hal/m
icro/cortexm3/micro.o E:/em35x/hal/micro/cortexm3/sleep.o E:/em35x/hal/micro/cor
texm3/token-def.o E:/em35x/hal/micro/cortexm3/token.o E:/em35x/hal/micro/cortexm
3/uart.o E:/em35x/hal/micro/generic/crc.o E:/em35x/hal/micro/generic/endian.o E:
/em35x/hal/micro/generic/mem-util.o E:/em35x/hal/micro/generic/random.o E:/em35x
/hal/micro/generic/sim-eeprom.o E:/em35x/app/util/serial/cli.o E:/em35x/app/util
/serial/serial.o E:/em35x/hal/micro/cortexm3/em35x/mpu.o E:/em35x/hal/micro/cort
exm3/faults.o E:/em35x/hal/micro/cortexm3/isr-stubs.o

   IAR ELF Linker V5.50.5.51995/W32 for ARM
   Copyright (C) 2007-2010 IAR Systems AB.
Fatal error[Li001]: could not open file "E:\em35x\app\mfglib\mfg-sample.o"
Fatal error detected, aborting.
make: *** [mfg-sample-app.out] Error 3

(сначала он компилирует исходные файлы, но в конце не может найти объектные файлы в папке сборки)

Теперь, после того, как я удалю строку 70 из make-файла, который является

OBJ = $(SRC:.c=.o) E:/em35x/hal/micro/cortexm3/faults.o E:/em35x/hal/micro/cortexm3/isr-stubs.o

тогда компоновщик может найти предыдущие скомпилированные объектные файлы в каталоге компоновки и создать файл .out. И если я вручную удаляю все объектные файлы из каталога сборки (который компилятор создал ранее) и снова запускаю make-файл (строка 70 все еще удаляется), то я получаю эту ошибку:

$ make
make: *** No rule to make target `E:/em35x/build/mfg-sample-app-cortexm3-iar-em3
57-em3xx-dev0680/mfg-sample.o', needed by `mfg-sample-app.out'.  Stop.

И если я снова добавлю строку 70, которая будет:

OBJ = $(SRC:.c=.o) E:/em35x/hal/micro/cortexm3/faults.o E:/em35x/hal/micro/cortexm3/isr-stubs.o

затем он снова компилируется, но не связывается, потому что не может открыть объектные файлы. (Снова первая упомянутая ошибка)

Я не знаю, что я делаю неправильно. Я перепробовал много вещей, но не могу найти свою проблему.

Спасибо

РЕДАКТИРОВАТЬ : Я использую GNU Make 3.81

изменили последнюю строку на:

$(END_DIR)/%.o : %.c

и я также внес изменения в VPATH, как предложил Жиль, но не повезло.

Теперь я получаю этот erorr:

$ make
make: *** No rule to make target `E:/em35x/build/mfg-sample-app-cortexm3-iar-em3
57-em3xx-dev0680/mfg-sample.o', needed by `mfg-sample-app.out'.  Stop.

Он не компилирует какой-либо файл .c в файл .o

РЕДАКТИРОВАТЬ: Бета, я буду в состоянии проверить ваши линии в понедельник. Затем я сообщу результаты, я хочу решить эту проблему, это сводит меня с ума. Спасибо

EDIT:

Привет бета,

Я все еще получаю ту же ошибку с кодом, который вы предложили. Это ошибка, если mfg-sample.o не находится в папке сборки (E: / em35x / build / mfg-sample-app-cortexm3-iar-em3 57-em3xx-dev0680):

tjoyia@TJ-PC /e/em35x/build/mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680
$ make
make: *** No rule to make target `E:/em35x/build/mfg-sample-app-cortexm3-iar-em3
57-em3xx-dev0680/mfg-sample.o', needed by `mfg-sample-app.out'.  Stop.

Но если mfg-sample.o уже существует в папке сборки (после того, как я собрал mfg-sample.c в mfg-sample.o), я получаю это сообщение:

tjoyia@TJ-PC /e/em35x/build/mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680
$ make
found E:/em35x/build/mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680/mfg-sample.
o, making mfg-sample-app.out

EDIT:

Привет, бета, Да, это сработало.

Я получил это сообщение:

tjoyia@TJ-PC /e/em35x/build/mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680
$ make
found E:/em35x/app/mfglib/mfg-sample.c, making E:/em35x/build/mfg-sample-app-cor
texm3-iar-em357-em3xx-dev0680/mfg-sample.o
found E:/em35x/build/mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680/mfg-sample.
o, making mfg-sample-app.out

Итак, что мне теперь делать в моем исходном make-файле? Я хочу скомпилировать весь мой проект и связать объектные файлы (все мои файлы .c с разными путями в папке сборки, а затем компоновщик должен связать ранее созданные файлы .o с файлом .out)

EDIT:

Привет бета,

Хорошо, я все заработал, но как насчет двух файлов .s79, как я могу получить их также скомпилированными в объектные файлы в каталоге сборки? Почему VPATH не работает, и я думаю, что мое создание файла зависимостей (.d) не вызывается, как я могу вызвать его. Я хочу, чтобы все файлы .h (операторы #include в исходных файлах) автоматически распознавались и зависели от объектного файла.

И после этого я хочу преобразовать файлы .out, но он не вызывается.

Вот проблема:

Вы знаете, как я мог бы добавить это в мой make-файл:

ielftool.exe --srec --verbose E: \ em35x \ build \ mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680 \ mfg-sample-app.out E: \ em35x \ build \ mfg -sample-app-cortexm3-iar-em357-em3xx-dev0680 \ mfg-sample-app.s37

Он должен преобразовать файл mfg-sample-app.out в mfg-sample-app.s37 после того, как файл .out создан / связан с объектными файлами.

Ответы [ 3 ]

1 голос
/ 20 августа 2010

Во-первых, эта ссылка не указывает на make-файл, она указывает на вывод вашей попытки запустить make. Во-вторых, я не вижу доказательств того, что это на самом деле произвело mfg-sample-app.o, но вы говорите, что это так, поэтому я поверю на ваше слово.

Есть несколько разных причин, которые могут вызывать эту ошибку. Я предлагаю вам восстановить строку 70, начать с чистого листа и запустить make дважды . Я думаю, что есть большая вероятность, что он создаст объектные файлы на первом проходе и найдет их на втором. И независимо от того, что он делает, мы чему-то научимся. (Я бы посоветовал вам также перейти на более авторитетный компилятор / компоновщик, такой как gcc, но похоже, что он использует некоторые флаги нестандартным способом.)

Вторую ошибку, которую вы получили, легко понять: вы удалили строку, которая определяла список объектов, и в этом списке было определено правило, поэтому Make больше не знал, как создавать эти объекты. Но меня пугает, что Make знал, как вызвать компоновщик без этого списка; это говорит о том, что в вашем make-файле много избыточности, и это плохо.

Кстати, какую марку вы используете? Попробуйте запустить make -v и посмотрите, что там написано.

EDIT:
Теперь, когда я могу посмотреть на make-файл, я думаю, что смогу разгадать эту тайну.

Исходный файл, о котором идет речь, E:/em35x/app/mfglib/mfg-sample.c. Со строкой 70 Make просто меняет .c на .o и приходит к выводу, что рассматриваемый объектный файл - E:/em35x/app/mfglib/mfg-sample.o. Но вы жестко закодировали путь к каталогу компоновки во флаги компилятора ( очень плохая практика), так что туда идут файлы объектов. Затем, когда Make достигает шага связывания, он не может найти E:/em35x/app/mfglib/mfg-sample.o и умирает.

Когда вы запускаете без строки 70, он использует предыдущую строку и приходит к выводу, что mfg-sample.o должен находиться в каталоге сборки. Если этот объектный файл уже существует до запуска, Make связывает объектные файлы вместе, и все в порядке. Но если этого файла нет, то Make не может его собрать, потому что этот make-файл знает только один способ создания объектного файла - компиляция исходного кода , который находится в том же каталоге, где он намеревается создать объект *. 1031 *. Поскольку в каталоге сборки такого исходного файла нет, он умирает.

Этот make-файл может использовать много работы, но вот самое маленькое изменение, которое (вероятно) решит вашу проблему. (Вы не сказали, какую версию Make вы используете - это работает для GNUMake.) Избавьтесь от строки 70 и измените вторую до последней строки:

$(END_DIR)/%.o : %.c

Теперь, независимо от того, куда Make думает, что объектный файл должен идти, он будет искать исходный файл без пути (mfg-sample.c), и VPATH найдет его.

P.S. Жиль отметил, что разделитель в VPATH может не работать в Windows. Если предложенное мной изменение не работает, попробуйте также изменить разделитель, как предлагает Жиль (изменение только одного разделителя не поможет).

EDIT:
VPATH, похоже, не работает. Мы можем обойтись без этого, но я хотел бы попробовать последний эксперимент, прежде чем мы откажемся от него. Пожалуйста, попробуйте это и расскажите нам, что происходит:

END_DIR = E:/em35x/build/mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680

OBJ = $(END_DIR)/mfg-sample.o 

VPATH = E:/em35x/app/mfglib

mfg-sample-app.out : $(OBJ)
  @echo found $<, making $@

$(END_DIR)/%.o : %.c
  @echo found $<, making $@
  @touch $@

РЕДАКТИРОВАТЬ 3:
Хорошо, VPATH не работает - может быть, позже мы сможем выяснить, почему.

Попробуйте это (это может сработать, а может и нет - мне сложно проверить пути в стиле Windows):

END_DIR = E:/em35x/build/mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680

OBJ = $(END_DIR)/mfg-sample.o 

mfg-sample-app.out : $(OBJ)
  @echo found $<, making $@

$(END_DIR)/mfg-sample.o : E:/em35x/app/mfglib/mfg-sample.c

$(END_DIR)/%.o :
  @echo found $<, making $@
  @touch $@

РЕДАКТИРОВАТЬ 4:

Скрестите пальцы и попробуйте вставить это в свой настоящий make-файл (и избавиться от строки 70):

$(END_DIR)/mfg-sample.o: E:/em35x/app/mfglib/mfg-sample.c

$(END_DIR)/ember-configuration.o: E:/em35x/hal/ember-configuration.c

CORTEXM3 = adc \
bootloader-interface-app \
bootloader-interface-standalone \
bootloader-interface \
button \
buzzer \
cstartup-iar-common \
diagnostic \
led \
mfg-token \
micro-common \
micro \
sleep \
token-def \
token \
uart

CORTEXM3_OBJS = $(patsubst %,$(END_DIR)/%.o,$(CORTEXM3))
$(CORTEXM3_OBJS): $(END_DIR)/%.o : E:/em35x/hal/micro/cortexm3/%.c

GENERIC = crc \
endian \
mem-util \
random \
sim-eeprom

GENERIC_OBJS = $(patsubst %,$(END_DIR)/%.o,$(GENERIC))
$(GENERIC_OBJS): $(END_DIR)/%.o : E:/em35x/hal/micro/generic/%.c

$(END_DIR)/cli.o $(END_DIR)/serial.o: $(END_DIR)/%.o : E:/em35x/app/util/serial/%.c

$(END_DIR)/mpu.o: E:/em35x/hal/micro/cortexm3/em35x/mpu.c

$(END_DIR)/%.o :
    $(CC) $(CFLAGS) $(INCLUDES) $<

Видите, почему VPATH так удобен?

РЕДАКТИРОВАТЬ 5:

Файлы s79:

Мы меняем правило (последние две строки EDIT 4):

# change this:
#
# $(END_DIR)/%.o :
#    $(CC) $(CFLAGS) $(INCLUDES) $<

# to this:

$(END_DIR)/mfg-sample.o \
$(END_DIR)/ember-configuration.o \
$(CORTEXM3_OBJS) \
$(GENERIC_OBJS) \
$(END_DIR)/cli.o $(END_DIR)/serial.o \
$(END_DIR)/mpu.o:
    $(CC) $(CFLAGS) $(INCLUDES) $<

(Вы можете поместить эти цели в одну строку, если хотите, я собирался для удобочитаемости.)

Убедитесь, что это работает, затем добавьте другое правило для источников s79:

$(END_DIR)/faults.o $(END_DIR)/isr-stubs.o : $(END_DIR)/%.o : E:/em35x/hal/micro/cortexm3/%.s79
    @echo attempting to build $@ from $<
    $(ASM) $(AFLAG) $(AFLAG1) $(AFLAG2) $(AFLAG3) $(AFLAG4) $<

И обязательно добавьте эти два к переменной OBJ, чтобы Make знал, что нужно mfg-sample-app.out.

VPATH. Я не знаю, почему VPATH не работает.Возможно дополнительное расследование, но это очень трудно сделать удаленно, как это.Вы можете попробовать длинный вариант: в экспериментальном make-файле, который я предложил (во втором блоке EDIT), измените строку VPATH на:
vpath %.c E:/em35x/app/mfglib

(обратите внимание на нижний регистр.)

Файлы зависимостей (.d). Я не знаю, работают ли команды в правилах (у меня нет доступа к вашим инструментам "Embedded Workbench"), но причина, по которой правила не отображаются 'Вызывается, что операторы include используют переменную (sources), которая не определена.Make не может найти исходные файлы таким образом, поэтому он не думает, что он должен включать что-либо, поэтому он не думает, что должен что-то создавать (и не мог, даже если бы захотел, потому что не мог найтиисточники).Вместо этого вы можете использовать переменную SRC, но не забудьте добавить в файлы s79.

Преобразование файлов .out. Кусок торта:
E:\em35x\build\mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680\mfg-sample-app.s37 : mfg-sample-app.out
    ielftool.exe --srec --verbose $< $@

(Если вы хотите, чтобы это была ваша цель по умолчанию, поставьте ее перед всеми остальными.) Я жестко прописал путь к цели s37, потому что вы ее указали.Вы могли бы, вероятно, сделать только с mfg-sample-app.s37.

0 голосов
/ 21 августа 2010

Компоновщик делает именно то, что ему говорят: ему говорят связать "E: \ em35x \ app \ mfglib \ mfg-sample.o", которого не существует.

Существует проблема в определении VPATH в файле makefile: : используется как индикатор диска DOS / Windows и как разделитель пути. В Windows вы должны заменить : на ; или пробелами. (Это может нарушить совместимость с другими реализациями make для Unix, поэтому автор сценария, который сгенерировал этот (make) файл makefile, использовал :.)

VPATH = E:/em35x/app/mfglib/ E:/em35x/hal/ E:/em35x/hal/micro/cortexm3/ E:/em35x/hal/micro/generic/ E:/em35x/app/util/serial/ E:/em35x/hal/micro/cortexm3/ E:/em35x/build/mfg-sample-app-cortexm3-iar-em357-em3xx-dev0680/
0 голосов
/ 20 августа 2010

У вас есть два определения OBJ.Один явно перечисляет все объекты и говорит, что они находятся в END_DIR, но не существует правила для создания объектного файла в одном месте из исходного файла в другом каталоге.Второе правило использует исходные файлы и заменяет .c на .o (и объектные файлы будут в том же каталоге, что и исходные).

После того, как вы удалили второе правило, make использовал первое определение, чтобы определить, где должны быть ссылки на объектные файлы, но не знал, как их сгенерировать.Это объясняет вторую ошибку.Чтобы исправить это, измените правило компиляции, чтобы поместить объектные файлы в другой каталог, или используйте правило в строке 70, которое говорит, что они находятся в том же месте, что и источник.

Не ясно, почемуПервый проход не сработал, но я бы порекомендовал снять генерацию и включить файлы зависимостей (.d), пока компиляция не заработает.Я обнаружил, что гораздо полезнее создавать их как побочный эффект компиляции, чем создавать их явно.Если они не существуют, значит, вы ничего не скомпилировали и все равно должны выполнить полную сборку.

...