Makefile C с несколькими архивами

У меня есть каталог, содержащий заголовки и исходный код небольшой коллекции любительских программ OpenGL. Моя цель — создать два основных заголовочных файла: «toolbox.h» и «geometry.h». Второе #include это первое. Я также хотел бы, чтобы для удобства источники, связанные с этими двумя заголовками, были объединены в два архива. Когда я make 01_Planet-Geom, ни один из символов из «toolbox.h» не найден, несмотря на то, что я включил его архив в правило make. make 00_Dyn-6D работает отлично.

Что мне нужно изменить, чтобы make 01_Planet-Geom?

  • Соответствующее правило make:
    01_Planet-Geom: 01_Planet-Geom.o toolbox.a geometry.a
    gcc $(CFLG) -o [email protected] $^ $(LIBS)
  • Я запускаю make 01_Planet-Geom из каталога проекта.
  • gcc версия 9.4.0
  • GNU Сделать 4.2.1

Я получаю следующий результат:

gcc -c -O3 -Wall -std=gnu17  01_Planet-Geom.c
gcc -c -O3 -Wall -std=gnu17  TriNet.c
ar -rcs geometry.a toolbox.a TriNet.o
gcc -O3 -Wall -std=gnu17 -o 01_Planet-Geom.out 01_Planet-Geom.o toolbox.a geometry.a -lglut -lGLU -lGL -lm
/usr/bin/ld: geometry.a(TriNet.o): in function `N_from_VF':
TriNet.c:(.text+0x151): undefined reference to `get_CCW_tri_norm'

... и многим другим это нравится. Это все функции, определенные в «vector-f_ops.c»…

/usr/bin/ld: TriNet.c:(.text+0x1abd): undefined reference to `dot_vec4f'
collect2: error: ld returned 1 exit status
make: *** [makefile:50: 01_Planet-Geom] Error 1

У меня есть следующее в «makefile»:

########## COMPILATION SETTINGS ##################

CFLG=-O3 -Wall -std=gnu17
LIBS=-lglut -lGLU -lGL -lm
CLEAN=rm -f *.out *.o *.a


########## DEPENDENCIES ##########################

### Prog Dependencies ###
00_Dyn-6D.o: 00_Dyn-6D.c toolbox.h
01_Planet-Geom.o: 01_Planet-Geom.c toolbox.h geometry.h

### Float Matrix Math ###
matrix4x4f.o: matrix4x4f.c matrix4x4f.h

### OpenGL Toolbox ###
OGL_utils.o: OGL_utils.c toolbox.h
load_assets.o: load_assets.c toolbox.h
vector-f_ops.o: vector-f_ops.c toolbox.h

### Geometry Construction ###
TriNet.o: TriNet.c toolbox.h geometry.h


########## ARCHIVES & GENERAL RULES ##############

toolbox.a: OGL_utils.o load_assets.o vector-f_ops.o
    ar -rcs $@ $^

geometry.a: toolbox.a TriNet.o
    ar -rcs $@ $^

# Compile rules
.c.o:
    gcc -c $(CFLG)  $<


########## PROGRAM & CLEAN RULES #################

##### Program Rules ##############################

00_Dyn-6D: 00_Dyn-6D.o toolbox.a
    gcc $(CFLG) -o [email protected] $^ $(LIBS)

01_Planet-Geom: 01_Planet-Geom.o toolbox.a geometry.a
    gcc $(CFLG) -o [email protected] $^ $(LIBS)


##### Clean Rule #################################

#  Clean
clean:
    $(CLEAN)

Я дважды проверил, что все исходные файлы имеют соответствующие заголовки.

«TriNet.c» успешно скомпилировался в другом контексте. Я подтвердил, что #include все еще работает после добавления правил для make 00_Dyn-6D и 01_Planet-Geom.

Отредактируйте свой вопрос, указав точную строку компиляции, используемую на последнем этапе.
Stephen Newell 09.05.2024 18:47

Также укажите точные сообщения об ошибках. Другими словами, вырежьте и вставьте в вопрос командную строку и получите сообщения об ошибках (если вы получаете тысячи сообщений, вы можете включить только ПЕРВЫЕ сообщения - при компиляции и связывании первые сообщения всегда стоят больше, чем последние сообщения).

MadScientist 09.05.2024 18:58

В каком файле определяется get_CCW_tri_norm?

stark 09.05.2024 20:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша связь не удалась по сочетанию двух причин.

Первый

это:

ar -rcs geometry.a toolbox.a TriNet.o

что является результатом правила Makefile:

geometry.a: toolbox.a TriNet.o
    ar -rcs $@ $^
    

Вы можете поверить, что ar -rcs geometry.a toolbox.a TriNet.o обладает эффектом извлечения все объектные файлы из архива toolbox.a и добавление их в целевой архив geometry.a вместе с объектным файлом TriNet.o.

Фактически, он просто архивирует файлы toolbox.a и TriNet.o в geometry.a, в результате чего этот geometry.a представляет собой архив, содержащий еще один архив toolbox.a и один объектный файл TriNet.o.

Когда в компоновщик вводится такой архив, как geometry.a, он учитывает только объектные файлы, являющиеся членами архива, как указано ar t geometry.a. Он извлечет из архива только те объектные файлы-члены, которые предоставить определения неопределенных символов ранее в выходном файле и статически свяжите их с выходным файлом, делая это итеративно, пока архив не даст результат больше не нужны определения.

Компоновщик не будет рассматривать объектные файлы, являющиеся членами архивы, входящие в geometry.a. Поэтому что geometry.a может способствовать вашим ссылкам - это всего лишь TriNet.o, что, конечно, не так достаточно.

Если вы хотите geometry.a иметь в качестве членов все объектные файлы в toolbox.a а также TriNet.o то вам нужно будет сделать geometry.a из тех же объектных файлов который вы поставили в toolbox.a плюс TriNet.o.

Если ar -rcs geometry.a toolbox.a TriNet.o сработало так, как кажется, вы этого ожидаете to, тогда было бы ненужно связывать geometry.a и toolbox.a в программы, требующие geometry.a, и вам понадобится какая-то другая причина для toolbox.a существовать (что, кажется, вы и делаете).

Но, видимо, вы все же считаете необходимым ввести в связку и то, и другое. вашей программы 01_Planet-Geom.out.

gcc -O3 -Wall -std=gnu17 -o 01_Planet-Geom.out 01_Planet-Geom.o toolbox.a geometry.a -lglut -lGLU -lGL -lm

чья связь не удалась:

/usr/bin/ld: geometry.a(TriNet.o): in function `N_from_VF':
TriNet.c:(.text+0x151): undefined reference to `get_CCW_tri_norm'

Что подводит нас к:

Второй

geometry.a содержит только объектный файл TriNet.o, насколько может видеть компоновщик. Но TriNet.o содержит неопределенную ссылку на get_CCW_tri_norm, которая (держу пари) определена в члене toolbox.a.

У вас есть ввод toolbox.a для связи, но вы ввели его до geometry.a. Так когда компоновщик проверил toolbox.a, ему не было известно об отсутствии неопределенной ссылки на get_CCW_tri_norm и поэтому не искал, не извлекал и не связывал какой-либо объектный файл из toolbox.a, который содержит определение из get_CCW_tri_norm. Ни один вводимый впоследствии файл не дает такого определения. поэтому символ остается неопределенным в конце связи.

Файлы, которые вводят в связь неопределенные символы, должны передаются компоновщику перед библиотеками, предоставляющими их определения. Компоновщик проверит библиотеку только для того, чтобы найти определения неопределенных символов, которые уже есть в наличии, и не оглядываться назад.

Спасибо! Соответствующие исправления были: geometry.a: TriNet.oar -rcs $@ $^ и 01_Planet-Geom: 01_Planet-Geom.o geometry.a toolbox.a gcc $(CFLG) -o [email protected] $^ $(LIBS).

James Watson 10.05.2024 03:11

Другие вопросы по теме