Domanda

Sono un Newb di C

Scrivo molto codice in linguaggi dinamici (javascript, python, haskell, ecc.), ma ora sto imparando il C per la scuola di specializzazione e non ho idea di cosa sto facendo.

Il problema

Inizialmente stavo costruendo tutti i miei sorgenti in una directory usando un makefile, che ha funzionato piuttosto bene.Tuttavia, il mio progetto sta crescendo e vorrei dividere il sorgente in più directory (test unitari, utils, core, ecc.).Ad esempio, il mio albero di directory potrebbe essere simile al seguente:

.
|-- src
|   |-- foo.c
|   |-- foo.h
|   `-- main.c
`-- test
    `-- test_foo.c

test/test_foo.c li usa entrambi src/foo.c E src/foo.h.Utilizzando i makefile, qual è il modo migliore/standard per crearlo?Preferibilmente, ci sarebbe una regola per costruire il progetto e una per costruire i test.

Nota

So che ci sono altri modi per farlo, incluso autoconf e altre soluzioni automatiche.Vorrei però capire cosa sta succedendo e riuscire a scrivere i makefile da zero nonostante la sua possibile impraticabilità.

Qualsiasi guida o suggerimento sarebbe apprezzato.Grazie!

[Modificare]

Quindi le tre soluzioni finora fornite sono le seguenti:

  • Posiziona i file di intestazione utilizzati a livello globale in parallelo include directory
  • utilizzare il percorso in #include dichiarazione come in #include "../src/foo.h"
  • Usa il -I switch per informare il compilatore delle posizioni di inclusione

Finora mi piace il -I cambia soluzione perché non comporta la modifica del codice sorgente quando cambia la struttura della directory.

È stato utile?

Soluzione

Per test_foo.c devi semplicemente dire al compilatore dove possono essere trovati i file header.Per esempio.

gcc -I../src -c test_foo.c

Quindi il compilatore esaminerà anche questa directory per trovare i file di intestazione.In test_foo.c scrivi quindi:

#include "foo.h"

MODIFICARE:Per collegarsi a foo.c, anzi a foo.o, è necessario menzionarlo nell'elenco dei file oggetto.Presumo che tu abbia già i file oggetto, quindi fai dopo:

gcc test_foo.o ../src/foo.o -o test

Altri suggerimenti

Inoltre utilizzo raramente gli autotools GNU.Invece, inserirò un singolo makefile creato manualmente nella directory root.

Per ottenere tutte le intestazioni nella directory di origine, usa qualcosa di simile:

get_headers = $(wildcard $(1)/*.h)
headers := $(call get_headers,src)

Quindi, puoi utilizzare quanto segue per far sì che i file oggetto nella directory test dipendano da queste intestazioni:

test/%.o : test/%.c $(headers)
    gcc -std=c99 -pedantic -Wall -Wextra -Werror $(flags) -Isrc -g -c -o $@ $<

Come puoi vedere, non sono un fan delle direttive integrate.Da notare anche il -I interruttore.

Ottenere un elenco di file oggetto per una directory è leggermente più complicato:

get_objects = $(patsubst %.c,%.o,$(wildcard $(1)/*.c))
test_objects = $(call get_objects,test)

La seguente regola creerebbe gli oggetti per i tuoi test:

test : $(test_objects)

IL test rule non dovrebbe creare solo i file oggetto, ma gli eseguibili.Il modo in cui scrivere la regola dipende dalla struttura dei test:Ad esempio, potresti creare un eseguibile per ciascuno .c file o solo uno singolo che verifica tutti.

Un modo comune per farlo è che i file header usati da un singolo file C abbiano lo stesso nome di quel file C e nella stessa directory, e che i file header usati da molti file C (specialmente quelli usati dall'intero progetto) essere in una directory include che è parallelo alla directory dei sorgenti C.

Il tuo file di test dovrebbe includere semplicemente i file di intestazione utilizzando direttamente i percorsi relativi, come questo:

#include "../src/foo.h"
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top