Ошибка компилятора/компоновки: Freedup

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

Я пытаюсь скомпилировать программу из среды cygwin, используя последние стабильные версии gcc (3.4.4-999) и make (3.81-2). Я пытался удалить все объектные файлы и запустить make, но всегда получаю следующую ошибку:

freedup.o: В функции 'main':
/home/[user]/freedup-1.5/freedup.c:1791: неопределенная ссылка на '_hashed'
collect2: ld вернул 1 статус выхода make: * * * [свободное дублирование] Ошибка 1

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

Если кто-нибудь будет достаточно любезен, чтобы попытаться скомпилировать эту программу в среде Windows и ему повезет, я был бы очень признателен. Спасибо

Прямая ссылка на исходные файлы: http://freedup.org/freedup-1.5-3-src.tgz


person Community    schedule 07.12.2009    source источник
comment
не знаю насчет компиляции, но я использовал Perl-скрипт для фактической задачи (жесткая привязка дубликатов): cpansearch.perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/ — возможно, это работает и под Cygwin?   -  person Timo Metsälä    schedule 08.12.2009
comment
Источник, на который вы ссылаетесь, отлично подходит для меня, используя cygwin и gcc 3.4.4.   -  person karoberts    schedule 08.12.2009
comment
Попробуйте удалить inline... и надейтесь, что компилятор все равно его встроит :)   -  person pmg    schedule 08.12.2009
comment
@karoberts Какую версию Windows и Cygwin вы использовали?   -  person    schedule 08.12.2009


Ответы (2)


Меня не впечатляет код, в котором используется «#include <linux/stat.h>» вместо «#include <sys/stat.h>». Меня также не впечатлил код, в котором файл version.h содержит:

-e #define VERSION "1.5-3"

(Этот файл создается командой - 'echo -e '#define...' > version.h'. Тьфу!)

Если вы измените функцию с:

inline int hashed(const char*s)
{
    int returnval=atoi(s);

    if(returnval>2) returnval=2;
    if(returnval<0) returnval=0;
    return returnval;
}

to:

static
inline int hashed(const char*s)
{
    int returnval=atoi(s);

    if(returnval>2) returnval=2;
    if(returnval<0) returnval=0;
    return returnval;
}

(и исправить другие проблемы, упомянутые выше), затем он компилируется в MacOS X 10.6.2 с GCC "i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. сборка 5646) (точка 1 )».

Код теста дает сбой в случайных точках, так как он предполагает касание в /bin/touch (это /usr/bin/touch в MacOS X). Есть также много предупреждений о том, что «квалификаторы типов игнорируются в возвращаемом типе функции», поскольку «auto.h» определяет 4 функции как возвращающие «const int» (для различных ипостасей «int»), а также в указателях функций в структуре в тот же заголовок.

Я предполагаю, что это связано с недостаточным опытом авторов или недостаточно протестированными платформами. Команде version.h не нужно использовать вкладку (я полагаю, что «-e» предназначен для расширения нотации «\t» в командной строке — Makefile должен быть исправлен, чтобы опустить «-e» и заменить «\t» на простая пустышка.

Интересно поведение 'inline' в стандартном C99:

6.7.4 Спецификаторы функций

Синтаксис

спецификатор функции:

    inline

Ограничения

Спецификаторы функций должны использоваться только при объявлении идентификатора функции.

Встроенное определение функции с внешней связью не должно содержать определение изменяемого объекта со статической продолжительностью хранения и не должно содержать ссылку на идентификатор с внутренней связью.

В размещенной среде спецификатор встроенной функции не должен появляться в объявлении main.

Семантика

Функция, объявленная с помощью спецификатора встроенной функции, является встроенной функцией. Спецификатор функции может появляться более одного раза; поведение такое же, как если бы оно появилось только один раз. Превращение функции в встроенную предполагает, что вызовы функции будут максимально быстрыми.118) Степень эффективности таких предложений определяется реализацией.119)

Любая функция с внутренней связью может быть встроенной функцией. Для функции с внешней связью применяются следующие ограничения: Если функция объявлена ​​со спецификатором встроенной функции, то она также должна быть определена в той же единице перевода. Если все объявления области действия файла для функции в единице перевода включают встроенный спецификатор функции без extern, то определение в этой единице перевода является встроенным определением. Встроенное определение не предоставляет внешнее определение для функции и не запрещает внешнее определение в другой единице перевода. Встроенное определение представляет собой альтернативу внешнему определению, которое транслятор может использовать для реализации любого вызова функции в той же единице перевода. Не указано, использует ли вызов функции встроенное определение или внешнее определение.120)

118) Используя, например, альтернативу обычному механизму вызова функций, такую ​​как «встроенная подстановка». Встроенная замена не является текстовой заменой и не создает новую функцию. Поэтому, например, расширение макроса, используемого в теле функции, использует определение, которое оно имело в точке появления тела функции, а не в месте вызова функции; а идентификаторы относятся к объявлениям в области видимости, в которой находится тело. Точно так же функция имеет один адрес, независимо от количества встроенных определений, которые встречаются в дополнение к внешнему определению.

119) Например, реализация может никогда не выполнять встроенную замену или может выполнять встроенную замену только для вызовов в области действия встроенного объявления.

120) Поскольку встроенное определение отличается от соответствующего внешнего определения и любых других соответствующих встроенных определений в других единицах перевода, все соответствующие объекты со статической длительностью хранения также отличаются в каждом из определений.

person Jonathan Leffler    schedule 08.12.2009
comment
правильно по всем пунктам. Встроенные функции сложны. Если вы компилируете без оптимизации, и компилятор не встраивает вашу функцию, вы получите ошибку ссылки, если не поместите extern inline foo(); в одном файле .c, чтобы принудительно создать там не встроенное определение. - person Peter Cordes; 10.12.2009

Джонатан Леффлер дает ответ для freedup 1.5.3: добавить «статический» или удалить «встроенный» в хэш-функции. (Возможно, вам следует принять этот ответ.)

freedup 1.6-* вообще не компилируется на Cygwin:

socket.c:20:26: fatal error: net/ethernet.h: No such file or directory

Этот файл не существует в Cygwin.

person reinierpost    schedule 27.10.2011