У меня странная проблема с включаемыми файлами и очевидное несоответствие между процессом сборки Eclipse и его отчетом об ошибках. Я дам подробные инструкции по воспроизведению этой проблемы, чтобы мы могли как можно быстрее сузить причины.
Eclipse 3.7.1 (Indigo SR1) для разработчиков C / C ++ Linux, 64-разрядная версия Ubuntu 10.10
Все началось, когда я импортировал существующий проект, который «работает» сам по себе: я думал, что Eclipse поможет значительно в навигации по файлам и выяснении того, что делает. Однако некоторые из системных заголовков #include
d, казалось, не имели правильного эффекта в представлении Eclipse. Это было очень загадочно, и в ходе исследования мне удалось воссоздать проблему в крошечной песочнице.
Шаг первый: Создайте новый проект C ( Файл: Новый: Проект C
), используя образец Hello World ANSI C Project
. Параметры: Исполняемый файл: Hello World ANSI C Project / Linux GCC
, оставшиеся Пустые
проекты установлены на Linux GCC
и GNU Autotools
установлено значение Hello World ANSI C Autotools Project
. Назовите это "привет". Обязательно сгенерируйте make-файл автоматически (расширенные настройки, я считаю, что это значение по умолчанию).
Шаг второй: Настройте путь включения. Использование Project: Свойства: C / C ++ Общие: Пути и символы: Включает: GNU C
, установите путь поиска на / usr / local / include
, / usr / lib /gcc/x86_64-linux-gnu/4.4.5/include
, / usr / include
. Второй путь зависит от установленной вами версии gcc. Это не имеет большого значения, если путь сборки включает как минимум / usr / include
.
Теперь, если вы откроете hello.c
, он будет выглядеть очень просто, и Eclipse будет вполне доволен, за исключением return EXIT_SUCCESS;
, который не может разрешить EXIT_SUCCESS
. Замените EXIT_SUCCESS
нулем ( 0
), и Eclipse выдаст полную очистку. Выберите Project: Build Project
, чтобы сгенерировать исполняемый файл.
Откройте окно командной строки и перейдите к подпапке hello / Debug папки рабочего пространства Eclipse . Оказавшись там, вы можете запустить исполняемый файл со строкой
./ hello
.
Теперь начинается самое интересное. Измените hello.c
, чтобы он читался во второй части:
#include <fcntl.h>
int main(void) {
printf("Hello World!\n");
int zz = SPLICE_F_MOVE;
printf("zz (SPLICE_F_MOVE) is '%d'\n", zz);
printf("Bye World!\n");
return 0;
}
Вы получите сообщение об ошибке в строке int zz ...
: «Символ 'SPLICE_F_MOVE' может не подлежит разрешению »
. Если вы выполните сборку проекта, вы получите аналогичную ошибку в представлении консоли: «ошибка: 'SPLICE_F_MOVE' undeclared»
.
Теперь, если вы измените преамбулу на:
#define _GNU_SOURCE
#include <fcntl.h>
Вы по-прежнему получите ошибку в строке int zz
(в редакторе), но проект будет построен правильно! Вы можете подтвердить это, запустив двоичный файл в окне командной строки, которое вы открыли ранее. Это действительно странно, поскольку изучение /usr/include/fcntl.h
покажет, что он #include
s
, и что последний заголовок #define
s SPLICE_F_MOVE
(и ряд других) в блоке, охраняемом #ifdef __USE_GNU
( __ USE_GNU
получает ] #define
d, если _GNU_SOURCE
равно #define
d). Почему наш #define _GNU_SOURCE
не распространяется должным образом в перспективе рабочей области?
Итак, это моя проблема в двух словах: почему редактор (и все Eclipse CDT) сообщает об ошибке (очевидно, отказавшись правильно обработать включение), но что базовая сборка завершается успешно?