Działanie linkera, kompilacja gcc i pliki .h

0

Cześć,
Mam pewne problemy ze zrozumieniem procesu kompilacji przez gcc . Przypuśćmy, że istnieją następujące pliki (wszystkie w jednym katalogu):

func.h

#ifndef __FUNC_
#define __FUNC_

int add(int a,int b);
int sub(int a, int b);

#endif

func.c

#include "func.h"

int add(int a,int b)
{
    return a+b;
}
int sub(int a, int b)
{
    return a-b;
}

main.c

#include <stdlib.h>
#include <stdio.h>

#include "func.h"

int main()
{
    printf("5+6 = %d\n", add(5,6));

    return 0;
}

Jeżeli to skompiluje, to gcc rzuci błędem, że nie może znaleźć 'add'. Jest to logiczne, ponieważ preprocesor wklei mi wszytko z func.h i nie ma tam definicji funkcji.
Czytałem trochę ten wątek na stacku: https://stackoverflow.com/que[...]ct2-ld-returned-1-exit-status

I z tego co zrozumiałem, to za ten proces odpowiedzialny jest linker.
Przeprowadzając kompilację w taki sposób:

gcc -c func.c # generates the object file func.o
gcc -c main.c # generates the object file main.o
gcc func.o main.o -o main # generates the executable main

Tworzy się plik: func.o - zawiera wyeksportowany adres gdzie jest 'add' i 'sub'
Tworzy się plik: main.o - zawiera miejsce, gdzie powinien znaleźć się adres 'add' i 'sub'

No i linker wkleja wszędzie to co trzeba (dobrze to rozumiem ?)
I teraz moje pytania:

  1. Jak to możliwe, że nie muszę tworzyć plików obiektowych dla wszystkich plików *.c które zawierają pliki nagłówkowe w takich nawiasach '<....h>' (np. <stdlib.h> ) tylko dzieje się to auto-magicznie ?
  2. Czy powinno się includować pliki .c w innych plikach .c ? Jeżeli podmienię w main 'func.h' na 'func.c' to wszystko będzie ok. Ale czy tak się "robi" ?
  3. Przypuśćmy, że miałbym wiele własnych plików .h includowanych (i odpowiednio dla nich plików .c ) w swoim programie. Czy ja za każdym razem będę musiał tworzyć każdy plik (.o dla każdego pliku *.c i potem to wszystko linkować do maina ? Jak się "normalnie" przeprowadza proces kompilacji dla aplikacji w języku C ?

Z góry dzięki
Pozdr.

1

Rozumiesz dobrze.

  1. Tak. Jeśli chodzi o bibliotekę standardową, gcc ma flagę -nostdlib, której użycie spowoduje niedołączanie biblioteki standardowej do Twojego programu. Ale domyślnie jest, i dobrze.
  2. Nie. W C++ w pewnych skrajnych przypadkach można to uważać za wytłumaczalne, ale w C, o ile mi wiadomo, nigdy.
  3. Jeśli te nagłówki będą deklarować funkcje, których użyjesz - tak. Ale od tego masz makefile i ich generatory, jak np. CMake czy nawet automake. Więc "normalnie" masz plik definiujący projekt, z którego generowane są makefiles.
0
  1. nawiasy <> sugerują że nagłówek jest „systemowy”, a cudzysłów "" że jest częścią projektu. nie wszystko jednak co ma <> będzie wlinkowywane domyślnie.
  2. nie robi się tak, ale wiedz że jest to tylko taka konwencja. kompilatorowi jest wszystko jedno: pliki .h i .c traktuje tak samo.
0

Dzięki Panowie za pomoc .

1
NeuroXiq napisał(a):
  1. Jak to możliwe, że nie muszę tworzyć plików obiektowych dla wszystkich plików *.c które zawierają pliki nagłówkowe w takich nawiasach '<....h>' (np. <stdlib.h> ) tylko dzieje się to auto-magicznie ?

Dodam do tego co zostało już powiedziane, że za proces kompilacji odpowiada sterownik (compiler driver). On decyduje jakie biblioteki zostaną zlinkowane, tj. przekazuje odpowiednie parametry do linkera. Domyślnie będzie Ci linkował biblioteki standardowe dla twojej platformy (o ile je znajdzie).

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0