kotyo87
1

Сборка проекта

30.05.2013, 12:55. Показов 3579. Ответов 2
Метки нет (Все метки)

Как правильно в makefile указать пути, по которым размещаются заголовочные файлы *.h. Зачастую при сборке проекта получается, что некая переменная (функция, тип) объявлена в некотором файле (.h) и этот файл найден компилятором (т.е. заголовочный файл включен в исходный файл директивой #include, компилятор на него не жалуется). Почему то он не может найти переменную, которая объявлена в этом заголовочном файле, т.е. выдает "... undefined reference to ...".

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.05.2013, 12:55
Ответы с готовыми решениями:

Сборка проекта для 32F411EDISCOVERY
Привет, друзья! Купил плату 32F411EDISCOVERY...

Сборка проекта для arm в qt
Доброго времени суток. Пытаюсь собрать проект для камня f103c8t6 в qt. После подключения...

Сборка и компиляция проекта (Keil, INTEL 8051)
здравствуйте можно ли выложить здесь исходный текст с комментариями, любой программы обращающейся...

Сборка проекта во время работы другого проекта
Здравствуйте! Можно ли в VS13, когда в одном решении находится несколько проектов, во время работы...

2
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
30.05.2013, 13:11 2
Если заголовок найден, то значит пути к нему указаны правильно.

Ошибка undefined reference to - это ошибка линкера. Это означает, что не скомпилирован соответствующий файл .c
Соответственно, добавить его в цели и проследить, чтобы он попал линкеру.
0
0 / 0 / 0
Регистрация: 25.05.2012
Сообщений: 37
15.07.2013, 19:11 3
Абсолютно согласен с Stiit.mi. Могу даже примерно рассказать про процесс компиляции и препроцессинга в котором вы явно не разбираетесь. Например у вас есть три файла
main.c:
Код
#include "lib.h"
void main(){
func();
}
lib.h:
Код
#ifndef lib_h
#define lib_h
void func();
#endif
lib.c:
Код
#include "lib.h"
void func(){
;
;
}
Теперь вы их собираете:
Код
сс параметры main.c -o main.o
cc параметры lib.c -o lib.o
Под cc я подразумеваю любой сишный компилятор будь то arm-none-eaby-gcc, или просто gcc, или avr-gcc...
В параметрах вы, например ключем -I говорите препроцессору (который встроен в компилятор) что бы он искал инклудники в определенных дерикториях (в папке, в которой находится компилируемый в данный момент исходник он ищет и так). Препроцессор - это такая штука, которая не генерирует бинарный код, а просто двигает-туда сюда исходный текст, еще до начала компиляции (процессинга - обработки). Препроцессор обычно отзывается на слова, начинающиеся со знака "#". Итак после того как препроцессор находит #include "lib.h", он ищет файл lib.h и тупо копирует его в файл main.c, в результате получается что-то такое:
main.c:
Код
#ifndef lib_h
#define lib_h
void func();
#endif
void main(){
func();
}
Препроцессор работает за несколько итераций, пока не останется слов, начинающихся с "#". Таким образом он пройдет по файлу main.c: еще разок, и наткнется на #ifndef lib_h. Эта штука пишется для того, что бы, если вы до этого уже включали файл в меин, он не был включен дважды. Дело в том, что препроцессор у себя внутри ведет список дефайнов, которые добавляются директивой #defymi. Первый раз #ifndef lib_h скажет что еще не разу не был задефайнен символ lib_h (не найдет его в своем списке), и оставит все что идет дальше до #endif. В процессе включения как раз таки и выполнится #define lib_h (lib_h включается в список) и если вдруг вы второй раз попробуете вызвать #ifndef lib_h он просто выкинет все, что до #endif.
В конечном счете у вас останется файл:
main.c:
Код:void func();
void main(){
func();
}

Все, решоток не осталось и теперь компилятор может превращать текст в байткод, и положить его в .o файл. Встретив прототип функции void func(); он положит в объектник заглушку без адреса, скажем __func. А адрес должен будет заполнить линкер в процесе линковки. То же будет при компиляции lib.c: препроцессор сделает такой файл:
main.c:
Код:void func();
void func(){
;
;
}

Тут уже компилятор не просто создаст заглушку, а реально объявит символ __func и предоставит его реализацию.
Теперь у нас есть два .o файла, которые нужно собрать в какой-нибудь .elf: Например часто линкер встроен в сам компилятор (или может им запускаться):
Код:сс параметры main.o lib.o -o main.elf
Линкер сначала включит весь объектный код и разложит его по реальным адресам (то есть когда он начнет включать lib.o, он сопоставит символу __func реальный адрес, например в arm-e 0х08002001 и запомнет его), а потом просто пробежится по фиктивным ссылкам (заглушкам), и заменит их на реальные адреса.
Так что вы, вероятно, просто не написали в своем мейк файле все объектники, типа так:
Код:сс параметры main.o -o main.elf
И в резултьтате линкер хотел бы разрешить все фиктивные ссылки, но не может, так как реально нету их реализаций, и кричит вам undefined reference to __func.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.07.2013, 19:11

Работа с картинками из ресурсов проекта и сборка проекта
Всем привет! Проблема вот в чем, я добавил в ресурсы проекта несколько картинок и хочу вывести их...

Сборка проекта
Переношу проект с версии 4+ на 5+ При попытке скомпилировать получаю 3 ошибки: :-1: ошибка:...

Сборка проекта
Всем добрый день! Начал изучать язык программирования C# в среде Visual Studio 2017, столкнулся с...

Сборка проекта
При сборке любого приложения возникает ошибка : Сообщения сборки - error: Error -1073741819....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.