[help]Uso librerie in sottocartelle

Ciao a tutti
visto la complessità del mio progetto, volevo suddividere le varie librerie in sottocartelle all'interno del progetto.
per esempio nel progetto ~/sketchbook/Test
ho i file
Test.pde
Libreria1.cpp
Libreria1.h

se nel Test.pde faccio:

#include "Libreria1.h"

tutto ok

ma se sposto Libreria1.cpp e Libreria1.h in una sottocartella, per esempio "lib" (path: ~/sketchbook/Test/lib) e faccio:

#include "lib/Libreria1.h"

ho errore:

Test.cpp:4:43: fatal error: lib/Libreria1.h: No such file or directory
compilation terminated.

In pratica l'IDE arduino se ne frega altamente delle sotto cartelle e quindi dà errore. è una grossa limitazione per me, direi quasi un bug dell'IDE... qualcuno ha già risolto?

io ad esempio per la libreria crc16, che è in una sotto cartella uso:

#include <util/crc16.h>

e funziona!

Da un refuso di basi di C mi ricordo che le virgolette stanno ad indicare che sei posizionato nella directory corrente, però non ho mai approfondito troppo la questione e uso sempre solo <...> :sweat_smile:

Secondo me per funzionare funziona, c'è da capire com'è giusto specificarle :wink:

certo, ma se la util/crc16.h è nelle cartelle di libreria di arduino IDE o del compilatore tutto funziona tranquillamente.
Il problema sorge quando vuoi usare una libreria "locale", sia che la metti nella cartella dello sketch.
E visto che le mie librerie comprendono alcune di sistema modificate, vorrei evitare di avere più installazioni di arduino, una "pulita" e le altre "sporcate" con le varie librerie

Soluzione:
senza accorgermi ero arrivato a soluzione già ieri notte, ma l'ora tarda...
in pratica nella cartella sketchbook si crea la carella libraries e si possono mettere le librerie annidiate.

lesto:
Soluzione:
senza accorgermi ero arrivato a soluzione già ieri notte, ma l'ora tarda...
in pratica nella cartella sketchbook si crea la carella libraries e si possono mettere le librerie annidiate.

Nemo profeta in patria ]:smiley:
E' da tanto che lo scrivo su vari post :wink:

si anch'io le librerie le metto nella cartella libraries nella cartella sketchbook...avevo capito che tu stavi provando a metterle nella cartella dello sketch.

Altra cosa, se modifichi qualche percorso devi sempre chiudere e riaprire l'IDE per fargli fare l'aggiornamento delle directory. Presumo lo sapessi già che non fosse questo il caso.

ehh ma sarebbe mille volte più comodo, a parte l'autoaggiornamento delle directory, il fatto di mettere cartelle annidiate all'interno della cartella del progetto

ps. che centra nemo?? :grin:

E' latino :stuck_out_tongue:
"Nemo profeta in patria" vuol dire "Nessuno è profeta in patria".
Sta a significare che generalmente una persona non viene mai ascoltata da chi invece dovrebbe farlo, come ad esempio i concittadini di un profeta, usando un'immagine antica.

avevo già cercato su wikipedia, però la battuta mi piaceva :stuck_out_tongue:

Come non detto, funziona solo se la libreria NON contiene altre cartelle =(

Allora in ~/libraries ho la cartella "LibreriaA"
che contine:
Classe.cpp
Classe.h
cartella "sottoclassi" (che non sono sottoclassi ma va bè, è solo un test)
che contiene:
Sottoclasse.h
Sottoclasse.cpp

Sottoclasse contiene un semplice metodo pubblico update:
Sottoclasse.h

#ifndef Sottoclasse_h
#define Sottoclasse_h

class Sottoclasse{
  public:
    void update();
  private:
  
};
#endif

Sottoclasse.cpp

#inlude "Sottoclasse.h"

void Sottoclasse::update(){
}

Classe invece possiede una variabile privata di tipo sottoclasse, e un metodo pubblico update che chiama l'update di Sottoclasse:
Classe.h

#ifndef Classe_h
#define Classe_h
#import "sottoclassi/Sottoclasse.h"

class Classe{
  public:
    void update();
  private:
    Sottoclasse temp;
};
#endif

Classe.cpp

#import "Classe.h"

void Classe::update(){
  temp.update();
}

Ora, se in arduino includo e dichiaro la variabile Classe:

#include <Classe.h>

Classe tmp;
void setup(){
}

void loop(){
}

tutto ok e fin quì nulla di strano...

ma se provo a chiamare il metodo update()...

#include <Classe.h>

Classe tmp;
void setup(){
  tmp.update();
}

void loop(){
}

mi da errore:

LibreriaA/Classe.cpp.o: In function Classe::update()': ~/sketchbook/libraries/LibreriaA/Classe.cpp:4: undefined reference to Sottoclasse::update()'
collect2: ld returned 1 exit status

ho provato anche ad includere la sottoclasse al .pde

#include <sottoclassi/Sottoclasse.h>

stesso identico problema, se non uso la variabile classe tutto ok, se la uso stesso errore.

Ho provato anche ad inizializzare le classi, anche se prima non davano problemi, aggiungendo un costruttore a classe:

Classe::Classe(){
  temp = Sottoclasse();
}

e nel .pde:

#include <Classe.h>
#include <sottoclassi/Sottoclasse.h>
Classe tm;
void setup(){
  tmp = Classe();
  tmp.update();
}

void loop(){
}

uff che dire... manca solo l'output di compilazione:

avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/hardware/arduino/cores/arduino -I~/sketchbook/libraries/LibreriaA /tmp/build3895633309484179111.tmp/sketch_apr28a.cpp -o/tmp/build3895633309484179111.tmp/sketch_apr28a.cpp.o
avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino -I~/sketchbook/libraries/LibreriaA -I~/sketchbook/libraries/LibreriaA/utility ~/sketchbook/libraries/LibreriaA/Classe.cpp -o/tmp/build3895633309484179111.tmp/LibreriaA/Classe.cpp.o
avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/wiring_shift.c -o/tmp/build3895633309484179111.tmp/wiring_shift.c.o
avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/wiring_digital.c -o/tmp/build3895633309484179111.tmp/wiring_digital.c.o
avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/wiring.c -o/tmp/build3895633309484179111.tmp/wiring.c.o
avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/wiring_analog.c -o/tmp/build3895633309484179111.tmp/wiring_analog.c.o
avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/pins_arduino.c -o/tmp/build3895633309484179111.tmp/pins_arduino.c.o
avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/wiring_pulse.c -o/tmp/build3895633309484179111.tmp/wiring_pulse.c.o
avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/WInterrupts.c -o/tmp/build3895633309484179111.tmp/WInterrupts.c.o
avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/Tone.cpp -o/tmp/build3895633309484179111.tmp/Tone.cpp.o
avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/WMath.cpp -o/tmp/build3895633309484179111.tmp/WMath.cpp.o
avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/WString.cpp -o/tmp/build3895633309484179111.tmp/WString.cpp.o
avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/Print.cpp -o/tmp/build3895633309484179111.tmp/Print.cpp.o
avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/main.cpp -o/tmp/build3895633309484179111.tmp/main.cpp.o
avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I~/arduino-0022/hardware/arduino/cores/arduino ~/arduino-0022/hardware/arduino/cores/arduino/HardwareSerial.cpp -o/tmp/build3895633309484179111.tmp/HardwareSerial.cpp.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/wiring_shift.c.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/wiring_digital.c.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/wiring.c.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/wiring_analog.c.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/pins_arduino.c.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/wiring_pulse.c.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/WInterrupts.c.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/Tone.cpp.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/WMath.cpp.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/WString.cpp.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/Print.cpp.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/main.cpp.o
avr-ar rcs /tmp/build3895633309484179111.tmp/core.a /tmp/build3895633309484179111.tmp/HardwareSerial.cpp.o
avr-gcc -Os -Wl,--gc-sections -mmcu=atmega328p -o /tmp/build3895633309484179111.tmp/sketch_apr28a.cpp.elf /tmp/build3895633309484179111.tmp/sketch_apr28a.cpp.o /tmp/build3895633309484179111.tmp/LibreriaA/Classe.cpp.o /tmp/build3895633309484179111.tmp/core.a -L/tmp/build3895633309484179111.tmp -lm

Questa cosa delle librerie mi interessa per l'IDE che sto sviluppando, anche se però adesso sono concentrato su un'altra parte di programma, però non so forse nel wizard per la creazione di un nuovo progetto, dopo la scelta e configurazione dell'hardware, potrei mettere una pagina per selezionare le libreire con le quali si vuole lavorare oltre quelle di default si intende.

Il problema con le librerie è che quando si sviluppa con i microcontrollori, oltre a delle librerie compilate staticamente "libname.a" sarebbe comodo poter inserire nel nostro sorgente dei pezzi di codice ancora non compilato, che poi è quello che fa Arduino IDE.

Non ho ancora chiaro come risolvere il problema, ho solo implementato qualcosa che non mi soddisfa. Lo standard è compilare le librerie per ogni microcontrollore supportato, ma così è facile ritrovarsi con un centinaio di librerie se non di più, per poi usarne al massimo 2 o poco più.

Poi conviene creare una libreria da 1 solo file dove ci sono 4 o 5 funzioni o una sola classe?; dipende dal lavoro che fà il link di gcc.

Comunque il tuo problema sembra dipendere dal fatto che crei istanza fuori dal blocco di codice della funzione loop, e poi dentro vuoi usare l'oggetto. È un problema di scope, la variabile tmp di tipo classe non è visibile all'interno dello scope in cui vuoi usarla. Il problema si risolve creando un puntatore "Classe *tmp;" poi "tmp = new Classe;".

Oppure se la visibilità deve essere ridotta solo al file "static Classe *tmp;", poi crei istanza, ed il puntatore sarà visibile dentro la funzione loop e setup.

Ciao.

no, problemi di visibilità non ci dovrebbero essere dato che faccio tutto nel setup().. spposta per avere un codice il più bug-free possibile.
e po l'operatore new in arduino non esiste.. quindi niente puntatori a classe, forse quando chiami una sottofunzione, non so se lo stack si copia tutta la classe o passa in automatico il puntatore come java, credo però più la prima vista il basso livello del C++

dando un'occhiata al sorgente dell'IDE, si scopre che già tutto è settato per funzionare ricorsivamente, ma viene passato come parametro il fatto di non farlo, sia per la cartella sketch, sia per quella libraries...

allora le modifiche da fare sono (bisogna ricompilare l'IDE):
file ~/arduino-0022/app/src/processing/app/debug/Compiler.java

cambiare TUTTI i

findFilesInFolder(libraryFolder, "S", false),
               findFilesInFolder(libraryFolder, "c", false),
               findFilesInFolder(libraryFolder, "cpp", false),

in:

findFilesInFolder(libraryFolder, "S", true),
               findFilesInFolder(libraryFolder, "c", true),
               findFilesInFolder(libraryFolder, "cpp", true),

eliminare la parte riguardante la cartella utility, caso speciale della libreria Wires(che non sarà più caso speciale etc ma vabbè):

/*
     includePaths.add(utilityFolder.getAbsolutePath());
     [...]
     outputFolder = new File(outputFolder, "utility");
     createFolder(outputFolder);
     objectFiles.addAll(
       compileFiles(avrBasePath, outputFolder.getAbsolutePath(), includePaths,
               findFilesInFolder(utilityFolder, "S", true),
               findFilesInFolder(utilityFolder, "c", true),
               findFilesInFolder(utilityFolder, "cpp", true),
               boardPreferences));
     // other libraries should not see this library's utility/ folder
     //includePaths.remove(includePaths.size() - 1);
*/

ora c'è un piccolo problema: il codice soprastante che abbiamo eliminato faceva crede alla classe Wire che la classe twi fosse nella sua stessa cartella giocando con i path di output, cosa che ora non avviene più... quindi bisogna aprire il file Wire.cpp contenuto in ~/build/linux/work/libraries/Wire/ (io sono in linux, magari per windows o mac cambia il path) e modificare l'include di twi.h da

  #include "twi.h"

a

  #include "utility/twi.h"

Et voilà, ora il vostro IDE è in grado di compilare sottocatelle, sotto-sottocartelle etc... fate solo attenzione a non creare collegamenti a una cartella superiore, se non vi piacciono i loop infiniti :wink:

edit: ho aperto una richiesta di miglioramento con questa soluzione su Google Code Archive - Long-term storage for Google Code Project Hosting., vediamo se me la accettano...

no, problemi di visibilità non ci dovrebbero essere dato che faccio tutto nel setup()

Si ho visto male anzi ho ragionato male "Classe tmp" è globale è tmp puoi usarlo negli scope più interni, non è vero il contrario, "Classe tmp" dentro una funzione, fuori nello scope esterno tmp non è visibile.

Quindi il problema quale era?
È Arduino ide che non andava?
Ora con la modifica che hai fatto quel codice và?

Faccio alcune considerazioni sulla questione librerie:
Intanto una libreria è un file che contiene vari file ".o" compressa con avr-ar, tuttavia è evidente il vantaggio di avere pezzi di codice sorgente che all'occasione vogliamo usare nel nostro programma (skethc).
Questi pezzi di codice non sono librerie, ma codice sorgente compilato staticamente, questo credo comporti un uso non proprio consono delle limitate risorse hardware con cui lavoriamo. Dico questo perchè tempo fà (credo) ho notato che pezzi di codice vengono inseriti staticamente nel "elf", mentre di una libreria il linker fà un lavoro più fino. Se un modulo.o in una libreria modules.a contiene cento funzioni, ed io nel mio programma ne uso una sola il linker prende solo ciò che serve per risolvere e non tutte le 100 funzioni, cosa che sarebbero presenti nel caso modulo.cpp viene compilato staticamente.

Se fosse come dico, allora se avessi un modo automatico che dal mio pezzo di codice sorgente crea delle libreire al volo e poi fa intervenire il linker, il problema sarebbe risolto. Ma come fare ciò? due strade, L'ide analizza il codice è fa il lavoro sporco, oppure L'ide analizza delle directory dove sa che troverà dei sorgenti che se specificato da questi deve ricavare delle librerie ".a".

Per il codice interno al progetto ho risolto, fà tutto in automatico qmake e make, guradando in sotto cartelle se richiesto e genera ".pro" e Makefile in ogni cartella. Questo da la possibilità di dividere il codice del progetto in sottocartelle ed anche se in qualche sotto cartella c'è del sorgente che non vogliamo compilare la cosa è fattibile abbastanza facilmente. Insomma come se stessimo sviluppando codice c++ per il nostro pc, tranne una cosa le librerie ".a" devono essere sempre ricompilate perchè non c'è modo di sapere se sono state compilate per atmega2561 o 328p, almeno io non ho trovato nessun modo per ricavare queste info da libreria ".a", ma anche se fosse la libreria deve stare nella directory di progetto perchè contiene informazioni preziose per il debug, sarebbe solo inteliggente interrogare il ".a" su come è stato compilato e se ritorna 328p e noi nell'ide non abbiamo fatto scelta diversa semplicemente non è necessario ricompilare. Io mi sono inventato un metodo per fare questo, ma non è elegante come interrogare le librerie direttamente però funge.

Ok mi fermo qui, perchè ho scritto tutto di getto, e mi sono reso conto che sono stato logorroico, (scrivorroico? :|)
Ciao.

MauroTec:
Quindi il problema quale era?

arduino non preleva i file ricorsivamente dalla cartella sketch o libraries, ma solo dalla core. In pratica se ne frega delle sottocartelle.

MauroTec:
È Arduino ide che non andava?

più che non andare, questa feature era stata "bloccata"

MauroTec:
Ora con la modifica che hai fatto quel codice và?

liscio come l'olio, il codice non sembra avere problemi

MauroTec:
Faccio alcune considerazioni sulla questione librerie:
Intanto una libreria è un file che contiene vari file ".o" compressa con avr-ar, tuttavia è evidente il vantaggio di avere pezzi di codice sorgente che all'occasione vogliamo usare nel nostro programma (skethc).
Questi pezzi di codice non sono librerie, ma codice sorgente compilato staticamente, questo credo comporti un uso non proprio consono delle limitate risorse hardware con cui lavoriamo. Dico questo perchè tempo fà (credo) ho notato che pezzi di codice vengono inseriti staticamente nel "elf", mentre di una libreria il linker fà un lavoro più fino. Se un modulo.o in una libreria modules.a contiene cento funzioni, ed io nel mio programma ne uso una sola il linker prende solo ciò che serve per risolvere e non tutte le 100 funzioni, cosa che sarebbero presenti nel caso modulo.cpp viene compilato staticamente.

Se fosse come dico, allora se avessi un modo automatico che dal mio pezzo di codice sorgente crea delle libreire al volo e poi fa intervenire il linker, il problema sarebbe risolto. Ma come fare ciò? due strade, L'ide analizza il codice è fa il lavoro sporco, oppure L'ide analizza delle directory dove sa che troverà dei sorgenti che se specificato da questi deve ricavare delle librerie ".a".

Per il codice interno al progetto ho risolto, fà tutto in automatico qmake e make, guradando in sotto cartelle se richiesto e genera ".pro" e Makefile in ogni cartella. Questo da la possibilità di dividere il codice del progetto in sottocartelle ed anche se in qualche sotto cartella c'è del sorgente che non vogliamo compilare la cosa è fattibile abbastanza facilmente. Insomma come se stessimo sviluppando codice c++ per il nostro pc, tranne una cosa le librerie ".a" devono essere sempre ricompilate perchè non c'è modo di sapere se sono state compilate per atmega2561 o 328p, almeno io non ho trovato nessun modo per ricavare queste info da libreria ".a", ma anche se fosse la libreria deve stare nella directory di progetto perchè contiene informazioni preziose per il debug, sarebbe solo inteliggente interrogare il ".a" su come è stato compilato e se ritorna 328p e noi nell'ide non abbiamo fatto scelta diversa semplicemente non è necessario ricompilare. Io mi sono inventato un metodo per fare questo, ma non è elegante come interrogare le librerie direttamente però funge.

Ok mi fermo qui, perchè ho scritto tutto di getto, e mi sono reso conto che sono stato logorroico, (scrivorroico? :|)
Ciao.

per me non è un problema, visto che le librerie (anzi, le classi) che ho creato le uso tutte al 100% :slight_smile:
sinceramente non so se i file .cpp abbiano questo tipo di ottimizzazioni, anche perchè sarebbe complessa la gestione in caso di estensioni, polimorfismo etc..
In compenso però è erroneo avere una classe con 100 metodi, i mio prof diceva sempre che se una classe è più lunga di una pagina, allora c'è qualcosa di errato nell'architettura del codice :slight_smile:

In compenso però è erroneo avere una classe con 100 metodi, i mio prof diceva sempre che se una classe è più lunga di una pagina, allora c'è qualcosa di errato nell'architettura del codice smiley

Si, difatti mi riferivo a funzioni non metodi di classe, non dimentichiamo che il cpp può tornare utile, ma quando vuoi efficienza e velocità il C è ancora una buona scelta, anzi.

Per le classi, posso confermare che tutti i metodi durante la compilazione vengono trasformati in codice asm, però poi non so se il link fà qualche acrobazia.

Mentre per le le funzioni contenute in un modulo di libreira ho visto che risolve solo i nomi mancanti e quindi un file con 10 funzioni ed io ne uso solo una solo questa verrà inclusa nel file binario, mentre se compilo un sorgente con 10 funzioni tutte faranno parte del binario, anche se ne uso solo una, di questo però ho un ricordo vago, mi riprometto di indagare.

Se dico al sistema di compilazione (qmake make) di compilare uno o più sorgenti da una directory esterna al file di progetto, questo fà il lavoro che ci si aspetto, il file oggetto compilato compare nell'albero dei file di progetto, ma non il sorgente.

Allora ho pensato che sarebbe comodo avere un posto nella home dell'utente dove salvare pezzi di codici, funzioni, classi, ecc, e inserire nell'ide una voce di menu "import code snippets" che mostra una dialog con una lista, così da poter importare la proprio classe o serei di funzione all'interno della directory di progetto.

Mi sembra una soluzione pulita, che dici.?

Ciao.

scusa non vedo la differenza dalla cartella libraries che puoi crearti all'interno di sketcbook apposta per fare quello che dici..

scusate i multipost, ma altro piccolo passo:
mi sono accorto che il discorso precedente funziona SOLO per la cartella libraries...

soluzione: nel file Base.java aggiungete i 2 metodi:

public static void updateLib(File sketchPath){// added by mauro
    libraries = new HashSet<File>();

    // reset the table mapping imports to libraries
    importToLibraryTable = new HashMap<String, File>();

    // Add from the "libraries" subfolder in the Processing directory
    try {
      addLib(librariesFolder);
    } catch (IOException e) {
      e.printStackTrace();
    }
    // Add libraries found in the sketchbook folder

    try {
      File sketchbookLibraries = getSketchbookLibrariesFolder();
      boolean found = addLib(sketchbookLibraries);
    } catch (IOException e) {
      e.printStackTrace();
    }

  // Add libraries found in the sketch folder
    try {
      boolean found = addLib(sketchPath);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  private static boolean addLib(File folder) throws IOException{
    if (!folder.isDirectory()) return false;

    String list[] = folder.list(new FilenameFilter() {
      public boolean accept(File dir, String name) {
        // skip .DS_Store files, .svn folders, etc
        if (name.charAt(0) == '.') return false;
        if (name.equals("CVS")) return false;
        return (new File(dir, name).isDirectory());
      }
    });
    // if a bad folder or something like that, this might come back null
    if (list == null) return false;

    // alphabetize list, since it's not always alpha order
    // replaced hella slow bubble sort with this feller for 0093
    Arrays.sort(list, String.CASE_INSENSITIVE_ORDER);

    boolean ifound = false;

    for (String potentialName : list) {
      File subfolder = new File(folder, potentialName);
//      File libraryFolder = new File(subfolder, "library");
//      File libraryJar = new File(libraryFolder, potentialName + ".jar");
//      // If a .jar file of the same prefix as the folder exists
//      // inside the 'library' subfolder of the sketch
//      if (libraryJar.exists()) {
        String sanityCheck = Sketch.sanitizeName(potentialName);
        if (!sanityCheck.equals(potentialName)) {
          String mess =
            "The library \"" + potentialName + "\" cannot be used.\n" +
            "Library names must contain only basic letters and numbers.\n" +
            "(ASCII only and no spaces, and it cannot start with a number)";
          Base.showMessage("Ignoring bad library name", mess);
          continue;
        }

        String libraryName = potentialName;
//        // get the path for all .jar files in this code folder
//        String libraryClassPath =
//          Compiler.contentsToClassPath(libraryFolder);
//        // grab all jars and classes from this folder,
//        // and append them to the library classpath
//        librariesClassPath +=
//          File.pathSeparatorChar + libraryClassPath;
//        // need to associate each import with a library folder
//        String packages[] =
//          Compiler.packageListFromClassPath(libraryClassPath);
        libraries.add(subfolder);
        String packages[] =
          Compiler.headerListFromIncludePath(subfolder.getAbsolutePath());
        for (String pkg : packages) {
          importToLibraryTable.put(pkg, subfolder);
        }

  
        ifound = true;

// XXX: DAM: should recurse here so that library folders can be nested
//      } else {  // not a library, but is still a folder, so recurse
//        JMenu submenu = new JMenu(libraryName);
//        // needs to be separate var, otherwise would set ifound to false
//        boolean found = addLibraries(submenu, subfolder);
//        if (found) {
//          menu.add(submenu);
//          ifound = true;
//        }
//      }
    }
    return ifound;
  }

nel file Sketch.java
a riga 1332, nel metodo preprocess aggiungere:

Base.updateLib(folder);

et voilà.. :stuck_out_tongue:

ah dimenticavo, un "piccolo" vantaggio collaterale di questo metodo, è che OGNI volta che COMPILATE, vengono aggiornate le librerie (ma NON nei menu, solo internamente), ciò vuol dire che ora potete inserire nuove librerie nei file di arduino, nella cartella libraries, e nella cartella dello sketch e usarle SENZA dovre chiudere e riaprire l'IDE

edit2: rimane un problema: la gerarchia interna delle librerie viene persa in fase di compilazione, quindi evitate come la peste di fare due librerie/classi con lo stesso nome, anche se in cartelle diverse..

INFINE ATTENZIONE: la compilazione va a buon fine, ma per ora non ho il tempo di provare a uppare il codice per vedere se effettivamente è tutto ok.... appena faccio le prove vi faccio sapere i risultati