No Nid ... non compila correttamente, ma credo che tu non te ne accorgi perché probabilmente hai il "verbose" non attivo ... mettilo attivo in compilazione e vedrai ...
La strada che indichi si chiama "Computed Includes" ... ed è la seconda strada che ho provato anche io subito dopo aver visto il problema con la include normale, ma ... purtroppo non va neanche quella ...
Non da errore, ma da warning perché ... non trova il file da includere ...
Il problema del "#ifdef" in realtà, secondo me, deriva da questo ...
"Even if a conditional fails, the controlled text inside it is still run through initial transformations and tokenization. Therefore, it must all be lexically valid C."
... che, secondo me, va letto come : "Anche se la condizione è falsa, il testo in essa contenuto (cioè quello che uno mette dentro al #ifdef) viene comunque trattato, per cui deve essere sintatticamente valido per il C."
Chiaramente, la libreria TiniWireM.h contiene cose che in C sono sintatticamente valide se il processore è il ATtiny85, ma non più valide se il processore è un altro e ... li casca l'asino.
Guglielmo
Edit : la cosa è indipendente dalla versione del IDE che si usa e ... anche dalla Toolchain (provato anche con la 3.4.3)
gpb01:
"Even if a conditional fails, the controlled text inside it is still run through initial transformations and tokenization. Therefore, it must all be lexically valid C."
Mi sembra una cosa stupida. Se non la voglio includere c'e' un motivo. Perchè analizzarla comunque?
Un conto è una define per una macro o una costante per debug, ma comunque non mi interessa ne faccia l'analisi.
Alquanto strana come "decisione" del gcc.
nid69ita:
Mi sembra una cosa stupida. Se non la voglio includere c'e' un motivo. Perchè analizzarla comunque?
...
Nid, concordo con te, e purtroppo questa cosa crea dei bei casini che, credo vadano ad aggiungersi a quelli che già crea di perse l'IDE.
Ad esempio ... il fatto che nei "Computed Includes" non trova i files (... perché non sa seguire più le path) ... ho idea che sia qualche cosa introdotto dall' IDE e non da gcc
il problema è probabilmente quello che fa l'ide qunado tagliuzza le cose per crare il file main in cpp a partire dall'INO.
Attivate le scritte di debug e controllate in che cartella temporanea compila, entrate nella cartella e cercate il main() (nomesckecth.cpp se ricordo bene) e verificate cosa è successo alle ifdef.
Se sono scomparse, e trovate entrambe le include, alloa aprite un bug (se state usando l'ultima versione di ide, si intende! se no aggiornate)
credo che intenda sintatticamente, non che viene elaborato. la #ifdef usata così è normale, ed è usata anche nelle librerie arduino. potrebbe essere che il fatto che Arduino.h sia incluso DOPO sia il problema?
Ho riletto, ma non ho capito qual'è l'intento. Per un compilatore C il preprocessore si limita a includere o meno del codice limitatamente al codice testato con #if, ciò non influisce sulle altre compile unit che se non hanno #if vengono compilate e questo è corretto.
Normalmente quando si ha un sorgente compatibile con più di una libreria si deve creare un configure parametrizzato che permetta di configurare il build per compilare la libreria da cui dipende e per fare la fase di collegamento. Questo è possibile farlo con IDE che offrono strumenti di configurazione esterni che possono essere configurati dal file di progetto.
Nel mio caso con qtcreator ho queste righe nel file di progetto:
Includo il path di ricerca header lib/tc, abilito la dipendenza nei confronti di /lib/tc, includo il path di ricerca header locale, LIBS +=..... mi permette di specificare delle librerie da linkare al codice compilato.
Potrei mettere LIBS +=... in una condizione simile a if elseif che in base al valore di una variabile sceglie cosa linkare, in realtà posso usare strutture condizionali ovunque rendendo il codice configurabile attraverso una o più
variabili o anche una sola, es contains(WhatBuilt, ALL) { } else { contains(WhatBuild, DEMO} ecc.
Mentre credo che l'ide di Arduino abiliti o meno la compilazione di librerie aggiuntive grazie al preprocessore
interno che però non è in grado di fare il lavoro che svolge il preprocessore C++, quindi include la libreria per compilarla e linkarla ma il preprocessore C non include l'header.
Comunque, se il problema c'è di sicuro non riguarda GCC in quanto il comportamento è standard.
MauroTec:
...
Comunque, se il problema c'è di sicuro non riguarda GCC in quanto il comportamento è standard.
Non sembrerebbe Mauro, anche dalla documentazione gnu che ho postato ...
"Even if a conditional fails, the controlled text inside it is still run through initial transformations and tokenization. Therefore, it must all be lexically valid C."
... e difatti è proprio quello che fa ... solo che facendolo, la cosa crea problemi !
Questo è il codice che mi interessa, visto che sto scrivendo del codice che vorrei poter compilare sia per ATtiny85 che per ATmega328p e che usa il protocollo I2C :
#if defined( __AVR_ATtiny85__ )
#include <TinyWireM.h>
#else
#include <Wire.h>
#endif
void setup() {
// non ha importanza
}
void loop() {
// non ha importanza
}
... ora provate voi a compilarlo senza errori né warning
Guglielmo
@Lesto : E non puoi mica girartela come ti pare ... certo che ti funziona, in quel modo non sei grado di produrre l'errore. Usa la libreria e l'include che ho messo io (che su 328p crea errore) e allora vedrai ...
L'IDE prende il codice sopra scritto, c'aggiunge qualche riga e lo trasforma così (sketch_jan28a.cpp) :
#line 1 "sketch_jan28a.ino"
#if defined( __AVR_ATtiny85__ )
#include <TinyWireM.h>
#else
#include <Wire.h>
#endif
#include "Arduino.h"
void setup();
void loop();
#line 7
void setup() {
// non ha importanza
}
void loop() {
// non ha importanza
}
A questo punto lancia avr-g++ ... e salta fuori il problema perché, nonostante la "#if defined" comunque ".... the controlled text inside it is still run through initial transformations and tokenization" :
Quando una caratteristica viene confusa per bug, di questo si tratta.
"Even if a conditional fails, the controlled text inside it is still run through initial transformations and tokenization. Therefore, it must all be lexically valid C"
Questo significa che anche se il test fallisce il parser e il tokenizer e quindi il controllo degli errori è attivo e questa è una caratteristica. Diversamente scopriresti di aver scritto includ "stoca> solo quando la ifdef da esito positivo.
Quindi se ci sono errori di scrittura o di altra natura sia che il test dia o meno validità il parser ecc fa il suo lavoro e questo è utile o no.
Il problema che si presenta e proprio quello che ho descritto, cioè il codice sorgente della libreria viene comunque incluso in quanto il preprocessore di Arduino non è in grado di valutare l'espressione #ifdef ....
Ricorda che il preprocessore di arduino viene eseguito sul codice prima che il preprocessore C++ possa operare.
Uso spesso Gcc è ti posso garantire che non si tratta di un bug.
dal tuo output noto che G++ viene chiamato passando la path della libreria TinyWireM che viene compilata nonostarnte il target sia atmega328p
Però se ci fai caso, al primo avvio arduino compila anche TUTTE le librerie interne, sarà poi il linker a decidere quale unire e quale scartare dall'eseguibile finale, questo perchè le librerie vengono ricompilate solo se la data del file oggetto è < del file sorgente (c'è stat una modifica), risparmiando un sacco di tempo in compilazione.
probabilmente esiste qualche opzione per dirgli di evitare questo comportamnto
MauroTec:
Il problema che si presenta e proprio quello che ho descritto, cioè il codice sorgente della libreria viene comunque incluso in quanto il preprocessore di Arduino non è in grado di valutare l'espressione #ifdef ....
Ricorda che il preprocessore di arduino viene eseguito sul codice prima che il preprocessore C++ possa operare.
Uso spesso Gcc è ti posso garantire che non si tratta di un bug.
Mauro, perdona, non capisco cosa c'entra Arduino ???
L'IDE di arduino, in questo caso, non fa altro che aggiungere una #include (Arduino.h) ed i prototipi delle funzioni, STOP.
Il resto lo fa tutto avr-g++ ...
... se a avr-g++ io passo un sorgente che contiene delle "#if defined" ... lui non chiama il suo preprocessore ? Il preprocessore di avr-g++ dovrebbe ignorare quanto è dentro e ... invece lo include e cerca di compilarlo !!!
lesto:
non è vero, lui lo fa per portarsi avanti, attento che COMPILA MA NON INCLUDE
Lesto .. a me che includa o no, al momento ... non interessa.
Il problema è che NON deve compilare perché nell'architettura 328p mancano delle cose che sono nell'architettura tiny85 e quindi ... anche solo compilando ... VA IN ERRORE !!! ] ] ]