#include classe e path
-
ciao. stò cercando di realizzare una gui per un programma open source in qt. Il problema principale è che il programma è in hard-realtime e quindi mette a disposizione tutta una serie di header e classi per potere comunicare col processo realtime. Quindi bisigna usare queste classi e header per potere
inviare i corretti segnali ed avere dei feedback adeguati inserendoli come #include nei vari header interessati del progetto.fino a qui niente di straordinario ...
la cosa per me difficile è questa: il programma attualmente è installato in una cartella in home (uso ubuntu) e non gira su kernel realtime. Questa è una possibilità di utilizzo del programma open per finalità di test. Per usarlo in questo modo bisogna prima lanciare uno script bash che non fa altro che lanciare una serie di comandi LD_PATH per linkare le librerie e gli header utilizzati nella cartella locale anzichè utilizzare quelli normalmente installati nelle normali directory (tipicamente /usr/share/include oppure /usr/lib). Infatti in questa modalità il programma viene installato solo nella cartella locale.
Ora usando qt5 idle non riesco a ricreare nel file.pro questa cosa ... non riesco perchè non sò come fare. INCLUDEPAH non è comando corretto infatti mi permette di creare il corretto percorso per gli inclide necessarii ... ma non costringe gli header o le classi del programma open source a puntare nella cartella locale anzichè in quelle standard di installazione. Non saprei come creare dei link statici per costringere tutte le librerie e gli header del programma opensources a puntare alla cartella locale.
se mi devo spiegare meglio ... lo farò per ora mi sembra di avere chiarito il concetto.
Accetto ogni suggerimeneo.giorgio
-
-
Allora credo di non aver capito il problema. Stai tentando di linkare librerie da una specifica cartella invece che da
/usr/lib
. Sbaglio?@VRonin si e no ..... si perchè mi serve ... ma questo è già risolto e il mio progetto "vede" gli header e librerie scritti da terzi. ... No perchè dovrei fare in modo che classi scritte da terzi e i cui header sono inclusi nel mio progetto cerchino a loro volta nella cartella /miacartelladihomespeciale/include ... anzichè nella cartella /usr/include come il programma fa, Se e solo se viene installato nella maniera classica.
Per scopi di test è possibile installarlo in una cartella di home, a patto di lanciare uno scripts in bash, il quale altro non fa che lanciare una serie di comandi ld_path per fare in modo che tutto il programma (classi, header e librerie) cerchino i vari file all'interno della cartella di installazione in home (anzichè nelle path standard previste), ogni qualvolta si accende il pc.
Ora nel mio progetto qt ho inserito tutta una serie di INCLUDEPATH e LIBS che fanno in modo che io possa utilizzare librerie e gli header correttamente. Ma se gli header fanno riferimento a loro volta ad altri header non inclusi nel mio progetto (come accade) sono fregato. Il mio file pro dovrebbe fare esattamente quello che fa il programma bash per potere compilare correttamente .... altrimenti il compilatore ogni volta mi restituisce degli errori di invalid references ... per forza faccio riferimento e classi che non vengono incluse nel progetto poichè fuori "della sfera di azione" del compilatore qt gcc.
non sono un campione e faccio fatica ad esprimenrmi correttamente ...
lo script fa cose queste cose (linuxcnc), reindirizzando tutto il programma nelle cartelle corrette .... ora anche il mio progetto per essere correttamente compilato dovrebbe prima fare questo tipo di reindirizzamento .... INCLUDEPATH non va bene ... ci vorrebbero comandi simili e non saprei come comporli (ammesso si possa):case "$0" in rip-environment|*/rip-environment) as_command=true if [ $# -eq 0 ]; then cat <<-EOF This script can be used in one of two ways. It can be loaded in the context of your shell, by executing . $0 after this, commands like 'linuxcnc', 'halrun' and so on refer to the version in this directory, instead of to an installed version of linuxcnc (if any) Second, it can be used to run a command in this directory without modifying the environment of the calling shell: $0 command... such as $0 halrun foo.hal $0 linuxcnc configs/.../foo.ini EOF exit 1 fi ;; *) as_command=false esac if ! test "xyes" = "xyes"; then echo "This script is only useful on run-in-place systems." return fi case "$PATH" in /home/mypc/linuxcnc-dev/bin:*|*:/home/mypc/linuxcnc-dev/bin:*) if ! $as_command; then echo "This script only needs to be run once per shell session." return fi ;; esac EMC2_HOME=/home/mypc/linuxcnc-dev; export EMC2_HOME EMC2VERSION="2.8.0~pre1"; export EMC2VERSION LINUXCNCVERSION="2.8.0~pre1"; export LINUXCNCVERSION LINUXCNC_NCFILES_DIR="/home/mypc/linuxcnc-dev/nc_files"; export LINUXCNC_NCFILES_DIR LINUXCNC_EMCSH=/usr/bin/wish8.6; export LINUXCNC_EMCSH PATH=/home/mypc/linuxcnc-dev/bin:$EMC2_HOME/scripts:$EMC2_HOME/tcl:"$PATH" if [ -z "$TCLLIBPATH" ]; then TCLLIBPATH=$EMC2_HOME/tcl else TCLLIBPATH=$EMC2_HOME/tcl:$TCLLIBPATH fi if [ -z "$LD_LIBRARY_PATH" ]; then LD_LIBRARY_PATH=$EMC2_HOME/lib else LD_LIBRARY_PATH=$EMC2_HOME/lib:"$LD_LIBRARY_PATH" fi if [ -z "$PYTHONPATH" ]; then PYTHONPATH=$EMC2_HOME/lib/python else PYTHONPATH=$EMC2_HOME/lib/python:"$PYTHONPATH" fi if [ -z "$MANPATH" ]; then if type -path manpath > /dev/null 2>&1; then MANPATH=$EMC2_HOME/docs/man:"$(manpath)" else MANPATH=$EMC2_HOME/docs/man:/usr/local/man:/usr/local/share/man:/usr/share/man fi else MANPATH=$EMC2_HOME/docs/man:"$MANPATH" fi if [ -z "$GLADE_CATALOG_PATH" ]; then GLADE_CATALOG_PATH=$EMC2_HOME/lib/python/gladevcp else GLADE_CATALOG_PATH=$EMC2_HOME/lib/python/gladevcp:"$GLADE_CATALOG_PATH" fi if ! $as_command; then # TODO: if these completion directives give trouble for any versions # of bash actively in use, protect them with checks of BASH_VERSINFO if [ $BASH_VERSINFO -eq 2 ]; then complete -o dirnames -f -X '!*.ini' emc axis mdi complete -o dirnames -f -X '!*.hal' halrun halcmd complete -W 'start stop restart status' realtime complete -C "halcmd -C" halcmd else _iningc () { case "$3" in *.ini) COMPREPLY=($(compgen -o plusdirs -f -X '!*.ngc' -- "$2")) ;; *) COMPREPLY=($(compgen -o plusdirs -f -X '!*.ini' -- "$2")) esac } complete -o plusdirs -F _iningc emc axis complete -o plusdirs -f -X '!*.ini' mdi complete -o plusdirs -f -X '!*.hal' halrun halcmd complete -W 'start stop restart status' realtime complete -C "halcmd -C" halcmd fi if [ -f $EMC2_HOME/src/Makefile ]; then build () { make -C $EMC2_HOME/src "$@"; } fi fi export PYTHONPATH MANPATH LD_LIBRARY_PATH TCLLIBPATH GLADE_CATALOG_PATH if $as_command; then exec "$@"; fi
-
Ok, separiamo 3 cose:
- Gli include sono file di testo che contengono le dichiarazioni. Sono usati solo dal compilatore
- Le librerie sono pezzi di programma pre-compilati che il tuo programma va a usare, gli include servono a dire al tuo programma cosa c'e' all'interno delle librerie. Sono usati solo dal compilatore
- I binari di librerie dinamiche (.dll) sono pezzi di programma che vengono distribuiti a parte dal programma principale. Sono usate solo quando esegui il programma
Ora nel mio progetto qt ho inserito tutta una serie di INCLUDEPATH e LIBS
Come?
il quale altro non fa che lanciare una serie di comandi ld_path
Quello script fa molto di piu'
PATH=/home/mypc/linuxcnc-dev/bin:$EMC2_HOME/scripts:$EMC2_HOME/tcl:"$PATH"
per esempio cambia la variabilePATH
e questo non e' possibile tramite qmake (files .pro) -
Ora nel mio progetto qt ho inserito tutta una serie di INCLUDEPATH e LIBS
Come?
INCLUDEPATH += /home/mypc/linuxcnc-dev/bin
INCLUDEPATH += /home/mypc/linuxcnc-dev/include
INCLUDEPATH += /home/mypc/linuxcnc-dev/libLIBS += -L /home/mypc/linuxcnc-dev/lib -lnml -llinuxcnc
il quale altro non fa che lanciare una serie di comandi ld_path
Quello script fa molto di piu'
PATH=/home/mypc/linuxcnc-dev/bin:$EMC2_HOME/scripts:$EMC2_HOME/tcl:"$PATH" per esempio cambia la variabile PATH e questo non e' possibile tramite qmake (files .pro)Bhè si è vero che fa molto di più ... ma la sostituzione della variabile $PATH funziona solo negli script python ... non sono riuscito trovare una spiegazione del perchè questo comando invece funzioni:
g++ myprogram.cc -o test1 -I include -L lib -lnml -llinuxcnc (ovviamente dopo avere lanciato lo script bash)
allo stato attuale myprogram.cc e la versione qt myprogram.ccp fanno le stesse cose ... addirittura ho provato a mettere il mio progetto nella cartella /home/mypc/linuxcnc-dev/scripts e compilarlo da la dopo avere lanciato lo scripts .... ma qmake se ne infischia ....
e qui viene il bello .... ogni tanto scrivendo mi vengono dei dubbi perchè sono cose che faccio dei ritagli di tempo ... così ho riprovato il comando
g++ myprogram.cc -o test1 -I include -L lib -lnml -llinuxcnc (ovviamente dopo avere lanciato lo script bash)e questa volta mi da lo stesso errore che ottengo su qt ... controllo il file e manca un include ... inserisco l'include in qt .... e finalmente tutto compila correttamente ....
bastava infilare il progetto nella cartella a cui puntava lo scripts ... a volte le soluzioni più facili ......
mi restituisce questo errore però quando lo faccio partire:
Starting /home/mypc/linuxcnc-dev/scripts/Qtmyprogram... /home/mypc/linuxcnc-dev/scripts/Qtmyprogram: error while loading shared libraries: libnml.so.0: cannot open shared object file: No such file or directory /home/mypc/linuxcnc-dev/scripts/QtDro exited with code 127
la libreria c'è .... ed è nel posto giusto .... io la chiamo con -lnml ... tu hai qualche idea a riguardo?
-
@VRonin ok ... quindi se non sono nella cartella del progetto, non sono raggiungibili da LIBS nel file pro ... significa che posso aggiungere nella cartella un link che punta alla libreria ...
teoricamente quella libreria dovrebbe essere letta da
LIBS += -L /home/mypc/linuxcnc-dev/lib -lnml -llinuxcnc
nota che -llnml è la prima e libnml.so.0 è proprio il suo binario ...
la cosa strana è che per certo sono in
PATH
provo ad aggiungere il link nella cartella ... ho il sospetto che se faccio il link a libnml.so.0 nella cartella del progetto (ammesso che funzioni) dovrò farne uno anche per -llinuxcnc .... quindi perchè secondo te qmake non carica le librerie?
-
Quello che non mi e' chiaro e' se il tuo problema sia al momento della compilazione o quando lanci il programma
@VRonin Quando lancio il programma ... alla compilazione ora va tutto a meraviglia ...
quindi riassumendo:
1-alla compilazione tutto ok.
2- al lancio del programma -> errore
Starting /home/mypc/linuxcnc-dev/scripts/Qtmyprogram... /home/mypc/linuxcnc-dev/scripts/Qtmyprogram: error while loading shared libraries: libnml.so.0: cannot open shared object file: No such file or directory /home/mypc/linuxcnc-dev/scripts/QtDro exited with code 127
giorgio
-
Allora quello che c'e' nel file pro non c'entra nulla.
La soluzione e' spiegata nel paragrafo "List Dependencies" di questo articolo