Связывание со статической библиотекой

gcc версия: 4:4.4.4-1ubuntu2 GNU Make 3.81

У меня есть следующая библиотека под названием net_api.a и некоторые заголовочные файлы, т.е.

network_set.h

Я включил заголовочный файл в мой исходный код в файл main.c

#include <network_set.h>

У меня есть следующая статическая библиотека и заголовок в следующем каталоге

./tools/net/lib/net_api.a
./tools/net/inc/network_set.h

В моем Makefile я попытался создать ссылку, используя следующий фрагмент кода:

INC_PATH = -I tools/net/inc
LIB_PATH = -L tools/net/lib

LIBS = -lnet_api

$(TARGET): $(OBJECT_FILES)
    $(CC) $(LDFLAGS) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(LIBS) $(OBJECT_FILES) -o $(TARGET)

main.o: main.c
    $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) -c main.c

Однако, когда я компилирую, я получаю следующие ошибки:

network_set.h error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘network_String’

Что здесь не так?

3 ответа

Решение

составление

Первая проблема, с которой вам приходится сталкиваться, заключается в том, почему код не компилируется. Есть проблема в вашем network_set.h заголовок; в некотором роде он не самодостаточен, поэтому вам нужно включить что-то еще, прежде чем включать его, или вы должны явно настроить его каким-либо образом. Вы должны стремиться к тому, чтобы ваши заголовки были как автономными, так и идемпотентными.

  • автономный может быть включен без каких-либо других заголовков, предшествующих ему
  • идемпотент может быть включен несколько раз, не вызывая хаоса

Самодостаточность достигается за счет того, что он может быть первым заголовком, включенным в исходный файл, а затем аккуратно компилироваться. Это означает, что если он использует функцию (например, size_tзатем он включает в себя заголовок, который определяет функцию (например, <stddef.h>).

Идемпотентность достигается путем включения защиты головы:

#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
...main body of header...
#endif /* HEADER_H_INCLUDED */

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

#!/bin/ksh
#
# @(#)$Id: chkhdr.sh,v 1.2 2010/04/24 16:52:59 jleffler Exp $
#
# Check whether a header can be compiled standalone

tmp=chkhdr-$$
trap 'rm -f $tmp.?; exit 1' 0 1 2 3 13 15

cat >$tmp.c <<EOF
#include HEADER /* Check self-containment */
#include HEADER /* Check idempotency */
int main(void){return 0;}
EOF

options=
for file in "$@"
do
    case "$file" in
    (-*)    options="$options $file";;
    (*)     echo "$file:"
            gcc $options -DHEADER="\"$file\"" -c $tmp.c
            ;;
    esac
done

rm -f $tmp.?
trap 0

Например:

chkhdr -Itools/net/inc tools/net/inc/network_set.h

соединение

Со временем, после того, как вы исправите проблемы компиляции, вы столкнетесь с проблемами компоновки. Опция -lnet_api ищет библиотеку с именем libnet_api.so или же libnet_api.a,

Чтобы связаться с net_api.aвам нужно будет передать путь к файлу команде link:

LIB_DIR     = ./tools/net/lib
LIB_NET_API = net_api.a
LIB_PATH    = -L ${LIB_DIR}

    ${CC} ... ${LIB_DIR}/${LIB_NET_API} ...

Очевидно, вы можете определить макрос для пути ко всей библиотеке. Обратите внимание, как я переопределил LIB_PATH в терминах макроса LIB_DIR.

Заголовок network_set.h имеет дополнительные зависимости, которые должны быть включены в первую очередь, одним из которых является определение network_String, Проверьте документацию библиотеки или обратитесь к автору за более подробной информацией.

Вы не показываете свои LDFLAGS; Я предполагаю, что они определены, но вы просто не опубликовали их. Они должны включать "-static", если вы строите против статической библиотеки.

Если вы не знаете, что это такое, посмотрите на вывод компилятора в начале, где он начинается с "gcc", и посмотрите, появляется ли "-static" там.

Другие вопросы по тегам