IUP в C — tutorial не удается скомпилировать

#c #gcc #iup

#c #gcc #iup

Вопрос:

Я использую IUP в Manjaro GNU / Linux и пытаюсь скомпилировать первый образец программы с этого сайта. Однако компилятор сообщает, что он не может найти iup.h . Я установил IUP с помощью yaourt, установив пакет с именем iup-all-bin .

Для чего я должен изменить свою #include директиву на iup.h ?

Редактировать: благодаря одному из комментариев я смог найти файлы заголовка и библиотеки (я думаю!), Но теперь я получаю эту ошибку от GCC вместо этого:

 $gcc hello0.c -I/usr/include/iup-3.7/ -L/usr/lib -o hello0
/tmp/ccMAbPwz.o: In function `main':
hello0.c:(.text 0x1e): undefined reference to `IupOpen'
hello0.c:(.text 0x28): undefined reference to `IupLabel'
hello0.c:(.text 0x30): undefined reference to `IupDialog'
hello0.c:(.text 0x38): undefined reference to `IupShow'
hello0.c:(.text 0x3d): undefined reference to `IupMainLoop'
hello0.c:(.text 0x42): undefined reference to `IupClose'
collect2: error: ld returned 1 exit status
 

Я знаю, что libiup.so (вместе со всеми библиотеками, отличными от Lua) находятся в /usr/lib , и что файл заголовка находится в /usr/include/iup-3.7

Комментарии:

1. Никогда не слышал о IUP или Manjaro, но … скорее всего, вам нужно указать местоположение, в котором устанавливается IUP, используя -I/path/to/iup/include и -L/path/to/iup/lib в командной строке. Первый сообщает компилятору, где найти заголовки IUP ( iup.h ), а второй сообщает компоновщику, где найти библиотеки IUP. Это обоснованное предположение; детали могут отличаться, но схема, скорее всего, правильная. Возможно, это то, что вам нужно -I/usr/local/include , и -L/usr/local/lib или это может быть где-то еще.

2. @JonathanLeffler: Есть ли способ заставить GCC включать директивы -I and -L по умолчанию (как только я их найду)?

3. @KozRoss: обычно вы создаете a Makefile с соответствующей командной строкой в нем, поэтому вам нужно только ввести make , чтобы скомпилировать вашу программу.

4. @KozRoss: Могу я предложить попробовать -liup .

5. @KozRoss: Я добавил ответ.

Ответ №1:

Как вы можете знать или не знать, для перехода от исходного кода к исполняемому файлу необходимо выполнить два шага: компиляцию и компоновку. (Каждый из этих шагов сам по себе имеет шаги, но они не имеют отношения к обсуждению.)

Когда вы включаете файл с #include :

 #include <iup.h>
#include <stdlib.h>
/* ... */
 

iup.h и stdlib.h не появляются из воздуха. Это реальные имена файлов, и компилятор должен знать, где их найти, чтобы он мог послушно включать и обрабатывать их. stdlib.h находится в некотором каталоге (обычно /usr/include ), который компилятор будет искать по умолчанию, но когда вы устанавливаете нестандартные библиотеки, вам может потребоваться сообщить компилятору, где еще он может искать включаемые файлы, которые он не может найти в другом месте. Вот где -I появляется флаг. Если iup.h существует в /usr/include/iup-3.7 , вы можете -I/usr/include/iup-3.7 нажать, и компилятор будет искать там после того, как он не сможет найти iup.h /usr/include . В качестве хет-трика вам может показаться интересным, что поскольку /usr/include/iup-3.7 это подкаталог /usr/include , вы можете просто изменить #include директиву, если захотите:

 #include <iup-3.7/iup.h>
 

Но это может быть хрупким, если оно не всегда находится в iup-3.7 подкаталоге.


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

По умолчанию gcc будет ссылаться на стандартную библиотеку C, предоставляя вам доступ к таким функциям, как printf и exit . Но когда вы ссылаетесь на функции из внешней библиотеки, вы должны сообщить ей, что хотите связать это с вашей программой, и разрешить эти ссылки. Вы можете сделать это с помощью -l .

Наконец, я должен отметить, что -l он также использует путь поиска. Like -I , который добавляет к пути включения, -L добавляет к пути поиска библиотеки. Если ваши библиотеки расположены где-то нестандартно, вам нужно будет включить -L флаг, указывающий компоновщику, где найти библиотеку, в дополнение к -l флагу, указывающему компоновщику, что вы хотите ссылаться на определенную библиотеку.