SamL
(usa XUbuntu)
Enviado em 27/06/2022 - 23:08h
nixtavo escreveu:
Bem, eu entendi algumas coisas do seu tópico 1, mas fiquei com dúvida em uma coisa. Quando nos queremos usar um header do /usr/include/ no nosso programa, como por exemplo o stdio.h, nós não necessáriamente precisamos escrever o caminho completo #include "/usr/include/stdio.h", mas apenas #include <stdio.h>, será que qualquer header que eu colocar em /usr/include vai funcionar colocando #include <exemplo.h> eu fiz o teste e funcionou.E gostaria de saber se é uma boa prática ou não usar o include com o caminho completo "/usr/include/stdio.h" ou apenas <stdio.h>. Também gostaria de saber como funciona , por exemplo, eu desenvolvo um programa que contem headers não padrões e eu quero que ou outro usuário consiga rodar meu programa sem precisar colocar o header na mesma pasta que eu coloquei, tem uma maneira intuitiva de fazer isso?
Vamos fazer um passo a passo, basta tu seguir executando os comandos que tu vai entender melhor.
1-abra um terminal
2-execute isso:
ls /usr/include
Vai mostrar todos os arquivos que estão na pasta 'include' do caminho /usr/include
3-pronto, notado isso, o que eu quis dizer com o parâmetro -I (i maiúsculo) do primeiro post?
Ora, o parâmetro -I nada mais é que um meio de tu indicar ao gcc mais uma pasta para rpcourar por headers na hora de compilar o programa.
Por exemplo, vamos supor que vc não tenha a term.h no /usr/include mas ela está na pasta /etc/
Como o gcc não é um compilador advinhão, se você tentar compilar o programa e a term.h estiver em /etc, ele não vai saber e vai dar error de que não achou o header.
Sendo assim, você deve usar o -I para indicar o caminho da pasta onde está o term.h para então incluir ele na compilação:
Exemplo:
//arquivo 'main.c' seu programa poderia ser assim
#include "term.h"
int main(void) {
return 0;
}
Se você compilar com:
gcc -o main main.c
O gcc vai acusar que não achou o header term.h
Agora, se você usa o -I e coloca o term.h dentro do usr/include vai ficar:
gcc -o main main.c -I/usr/include
E a compilação terá sucesso.
"Mas, e se eu quiser colocar o path completo? É uma boa prática de programação?"
Não é não, isso de certa forma é considerado como não portável.
Por exemplo, vc mesmo disse que não quer que seu usuário tenha que instalar o header, e isso já é um ponto a considerar.
Se você vai abrir o código de um programa em C e deseja atingir mais plataformas, então, deve deixar o código o mais portável.
Outro exemplo:
se vc usa isso como include:
#include "/usr/include/term.h"
Vc está fixando o caminho completo e inciado pro compilador (que não precisa ser só o gcc), que é rpa incluir o term.h que está dentro do diretório /usr/include.
Isso pra Linux e outros sistemas unixlike deve funcionar de boa.
Agora, imagine que você queira que sua aplicação seja compilada pra windows. Daí o usuário pega seu source e tenta compilar e então dá um erro na compilação como:
fatal error: /usr/include no such file or directory
Esse erro vai aparecer em todo sistema que não exista o caminho completo /usr/include com o arquivo term.h
Se vc deseja ter uma aplicação mais portável, que compile em diversos sistemas, basta incluir a term.h assim:
#include "term.h"
E então, no comando de compilação, você muda para cada sistema através do -I.
Onde o -I vai indicar onde está gravado o term.h necessário para compilar.
Ele pode estar em C:\headers onde o usuário salvou o header, então, vc diz a ele para compilar com:
gcc.exe -o main.exe main.c -l'C:\headers'
#NOTA não sei como é o path no windows rsrsrs
Ou se for num linux, e o usuário salvou em /home/Downloads:
gcc -o main main.c -I/home/Downloads
E então, num programa real, o que mudaria seria apenas o compilador e seus parâmetros, mas nada no código fonte que já não seja previsto no projeto original.
Por que não
#include <term.h>?
Porque assim, você está indicando que é pra buscar
primeiro no diretório padrão de headers, no caso no linux é comum ser o /usr/include.
Como o stdio.h está dentro do /usr/include e é um diretório padrão de compilação, é possível declarar algo como #include "stdio.h", mas isso não é lá uma boa prática. Se é uma lib padrão, é melhor declarar entre o '<' e '>' ao invés de entre aspas duplas.
Também gostaria de saber como funciona , por exemplo, eu desenvolvo um programa que contem headers não padrões e eu quero que ou outro usuário consiga rodar meu programa sem precisar colocar o header na mesma pasta que eu coloquei, tem uma maneira intuitiva de fazer isso?
Na verdade, pra rodar um programa compilado, você não precisa do header, mas sijm da bilioteca, se o programa for compilado dinamicamente.
O header só é usado no momento da compilação. Sendo assi, você pode:
1-adicionar os headers e as libs dinâmica ou estática de outro projeto e compilar tudo junto.
No caso de lib dinâmica (como os arquivos .so ou .dll), você precisa colocar os binários delas no path, ou definir o path pra carregar tais bibliotecas.
Já se for uma lib estática que estiver usando, elas são "ligadas" no moemnto da compilação, tipo, arquivo de código objeto (.o) ou mesmo .a.
Na pasta /usr/lib tem esses tipos de arquivos de bibliotecas. Quando, no ubunutu por exemplo, instalar uma lib para desenvolvimento, o apt baixa os arquivos arquivos .a (se for o caso) e os headers (.h) da lib.
Os headers vão por padrão para /usr/include e o restante para /usr/lib.
Como o /usr/include é padrão de compilação em sistemas como o linux, então, você não precisa definir esse path na inclusão dos headers.
Seria bom esperar o Paulo dizer algo a respeito, pelo menos pra uma segunda opinião.