У меня странная проблема с включаемыми файлами и очевидное несоответствие между процессом сборки Eclipse и его отчетами об ошибках. Я подробно расскажу о том, как воспроизвести эту проблему, чтобы мы могли как можно быстрее сузить причины.
Eclipse 3.7.1 (Indigo SR1) для разработчиков Linux на C / C ++, Ubuntu 10.10, 64-битная
Все началось, когда я импортировал существующий проект, который сам по себе "отлично" работает: я думал, что Eclipse значительно поможет в навигации по файлам и выяснении, что и для чего. Однако некоторые системные заголовки #include
d, по-видимому, не дают правильного эффекта в представлении Eclipse. Это было очень загадочно, и в ходе исследования мне удалось воссоздать проблему в крошечной песочнице.
Шаг первый: создайте новый проект C (File: New: C Project
), используя образец Hello World ANSI C Project
. Параметры Executable: Hello World ANSI C Project/Linux GCC
, остальные Empty
проекты установлены на Linux GCC
, а GNU Autotools
установлены на Hello World ANSI C Autotools Project
. Назовите это "привет". Обязательно создайте make-файл автоматически (Расширенные настройки, я считаю, что это по умолчанию).
Шаг второй: Настройте путь включения. Используя Project: Properties: C/C++ General: Paths and Symbols: Includes: 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...
вы получите ошибку: "Symbol 'SPLICE_F_MOVE' could not be resolved"
. Если вы создадите проект, вы увидите похожую ошибку в представлении консоли: "error: 'SPLICE_F_MOVE' undeclared"
.
Теперь, если вы измените преамбулу на:
#define _GNU_SOURCE
#include <fcntl.h>
Вы все еще получаете сообщение об ошибке в строке int zz
(в редакторе), но проект будет построен правильно! Вы можете подтвердить это, запустив двоичный файл в окне командной строки, которое вы открыли ранее. Это действительно странно, так как проверка /usr/include/fcntl.h
покажет, что это #include
s <bits/fcntl.h>
, и этот последний заголовок #define
s SPLICE_F_MOVE
(и множество других) в блоке, охраняемом #ifdef __USE_GNU
(__USE_GNU
получает #define
d, если _GNU_SOURCE
равно #define
d). Почему на земле наше #define _GNU_SOURCE
не распространяется должным образом в перспективе рабочего пространства?
Итак, это моя проблема в двух словах: почему редактор (и все Eclipse CDT) сообщает об ошибке (очевидно, отказываясь правильно обрабатывать включение), но что базовая сборка завершается успешно?