ti compilo, non ti compilo, ti compilo di nuovo...

Ovvero come pre-compilare le librerie di arduino

abbiamo discusso tempo fa che che lo IDE pre-compila le librerie incluse con una direttiva @include qualcosa.h

ovvero “prima” di compilare il programma principale chiama gcc per compilare separatamente i varii cpp corrispondenti ai file puntoh inclusi

POI compila il propgramma principale (e qui fa l’inclusione delle varie schede, l’aggiunta della main() e altro cinema)

e POI linka il tutto

in questa maniera abbiamo il lato “peggiore” di ognuna delle due “teorie” sull’inclusione di sorgenti in ‘C’

da un lato “paghiamo” tutte le volte il tempo di compilazione
dall’altro essendo le librerie compilate “prima” del corpo principale del programma non è possibile usare delle #define per cambiare le impostazioni delle stesse, pur se tali impostazioni dipendono da delle #define

durante quella discussione ho mostrato una maniera per “evitare” almeno questa secondo “effetto” collaterale
basta includere il file .CPP invece del .H
abbiamo già fatto le prove e abbiamo visto che lo IDE non cerca nelle varie cartelle il .cpp
serve di includerlo specificando un percorso, eventualmente usando dei link del sistema operativo per ridurre la lunghezza dei nomi di cartella

OK, Tux ha ragione

lunghezza dei nomi di directory

in questa maniera è diventato possibile “modificare” le impostazioni di base di una libreria usando delle #define, pur senza alterare il “testo” della libreria, ovvero senza manometterla apposta per noi, garantendo quindi la compatibilità con prossimi eventuali rilasci

ma questo è il passato

ora ho voluto esplorare la direzione opposta
compilare una volta sola e lasciare che il linker si arrangi a cercare il file .o pre-compilato, ma pre-compilato veramente

ora, credo di esserci riuscito

ho preso una funzione “stupida”
ne ho fatto una libreria, divisa in un .h e un .cpp

ho compilato e, senza chiudere lo IDE, sono andato nella cartella temporanea che lo IDE indica
e mi sono copiato il file che ha una estensione strana: .cpp.o

me lo sono messo accanto alle mia libreria e messo a posto l’estensione

cancellato il file .ccp e magia funziona

ho quindi provato a “esportare” in una installazione della 1.8.10 (io adesso uso 1.8.13, ma ho due installazioni separate di 1.8.10, in disuso)

non va (e magari ci sta, dato che magari sono due differenti toolchain)

rifatta la compilazione sulla una 1.8.10, ricancellato il file cpp e va

esportato i soli .h e .o sull’altra 1.8.10 e va

sembrerebbe quindi che sia possibile distribuire librerie personalizzate sotto forma di codice oggetto

io per stasera sono a posto, ma magari a qualcuno viene voglia di provare anche lui

lascio qui il programma

// di Nelson-StandardOil
// IDE 1.8.10
// importato da 1.8.13
// Progetto:
// Scopo: provare delle libreria precompilate distribuite come .h e .o
// Data inizio lavori:


#include <invertistringa.h>
char prova[]="stringadainvertire";



void setup(void)
{
  Serial.begin(9600);
  Serial.println("Inizio del programma");
  Serial.println(prova);
  invertistringa(prova);
  Serial.println(prova);

}

void loop(void)
{

}

il file “invertistringa.h”

// librerie di funzioni mie che possono sempre servire
// macro varie

#ifndef invertistringaLIB
#define invertistringaLIB 1.0

extern char * invertistringa(char * stringa);

#endif

la parola chiave “extern” sembra che non sia strettamente necessaria

il file “invertistringa.cpp”

// prova per una libreria che si include precompilata, come .h e .o

#include "invertistringa.h"
#include <Arduino.h>
char * invertistringa(char * stringa)
{
    //inverte una stringa
    byte i = 0;
    byte j = strlen(stringa) - 1;
    char c = 0;

    while (i < j)
    {
        c = stringa[i];
        stringa[i] = stringa[j];
        stringa[j] = c;
        i++;
        j--;
    }

    return stringa;
}

come vedete non è granché, si tratta solo di una prova di fattibilità

e il file .o compilato per una UNO, sotto 1.8.10

se ci fate delle prove fatemi sepere l’esito

invertistringa.o.zip (3.03 KB)

Il problema è proprio nella tua penultima riga ... il .o che così ottieni è mono MCU e quindi ... piuttosto inutile se uno utilizza più schede con MCU differenti (UNO, Leonardo, MEGA, MKR, Teensy, ESP, ...).

Normalmente, nei "veri" ambienti di sviluppo, quando si compila una libreria gli si dice per quali MCU target va compilata e viene creato una specie file oggetto che, in realtà, include le compilazioni per tutte le MCU selezionate ... il linker poi va a prendere quella corretta.

La potenza delle librerie "sorgenti" di Arduino (... ma anche, se vogliamo, il punto debole per i vari problemi che la cosa comporta) è proprio la grande trasportabilità, la facilità di modifica e l'open-source che , con le librerie oggetto ... va a farsi benedire.

Guglielmo

P.S.: Io ci tengo un corso su come usare Arduino in ambiente MPLAB X di Microchip, con tutti i vantaggi che questo comporta, inclusa la possibilità di avere delle vere librerie compilate multi MCU :wink:

Si..
Beh...

Lo sapevo, infatti lo ho indicato apposta

Però la cosa era nata per fare delle prove
Io ne ho fatto un sunto

Magari a qualcuno può essere utile...

Standardoil:
Magari a qualcuno può essere utile...

Certo, sono prove sempre utili che, comunque, fanno capire come il tutto è collegato :wink:

Guglielmo

Buongiorno, Nelson
Da ciò con cui hai esordito mi sembra di capire che questo non dovrebbe funzionare:

// Abilitazioni necessarie in NMEAGPS_cfg.h:
#define NMEAGPS_PARSE_GGA
#define NMEAGPS_PARSE_GSV
#define NMEAGPS_PARSE_RMC
#define NMEAGPS_PARSE_SATELLITES
#define NMEAGPS_PARSE_SATELLITE_INFO

#include <NMEAGPS.h> // Uso la libreria Neo-GPS.
#include <EEPROM.h>
#include <LiquidCrystal.h>
//                R E D4 D5 D6 D7
LiquidCrystal lcd(8,9,10,11,12,13);

char *percorso=__FILE__; // Dalla macro __FILE__ prende il percorso del file in uso. Questa parte di programma,
                         // però, si trova nel file/cartella dell'IDE c_setup, in cui non è scritta la versione
                         // del programma. La versione è scritta nel file principale, che ha lo stesso nome della
                         // cartella che contiene tutti i file del programma. Questa riga, quindi, non può stare
                         // nel setup.
char ver[10];

NMEAGPS GPS; // Imposto la seriale per NMEAGPS.
gps_fix fix;
(...)

Colui che ha scritto la libreria, infatti, dice che bisogna andarci dentro e abilitare ciò che serve. Io, senza sapere di questi problemi, ho messo dei #define nel programma, prima di citare la libreria, e funziona!..

Poi, a proposito dei tempi di compilazione: mi sembra che, dopo aver compilato una prima volta un programma, se si va a modificarlo e a compilarlo di nuovo il tempo necessario sia decisamente minore, proprio come se avesse conservato le librerie già compilate. Qui torniamo alla mia idea espressa tempo fa: non si potrebbe dare la possibilità di esportare un “progetto” di un programma, completo dei sorgenti e delle librerie già compilate, con l’IDE già impostato sul microcontrollore usato e magari anche con un file di testo in cui vengono riepilogate tutte le informazioni come, appunto, il microcontrollore per cui è stata effettuata la compilazione? Mi è capitato, infatti, di non aver scritto commenti riguardo il microcontrollore usato e poi non ricordarmi per quale erano impostati i pin di I/O.

Se per quella libreria funzione è perché tutto il codice è nel puntoh e il puntocpp è assente o vuoto o presenta solo parti di codice non personalizzabile

Il fatto che la seconda compilazione sia più veloce è proprio perché lo IDE mantiene i file oggetto fino all'uscita

Se esci e rientri vedrai che la prima compilazione è di nuovo lenta

Per la tua idea:
Sto lavorando proprio 8n quella direzione

Socio, io che sono un po' crudo di C, sto trovando queste tue sperimentazioni con relative note molto utili.
Purtroppo al momento non ho tempo di approfondire e consolidare i concetti, ma ormai è agli atti e quindi ci potrò sempre tornare in seguito.

Maurizio

P.S.
Visto che a Natale siamo tutti più buoni... K+ :stuck_out_tongue: ;D

P.S.2 (che non è la console)
E a me i tuoi titoli con effetti speciali piacciono pure :smiley:
Lo, so, non si stupirà nessuno di questo ;D

Grazie