Criando e instalando bibliotecas dinamicas e estaticas no linux[RESOLVIDO]

1. Criando e instalando bibliotecas dinamicas e estaticas no linux[RESOLVIDO]

Jean César
dark777

(usa Slackware)

Enviado em 13/10/2017 - 08:58h

wiki.anon

Beleza moçada fiz ums lib que limpa os buffers do teclado e queria saber como faço para criar as bibliotecas dinamicas e estaticas instalando as mesmas corretamente no meu SO para o compilador reconhecer elas ao realizar o seguinte comando:

$ gcc -o prog prog.c -l<minhabiblioteca>


  


2. Re: Criando e instalando bibliotecas dinamicas e estaticas no linux[RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 13/10/2017 - 15:06h

dark777 escreveu:

Beleza moçada fiz ums lib que limpa os buffers do teclado


Poderia mostrar como você fez? Há muitas maneiras erradas de fazer isso, e eu gostaria de ver se você não incorreu num desses erros.

e queria saber como faço para criar as bibliotecas dinamicas e estaticas instalando as mesmas corretamente no meu SO para o compilador reconhecer elas ao realizar o seguinte comando:

$ gcc -o prog prog.c -l<minhabiblioteca>


Para criar bibliotecas estáticas, você simplesmente compila (sem invocar o linker) os programas que fazem parte dela, e os junta num arquivo.

gcc -c arq1.c arq2.c arq3.c
ar -crs libABCD.a arq1.o arq2.o arq3.o


Para as dinâmicas, será parecido, mas a etapa de compilação precisa que o código seja gerado como independente de posição na memória, e a junção de múltiplos módulos na mesma biblioteca se faz através do ld (ou do gcc como front-end para o ld).

gcc -fPIC -c arq1.c arq2.c arq3.c
gcc -shared -Wl,-soname,libABCD.so.1 -o libABCD.so.1.0 arq1.o arq2.o arq3.o
ln -s libABCD.so.1.0 libABCD.so.1
ln -s libABCD.so.1.0 libABCD.so


Se você for administrador da máquina, pode eventualmente colocar as bibliotecas num diretório padrão de bibliotecas da sua máquina. Quais são essas diretórios pode variar de uma máquina para outra, de acordo com as regras definidas em /etc/ld.so.conf, mas comumente prevê um diretório local, como /usr/local/lib. Nesse caso, você pode copiar suas bibliotecas para lá.

sudo cp -p libABCD.{a,so*} /usr/local/lib/
ldconfig # regenera o cache de bibliotecas, de modo a incluir a nova lib nesse cache


Instalando num diretório padrão, fica fácil usar as bibliotecas.

gcc -static prog.c -lABCD -o prog-static 

gcc prog.c -lABCD -o prog-dynamic 


Se você não puder ou não quiser instalar as bibliotecas em áreas gerais do sistema, pode especificar o caminho da biblioteca no momento do linking. No caso de bibliotecas estáticas, isso é muito fácil.

gcc -static prog.c -L/home/fulano/lib -lABCD -o prog-static 


Com a biblioteca dinâmica, a ligação é feita em duas etapas: uma no momento da geração do executável (pelo ld, que pode ser invocado através do gcc), e outra a cada vez que o programa for executado (pelo comando ld.so). Assim sindo, você precisa embutir no execuável as informações necessárias para que o ld.so encontre as bibliotecas na hora da execução.

gcc prog.c -L/home/fulano/lib -Wl,-rpath,/home/fulano/lib -lABCD -o prog-dynamic 


Se você pretende distribuir um executável que dependa de uma biblioteca dinâmica, tem de distribuir a biblioteca também. Para tanto, existem duas opções principais. A primeira é você criar um pacote (.rpm, .deb ou similar) que instale a biblioteca num dos diretórios padronizados e regenere o cache, e num outro pacote distribuir sua aplicação.

A outra opção é colocar a biblioteca junto com o executável, e fazer com que o executável procure a biblioteca no mesmo diretório em que ele estiver instalado, ou algum diretório relativo ao local onde ele estiver instalado. Isso se consegue por meio da macro “$ORIGIN” passada como argumento da opção -rpath do linker.

gcc prog.c -L/home/fulano/lib -Wl,-rpath,'$ORIGIN'/../lib -lABCD -o prog-dynamic
# Se prog-dynamic for instalado em /home/fulano/bin, vai procurar a biblioteca
# em /home/fulano/lib. Se for instalado em /opt/teste, vai procurar em /opt/lib.



3. Re: Criando e instalando bibliotecas dinamicas e estaticas no linux[RESOLVIDO]

Jean César
dark777

(usa Slackware)

Enviado em 13/10/2017 - 22:14h

paulo1205 escreveu:

dark777 escreveu:

Beleza moçada fiz ums lib que limpa os buffers do teclado


Poderia mostrar como você fez? Há muitas maneiras erradas de fazer isso, e eu gostaria de ver se você não incorreu num desses erros.

e queria saber como faço para criar as bibliotecas dinamicas e estaticas instalando as mesmas corretamente no meu SO para o compilador reconhecer elas ao realizar o seguinte comando:

$ gcc -o prog prog.c -l<minhabiblioteca>


Para criar bibliotecas estáticas, você simplesmente compila (sem invocar o linker) os programas que fazem parte dela, e os junta num arquivo.

o programinha que fiz foi este minha intenção é que o mesmo seja compilado tanto em linux quanto windows

https://pastebin.com/T0iXfxX1

gcc -c arq1.c arq2.c arq3.c
ar -crs libABCD.a arq1.o arq2.o arq3.o


Para as dinâmicas, será parecido, mas a etapa de compilação precisa que o código seja gerado como independente de posição na memória, e a junção de múltiplos módulos na mesma biblioteca se faz através do ld (ou do gcc como front-end para o ld).

gcc -fPIC -c arq1.c arq2.c arq3.c
gcc -shared -Wl,-soname,libABCD.so.1 -o libABCD.so.1.0 arq1.o arq2.o arq3.o
ln -s libABCD.so.1.0 libABCD.so.1
ln -s libABCD.so.1.0 libABCD.so


Se você for administrador da máquina, pode eventualmente colocar as bibliotecas num diretório padrão de bibliotecas da sua máquina. Quais são essas diretórios pode variar de uma máquina para outra, de acordo com as regras definidas em /etc/ld.so.conf, mas comumente prevê um diretório local, como /usr/local/lib. Nesse caso, você pode copiar suas bibliotecas para lá.

sudo cp -p libABCD.{a,so*} /usr/local/lib/
ldconfig # regenera o cache de bibliotecas, de modo a incluir a nova lib nesse cache


Instalando num diretório padrão, fica fácil usar as bibliotecas.

gcc -static prog.c -lABCD -o prog-static 

gcc prog.c -lABCD -o prog-dynamic 


Se você não puder ou não quiser instalar as bibliotecas em áreas gerais do sistema, pode especificar o caminho da biblioteca no momento do linking. No caso de bibliotecas estáticas, isso é muito fácil.

gcc -static prog.c -L/home/fulano/lib -lABCD -o prog-static 


Com a biblioteca dinâmica, a ligação é feita em duas etapas: uma no momento da geração do executável (pelo ld, que pode ser invocado através do gcc), e outra a cada vez que o programa for executado (pelo comando ld.so). Assim sindo, você precisa embutir no execuável as informações necessárias para que o ld.so encontre as bibliotecas na hora da execução.

gcc prog.c -L/home/fulano/lib -Wl,-rpath,/home/fulano/lib -lABCD -o prog-dynamic 


Se você pretende distribuir um executável que dependa de uma biblioteca dinâmica, tem de distribuir a biblioteca também. Para tanto, existem duas opções principais. A primeira é você criar um pacote (.rpm, .deb ou similar) que instale a biblioteca num dos diretórios padronizados e regenere o cache, e num outro pacote distribuir sua aplicação.

A outra opção é colocar a biblioteca junto com o executável, e fazer com que o executável procure a biblioteca no mesmo diretório em que ele estiver instalado, ou algum diretório relativo ao local onde ele estiver instalado. Isso se consegue por meio da macro “$ORIGIN” passada como argumento da opção -rpath do linker.

gcc prog.c -L/home/fulano/lib -Wl,-rpath,'$ORIGIN'/../lib -lABCD -o prog-dynamic
# Se prog-dynamic for instalado em /home/fulano/bin, vai procurar a biblioteca
# em /home/fulano/lib. Se for instalado em /opt/teste, vai procurar em /opt/lib.




wiki.anon


4. Re: Criando e instalando bibliotecas dinamicas e estaticas no linux[RESOLVIDO]

Jean César
dark777

(usa Slackware)

Enviado em 13/10/2017 - 22:17h

paulo1205 escreveu:

dark777 escreveu:

Beleza moçada fiz ums lib que limpa os buffers do teclado


Poderia mostrar como você fez? Há muitas maneiras erradas de fazer isso, e eu gostaria de ver se você não incorreu num desses erros.

e queria saber como faço para criar as bibliotecas dinamicas e estaticas instalando as mesmas corretamente no meu SO para o compilador reconhecer elas ao realizar o seguinte comando:

$ gcc -o prog prog.c -l<minhabiblioteca>


Para criar bibliotecas estáticas, você simplesmente compila (sem invocar o linker) os programas que fazem parte dela, e os junta num arquivo.

gcc -c arq1.c arq2.c arq3.c
ar -crs libABCD.a arq1.o arq2.o arq3.o


Para as dinâmicas, será parecido, mas a etapa de compilação precisa que o código seja gerado como independente de posição na memória, e a junção de múltiplos módulos na mesma biblioteca se faz através do ld (ou do gcc como front-end para o ld).

gcc -fPIC -c arq1.c arq2.c arq3.c
gcc -shared -Wl,-soname,libABCD.so.1 -o libABCD.so.1.0 arq1.o arq2.o arq3.o
ln -s libABCD.so.1.0 libABCD.so.1
ln -s libABCD.so.1.0 libABCD.so


Se você for administrador da máquina, pode eventualmente colocar as bibliotecas num diretório padrão de bibliotecas da sua máquina. Quais são essas diretórios pode variar de uma máquina para outra, de acordo com as regras definidas em /etc/ld.so.conf, mas comumente prevê um diretório local, como /usr/local/lib. Nesse caso, você pode copiar suas bibliotecas para lá.

sudo cp -p libABCD.{a,so*} /usr/local/lib/
ldconfig # regenera o cache de bibliotecas, de modo a incluir a nova lib nesse cache


Instalando num diretório padrão, fica fácil usar as bibliotecas.

gcc -static prog.c -lABCD -o prog-static 

gcc prog.c -lABCD -o prog-dynamic 


Se você não puder ou não quiser instalar as bibliotecas em áreas gerais do sistema, pode especificar o caminho da biblioteca no momento do linking. No caso de bibliotecas estáticas, isso é muito fácil.

gcc -static prog.c -L/home/fulano/lib -lABCD -o prog-static 


Com a biblioteca dinâmica, a ligação é feita em duas etapas: uma no momento da geração do executável (pelo ld, que pode ser invocado através do gcc), e outra a cada vez que o programa for executado (pelo comando ld.so). Assim sindo, você precisa embutir no execuável as informações necessárias para que o ld.so encontre as bibliotecas na hora da execução.

gcc prog.c -L/home/fulano/lib -Wl,-rpath,/home/fulano/lib -lABCD -o prog-dynamic 


Se você pretende distribuir um executável que dependa de uma biblioteca dinâmica, tem de distribuir a biblioteca também. Para tanto, existem duas opções principais. A primeira é você criar um pacote (.rpm, .deb ou similar) que instale a biblioteca num dos diretórios padronizados e regenere o cache, e num outro pacote distribuir sua aplicação.

A outra opção é colocar a biblioteca junto com o executável, e fazer com que o executável procure a biblioteca no mesmo diretório em que ele estiver instalado, ou algum diretório relativo ao local onde ele estiver instalado. Isso se consegue por meio da macro “$ORIGIN” passada como argumento da opção -rpath do linker.

gcc prog.c -L/home/fulano/lib -Wl,-rpath,'$ORIGIN'/../lib -lABCD -o prog-dynamic
# Se prog-dynamic for instalado em /home/fulano/bin, vai procurar a biblioteca
# em /home/fulano/lib. Se for instalado em /opt/teste, vai procurar em /opt/lib.



O programinha que fiz foi este fiz o mesmo para compilar em linux e windows

https://pastebin.com/T0iXfxX1

wiki.anon


5. Re: Criando e instalando bibliotecas dinamicas e estaticas no linux[RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 16/10/2017 - 10:03h

Com relação ao código que você postou, alguns comentários:

1) Creio que você generalizou demais no código que seleciona __fpurge(), ao incluir os testes das definições de unix e _unix, e mesmo em alguns testes que procuram pelo Linux. A função __fpurge() foi introduzida no Solaris e depois trazida para versões relativamente recentes da GlibC. Ela não existe em outros Unices (por exemplo, nos BSDs ou no AIX), e pode não existir mesmo em versões alternativas de libc para o Linux (tais como musl, uClibc, ditelibc ou outras).

2) Versões recentes da GlibC aceitam o famigerado fflush(stdin), com o mesmo sentido que isso tem, historicamente, em implementações no MS-DOS e MS-Windows.

3) É possível que haja implementações alternativas de libc também no Windows ou MS-DOS, que não aceitem fflush(stdin), então o teste talvez tenha de ser modificado.

4) Para sistemas diferentes dos que você previu, a função é um no-op. É isso mesmo que você quer, ou seria mais adequado fazer uma rotininha que procurasse o próximo fim de linha, a exemplo de std::istream::ingore() do C++?

5) Você não precisa e nem deve incluir outros cabeçalhos desnecessários dento do seu cabeçalho. Seu arquivo cbuff.h poderia ser exatamente o seguinte.
#ifndef _cbuff_h_
#define _cbuf_h_
#ifdef _cplusplus
extern "C" void cbuff();
#else
void cbuff(void);
#endif /*_cplusplus*/
#endif /*_cbuff_h_*/


6) Como consequência de (5), os cabeçalhos necessários à implementação devem ser movidos para o arquivo com a implementação. Isso permite deixar toda aquela lenga-lenga de tentar identificar o SO num lugar só do código, em vez de espalhada e em dois arquivos.
#include "cbuff.h"
#include <stdio.h> // Sempre vai usar este aqui.

#if /* ... testes para saber se usa __fpurge() ... */
#include <stdio_ext>

void cbuff(void){ __fpurge(stdin); }
#elif /* ... testes para saber se usa fflush(stdin) ... */
void cbuff(void){ fflush(stdin); }
#else /* fallback */
void cbuff(void){
int ch;
while((ch=getchar())!=EOF && ch!='\n')
;
}
#endif


7) Não seria interessante poder passar o ponteiro para um stream qualquer, em vez de amarrar o uso de stdin? Teoricamente, ao menos no mundo Unix, o terminal poderia estar associado a outro stream (por exemplo, abrindo o arquivo virtual /dev/tty).

8) A função cbuff() acaba sendo muito reduzida. Ela possivelmente ficaria muito bem como função inline ou mesmo como macro. E, nesses dois casos, isso eliminaria a possibilidade de implementar como uma biblioteca separada.


---

Do ponto de vista filosófico, não deveria haver uma função que “limpasse o buffer”, uma vez que nenhum buffer é como uma prateleira, que fica pegando poeira ou outras fontes de sujeira. No caso da computação, qualquer coisa que vá parar num buffer estará lá porque foi colocada lá.

Eu até entendo que nem sempre o que está no buffer é de interesse do programa, e isso pode ser ainda mais verdadeiro se o buffer em questão for referente ao console ou outra coisa vinculada a interação direta com o usuário. No entanto, é virtualmente impossível saber construir uma função universal que saiba sempre “limpar” dados e que sirva para todos os casos.


6. Re: Criando e instalando bibliotecas dinamicas e estaticas no linux[RESOLVIDO]

Jean César
dark777

(usa Slackware)

Enviado em 17/10/2017 - 16:46h


wiki.anon

entend mas qual as flags de SO que existem no Unix BSD e no Aix?