Pergunta

Eu estou tendo um problema com meu compilador me dizendo há uma 'referência indefinida para' uma função que eu quero usar em uma biblioteca. Deixem-me partilhar algumas informações sobre o problema:

  • Eu sou compilação cruzada com gcc para C.
  • Eu estou chamando uma função de biblioteca que é acessado através de um cabeçalho incluído, que inclui outro cabeçalho, que contém o protótipo.
  • Eu incluí o diretório cabeçalhos usando -I e eu tenho certeza que ele está sendo encontrado.
  • Estou primeiro criar os arquivos .o, em seguida, ligando-os em um comando separado.

Então, meu pensamento é que poderia ser a ordem na qual incluo os arquivos de biblioteca, mas não tenho certeza qual é a maneira correta de encomendá-los. Eu tentei com incluindo os cabeçalhos de pasta antes e depois do arquivo .o.

Alguns sugere seria ótimo, e talvez e explicação de como o vinculador faz sua coisa.

Obrigado!


Response to respostas

  • não há nenhum arquivo de biblioteca .a, apenas .he .c na biblioteca, então -l não é apropriado
  • minha compreensão de um arquivo de biblioteca é que ele é apenas uma coleção de arquivos de inclusão e de código, mas talvez seja uma coleção de .o arquivos criados a partir da fonte?!
  • não há nenhum arquivo objeto de biblioteca que está sendo criado, talvez deve haver ?? Sim parece que eu não entendo a diferença entre inclui e bibliotecas ... eu vou trabalhar nisso: -)

Obrigado por todas as respostas! Eu aprendi muito sobre as bibliotecas. Eu gostaria de colocar todas as respostas como a resposta aceita: -)

Foi útil?

Solução

Parece que você não está compilando o arquivo .c na biblioteca para produzir um arquivo .o. O vinculador ficaria para a implementação do protótipo no arquivo .o produzido por compilar a biblioteca

Será que o seu processo de compilação compilar o arquivo .c biblioteca?

Por que você chamá-lo de uma "biblioteca" se é realmente o código-fonte apenas?

Outras dicas

cabeçalhos apresentar declarações de função e definições de função. Para permitir que o linker encontra a implementação da função (e livrar-se da referência indefinida), você precisa pedir ao motorista compilador (gcc) para ligar a biblioteca específica onde reside a função usando o sinalizador -l. Por exemplo, -lm vai ligar a biblioteca de matemática. página do manual de uma função tipicamente especifica que biblioteca, se houver, devem ser especificados para encontrar a função.

Se o vinculador não é possível encontrar uma biblioteca especificada você pode adicionar um caminho de pesquisa da biblioteca usando o interruptor -L (por exemplo, -L / usr / / lib local). Você também pode afetar permanentemente o caminho da biblioteca através da variável de ambiente LIBRARY_.

Aqui estão alguns detalhes adicionais para ajudar a depurar o seu problema. Por convenção os nomes de arquivos de biblioteca são prefixados com lib e (em sua forma estática) têm uma extensão .a. Assim, a versão estaticamente ligado da biblioteca de matemática padrão do sistema (o que você vincular com -lm) geralmente reside no /usr/lib/libm.a. Para ver o que símbolos um determinado define biblioteca você pode executar nm --defined-somente no arquivo de biblioteca. No meu sistema, executar o comando em libm.a me dá saída como a seguinte.

e_atan2.o:
00000000 T atan2

e_asinf.o:
00000000 T asinf

e_asin.o:
00000000 T asin

Para ver o caminho da biblioteca que usa seu compilador e as bibliotecas ele carrega por padrão você pode invocar o gcc com a opção -v. Mais uma vez no meu sistema que dá o seguinte resultado.

GNU assembler version 2.15 [FreeBSD] 2004-05-23 (i386-obrien-freebsd) 
using BFD version 2.15 [FreeBSD] 2004-05-23
/usr/bin/ld -V -dynamic-linker /libexec/ld-elf.so.1 /usr/lib/crt1.o 
/usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /var/tmp//ccIxJczl.o -lgcc -lc 
-lgcc /usr/lib/crtend.o /usr/lib/crtn.o

temo que misturou os conceitos de biblioteca e cabeçalho. Vamos dizer que você tem uma libmylib.a biblioteca que contém o myfunc() função e uma mylib.h cabeçalho correspondente que define seu protótipo. Em sua myapp.c arquivo de origem que você incluir o cabeçalho, diretamente ou incluindo outro cabeçalho que inclui. Por exemplo:

/* myapp.h
** Here I will include and define my stuff
*/
...
#include "mylib.h"
...

sua aparência arquivo de origem como:

/* myapp.c
** Here is my real code
*/
...
#include "myapp.h"
...
/* Here I can use the function */
myfunc(3,"XYZ");

Agora você pode compilá-lo para obter myapp.o:

gcc -c -I../mylib/includes myapp.c

Note que o -I apenas diz gcc onde os arquivos de cabeçalhos são, eles não têm nada a ver com a própria biblioteca!

Agora você pode vincular sua aplicação na biblioteca real:

gcc -o myapp -L../mylib/libs myapp.o -lmylib

Note que o interruptor -L diz gcc onde a biblioteca é, eo -l diz-lhe para ligar seu código para a biblioteca.

Se você não fizer este último passo, você pode encontrar o problema que você descreveu.

Pode haver outros casos mais complexos, mas a partir de sua pergunta, eu espero que isso seria suficiente para resolver seu problema.

Coloque seu makefile, e a função de biblioteca que você está tentando chamar. Mesmo makefiles gcc simples costumam ter uma linha como esta:

LIBFLAGS =-lc -lpthread -lrt -lstdc++ -lShared -L../shared

Neste caso, isso significa ligar a biblioteca C padrão, entre outros

Eu acho que você tem que adicionar o caminho onde o vinculador pode encontrar o libraray. Em gcc / ld você pode fazer isso com -L e libraray com -l.

-Ldir, --library-path = dir

Procurar diretório dir antes de padrão aos diretórios de busca (Esta opção deve preceder a opção -l que pesquisas esse diretório).

-larch, --library = arquivo

Inclua o arco arquivo no lista de arquivos a ligação.


Response to respostas - não há nenhum arquivo de biblioteca .a, apenas .he .c na biblioteca, então -l não é approriate

Em seguida, você pode ter que criar o libraray primeiro?

gcc -c mylib.c -o mylib.o
ar  rcs libmylib.a      mylib.o

Eu encontrei este problema ao construir um programa com uma nova versão do gcc. O problema foi corrigido chamando gcc com a -std = gnu89 opção. Aparentemente, isso foi devido a declarações de função in-line. Eu encontrei esta solução em https://gcc.gnu.org/gcc-5/porting_to .html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top