Связывание со статической библиотекой
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" там.