{"id":91,"date":"2011-03-14T07:43:20","date_gmt":"2011-03-14T07:43:20","guid":{"rendered":"http:\/\/www.budus.it\/Blog\/?p=91"},"modified":"2022-09-15T10:22:05","modified_gmt":"2022-09-15T10:22:05","slug":"installazione-dellambiente-di-sviluppo-mingw-msys-emacs-fltk","status":"publish","type":"post","link":"https:\/\/www.budus.it\/Blog\/installazione-dellambiente-di-sviluppo-mingw-msys-emacs-fltk\/","title":{"rendered":"Installazione dell&#8217;ambiente di sviluppo MinGW + MSYS + EMACS + FLTK"},"content":{"rendered":"<p>Da anni uso l&#8217;ambiente di sviluppo in oggetto per fare i miei &#8220;programmini&#8221;.<\/p>\n<p><!--more--><\/p>\n<p>Per chi non lo sapesse abbiamo:<\/p>\n<ul>\n<li><strong>MinGW<\/strong>: Compilatore C\/C++ per Windows, praticamente il porting del GCC presente su piattaforma UNIX (Linux in particolare).<\/li>\n<li><strong>MSYS<\/strong>: Emulatore del terminale Linux, con alcuni comandi tipici dell&#8217;ambiente Bash.<\/li>\n<li><strong>EMACS<\/strong>: Insieme a <strong>vi<\/strong>, uno degli editor storici del mondo UNIX.<\/li>\n<li><strong>FLTK<\/strong>: Framework C++ per sviluppare software con interfaccia grafica multipiattaforma.<\/li>\n<\/ul>\n<p>Bene, ecco i passaggi da fare (su Windows) per ottenere questo ambiente di sviluppo funzionante:<\/p>\n<ul>\n<li>Scaricare MinGW da <a title=\"MinGW\" href=\"http:\/\/sourceforge.net\/projects\/mingw\" target=\"_blank\" rel=\"noopener\">http:\/\/sourceforge.net\/projects\/mingw<\/a> e installarlo nella locazione di default ( <em><strong>C:\\MinGW<\/strong><\/em> ), lasciando il nome di default ( <strong>MinGW<\/strong>) e selezionando i seguenti componenti aggiuntivi:\n<ul>\n<li>C++ Compiler<\/li>\n<li>MSYS Basic System<\/li>\n<\/ul>\n<\/li>\n<li>Scaricare e installare EMACS da <a title=\"EMACS\" href=\"http:\/\/ftp.gnu.org\/gnu\/emacs\/windows\" target=\"_blank\" rel=\"noopener\">http:\/\/ftp.gnu.org\/gnu\/emacs\/windows<\/a> (nel momento in cui scrivo &#8211; 20.45 03\/09\/2010 &#8211; l&#8217;ultima versione disponibile risulta essere <em><strong>emacs-23.2-bin-i386.zip<\/strong><\/em> ); per installarlo, aperto lo zip, decomprimere il tutto in C:\\MinGW\\bin (dovrebbe creare una sotto-cartella di nome simile a &#8220;emacs-23.2&#8221;) e lanciare <strong>C:\\MinGW\\bin\\emacs-??.?\\addpm.exe<\/strong> e rispondere affermativamente quando chiede se installarlo l\u00ec.<\/li>\n<\/ul>\n<p style=\"padding-left: 60px;\">N.B.: Ricordo che EMACS \u00e8 il migliore editor del pianeta e chi non lo usa<br \/>\ndeve crepare lapidato.<\/p>\n<ul>\n<li>Sul desktop non viene messa nemmeno un&#8217;icona; se questa cosa sta sulle palle, si pu\u00f2 rimediare trascinando le icone:\n<ul>\n<li><em>Start -&gt; Tutti i Programmi -&gt; MinGW -&gt; MinGW Shell<\/em><\/li>\n<li><em>Start -&gt; Tutti i Programmi -&gt; GNU Emacs -&gt; Emacs<\/em><\/li>\n<\/ul>\n<\/li>\n<li>Ora bisogna fare in modo che da MinGW Shell ci sia modo di lanciare EMACS; io l&#8217;ho abbreviato in &#8220;e&#8221; (e penso che tutto il mondo dovrebbe fare cos\u00ec), quindi procedere come segue:\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Aprire MinGW Shell (<em>Start -&gt; Tutti i Programmi -&gt; MinGW -&gt; MinGW Shell<\/em>)<\/li>\n<li>Tasto destro del Mouse sulla barra del titolo e scegliere &#8220;Propriet\u00e0&#8221;<\/li>\n<li>Spuntare &#8220;Modalit\u00e0 Modifica Rapida&#8221;<\/li>\n<li>In &#8220;Tipo di carattere&#8221; scegliere &#8220;10&#215;18&#8221;<\/li>\n<li>Cliccare su &#8220;OK&#8221; e scegliere &#8220;Salva le propriet\u00e0 per le finestre future con lo stesso titolo&#8221;<\/li>\n<li>Digitare i seguenti comandi (ATTENTO: pu\u00f2 variare la cartella di EMACS):<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre> cd \/c\/MinGW\/bin\n echo '\/c\/MinGW\/bin\/emacs-23.2\/bin\/runemacs.exe \"$@\"' &gt; e\n chmod.exe +x e\n cd\n e<\/pre>\n<ul>\n<li>In EMACS usare la combinazione &#8220;CTRL+x f&#8221; e aprire il file &#8220;.emacs&#8221; (non esiste, lo stiamo creando nella HOME)<\/li>\n<li>Fare un copia\/incolla delle seguenti righe:\n<pre>(custom-set-variables\n;; custom-set-variables was added by Custom.\n;; If you edit it by hand, you could mess it up, so be careful.\n;; Your init file should contain only one such instance.\n;; If there is more than one, they won't work right.\n'(case-fold-search t)\n'(column-number-mode t)\n'(current-language-environment \"Italian\")\n'(default-input-method \"italian-postfix\")\n'(global-font-lock-mode t nil (font-lock))\n'(inhibit-startup-screen t)\n'(pc-selection-mode t nil (pc-select))\n'(save-place t nil (saveplace)))\n(custom-set-faces\n;; custom-set-faces was added by Custom.\n;; If you edit it by hand, you could mess it up, so be careful.\n;; Your init file should contain only one such instance.\n;; If there is more than one, they won't work right.\n'(default ((t (:stipple nil :background \"black\" :foreground \"white\" :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight normal :height 120 :width normal :family \"adobe-courier\"))))\n'(cursor ((t (:background \"white\" :foreground \"black\")))))\n;; keybindings\n(global-set-key \"\\C-x\\C-g\" 'goto-line)\n(global-set-key [(f1)] (lambda () (interactive) (manual-entry (current-word))))\n; TILDE C+M+\u00ec\n(define-key global-map (kbd \"C-M-\u00ec\") (lambda () (interactive) (insert ?~ )))\n(fset 'uda_protect_variable\n[C-insert ?\\C-x ?2 C-home ?\\M-% S-insert return S-insert ?} home right ?{ return ?! ?\\C-x ?o ?\\C-x ?1])\n(fset 'uda_remove_line_number\n[?\\C-\\M-% ?^ ?\\[ ?  ?0 ?- ?9 ?\\] ?* return return ?!])\n(mouse-wheel-mode t)\n(column-number-mode 1)\n;;(server-start)\n(menu-bar-mode)\n;;(tool-bar-mode)\n\n;; Kill All Buffers without prompting.\n;; Modified from kill-some-buffers in files.el, which prompts too much.\n(defun kill-all-buffers ()\n\"Kill all buffers without prompting.\"\n(interactive)\n(let ((list (buffer-list)))\n(while list\n(let* ((buffer (car list))\n(name (buffer-name buffer)))\n(kill-buffer buffer))\n(setq list (cdr list)))))<\/pre>\n<\/li>\n<li>Chiudere salvando con &#8220;CTRL+x CTRL+c y&#8221;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p style=\"padding-left: 120px;\">N.B.: Ora EMACS si apre con la configurazione giusta e consente, tra le varie cose, di raggiungere una determinata riga con &#8220;CTRL+x CTRL+g&#8221;<\/p>\n<p style=\"padding-left: 120px;\">Se la mancanza del menu in alto \u00e8 ritenuta grave(per\u00f2 poi i comandi che apro usando &#8220;F10&#8221; vanno scelti da menu &#8230;.), usare:<\/p>\n<p style=\"padding-left: 120px;\">ALT+x toggle-menu-bar-mode-from-frame<\/p>\n<p style=\"padding-left: 120px;\">Io comunque consiglio di abituarsi al tasto &#8220;F10&#8221; e navigare con le accelerazioni da tastiera; ad esempio il Revision Control System lo gestisci da: F10 t v<\/p>\n<ul>\n<li>Scaricare UDC (UDA Data Copy) da qui: <a title=\"UDA Data Copy\" href=\"http:\/\/digilander.libero.it\/udasoft\/Software\/multiplatform\/udc\/udc-1.6.00.zip\" target=\"_blank\" rel=\"noopener\">http:\/\/digilander.libero.it\/udasoft\/Software\/multiplatform\/udc\/udc-1.6.00.zip<\/a> e installarlo sempre in <em><strong>C:\\MinGW\\bin<\/strong><\/em><\/li>\n<li>Nel terminale dare i seguenti comandi:\n<pre>cd \/c\/MinGW\/bin\nmv udc udc-1.6.00\nln -s udc-1.6.00\/udc.exe udc\nln -s udc-1.6.00\/libregex.dll<\/pre>\n<\/li>\n<li>Aprire la cartella\u00a0 <em><strong>C:\\MinGW\\bin\\udc-1.6.00<\/strong><\/em> , copiare <strong>udc.exe<\/strong>, aprire &#8220;Esplora Risorse&#8221; sul tasto &#8220;Start&#8221; di Windows, selezionare la cartella &#8220;SendTo&#8221; e *INCOLLARE COME COLLEGAMENTO*, quindi rinominare il link, ad esempio in &#8220;UDA Data Copy&#8221;.<\/li>\n<\/ul>\n<p style=\"padding-left: 60px;\">N.B.: Questo consente di aprire i file UNIX visualizzandoli correttamente e, volendo, fare parecchie altre cose (vedere guida del programma).<\/p>\n<ul>\n<li>Quando si apre la shell di MinGW, la HOME directory si trova in un percorso simile al seguente:<\/li>\n<\/ul>\n<p style=\"padding-left: 60px;\"><em><strong>C:\\MinGW\\msys\\1.0\\home\\nome_utente<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px;\">dando il &#8220;cd&#8221;, si finisce automaticamente in questa cartella; per comodit\u00e0 \u00e8 quindi utile mettere i propri sorgenti in suddetta directory.<\/p>\n<p style=\"padding-left: 60px;\">Tutti i sorgenti che andremo ora a compilare andranno messi l\u00ec.<\/p>\n<ul>\n<li>Iniziamo da FLTK; scaricare questo file:<br \/>\n<a title=\"FLTK\" href=\"http:\/\/www.fltk.org\/software.php?VERSION=1.3.1&amp;FILE=fltk\/1.3.1\/fltk-1.3.1-source.tar.gz\" target=\"_blank\" rel=\"noopener\">http:\/\/www.fltk.org\/software.php?VERSION=1.3.1&amp;FILE=fltk\/1.3.1\/fltk-1.3.1-source.tar.gz<\/a><br \/>\ne decomprimerlo nella HOME, andando quindi a creare la cartella fltk-1.3.1 .<br \/>\nLo compiliamo con i seguenti comandi:<\/p>\n<pre>cd\ncd fltk-1.3.1\n.\/configure\nmake<\/pre>\n<p>(la compilazione delle pagine di manuale fallisce, ma non preoccuparsi)<\/p>\n<pre>make install<\/pre>\n<\/li>\n<\/ul>\n<ul>\n<li>Ora installiamo l&#8217;RCS (Revision Control System); lo si trova qui:<br \/>\n<a title=\"Revision Control System\" href=\"http:\/\/www.cs.purdue.edu\/homes\/trinkle\/RCS\" target=\"_blank\" rel=\"noopener\">http:\/\/www.cs.purdue.edu\/homes\/trinkle\/RCS<\/a>e, nel momento in cui scrivo &#8211; 10.09 04\/09\/2010 &#8211; i files da scaricare sono:<br \/>\n<a title=\"RCS - Pacchetto 1\" href=\"http:\/\/www.cs.purdue.edu\/homes\/trinkle\/RCS\/rcs57pc1.zip\" target=\"_blank\" rel=\"noopener\"> http:\/\/www.cs.purdue.edu\/homes\/trinkle\/RCS\/rcs57pc1.zip<\/a><br \/>\n<a title=\"RCS - Pacchetto 2\" href=\"http:\/\/www.cs.purdue.edu\/homes\/trinkle\/RCS\/rcs57pc2.zip\" target=\"_blank\" rel=\"noopener\"> http:\/\/www.cs.purdue.edu\/homes\/trinkle\/RCS\/rcs57pc2.zip<\/a><br \/>\n<a title=\"RCS - Pacchetto 3\" href=\"http:\/\/www.cs.purdue.edu\/homes\/trinkle\/RCS\/rcs57pc3.zip\" target=\"_blank\" rel=\"noopener\"> http:\/\/www.cs.purdue.edu\/homes\/trinkle\/RCS\/rcs57pc3.zip<\/a><br \/>\ni file vanno decompressi in <em><strong>C:\\MinGW\\bin\\RCS<\/strong><\/em>(bisogna creare la cartella RCS).Aprire MinGW Shell e dare i seguenti comandi:<\/p>\n<pre>cd \/c\/MinGW\/bin\nfor file in \/c\/MinGW\/bin\/RCS\/bin\/win32\/*; do ln -s ${file}; done\ncd\nexport TZ=GMT-0<\/pre>\n<p>In Windows cliccare con il tasto destro del mouse su &#8220;Risorse del Computer&#8221;, quindi scegliere &#8220;Propriet\u00e0&#8221;, scegliere la tabella &#8220;Avanzate&#8221;, cliccare su &#8220;Variabili d&#8217;ambiente&#8221;, il bottone &#8220;Nuovo&#8221; (uno dei due, io ho usato quello per il solo utente) e usare per &#8220;Nome Variabile&#8221; il valore &#8220;TZ&#8221; e per &#8220;Valore Variabile&#8221; la stringa &#8220;GMT-0&#8221; (chiaramente senza virgolette).<br \/>\nConfermare con OK, OK.<\/p>\n<p>In Windows cliccare con il tasto destro del mouse su &#8220;Risorse del Computer&#8221;, quindi scegliere &#8220;Propriet\u00e0&#8221;, scegliere la tabella &#8220;Avanzate&#8221;, cliccare su &#8220;Variabili d&#8217;ambiente&#8221;, il bottone &#8220;Nuovo&#8221; (uno dei due, io ho usato quello per il solo utente) e usare per &#8220;Nome Variabile&#8221; il valore &#8220;RCSINIT&#8221; e per &#8220;Valore Variabile&#8221; la stringa &#8220;-x,v\/&#8221; (chiaramente senza virgolette).<br \/>\nConfermare con OK, OK.<\/p>\n<p>N.B.: E&#8217; possibile che, facendo il check-out di sorgenti provenienti da un altro sistema, il sistema comunichi un messaggio di errore circa la necessita&#8217; di ripristinare il blocco sul file; rispondere &#8220;yes&#8221; e ripetere l&#8217;operazione di check-out.<\/p>\n<p>Ora gli ultimi 2 comandi per completare l&#8217;installazione:<\/p>\n<pre>cd\nmkdir src<\/pre>\n<p>Dentro <em><strong>src<\/strong><\/em> andremo a mettere i nostri sorgenti.<\/li>\n<\/ul>\n<p>Per verificare (e guardare un paio di comandi) se il sistema RCS \u00e8 funzionante, procediamo in questo modo da terminale MinGW:<\/p>\n<pre>cd src\ne main.cpp<\/pre>\n<p>dentro ci andiamo a scrivere:<\/p>\n<pre>\/* Il classico Hello World ! *\/\n#include &lt;stdio.h&gt;\n\nint main (int argc, char** argv) {\n  printf(\"Hello World !\\n\");\n  return 0;\n}<\/pre>\n<p>Salviamo con &#8220;CTRL+x CTRL+s&#8221;; ora facciamo il check-in del sorgente con &#8220;F10 t v c&#8221;; la prima volta che usiamo il sistema di controllo revisione in una cartella nuova, EMACS chiede quale strumento vogliamo usare (non c&#8217;\u00e8 solo RCS, ce ne sono parecchi altri), quindi andiamo a scrivere &#8220;RCS&#8221; al suo prompt.<\/p>\n<p>Dopodich\u00e9 ci chieder\u00e0 dove posizionare il &#8220;repository&#8221;, cio\u00e8 il suo database; ci basta dare INVIO per usare la cartella stessa (lui crea una sotto-cartella di nome RCS in automatico).<\/p>\n<p>A questo punto il sorgente &#8220;main.cpp&#8221; non \u00e8 pi\u00f9 modificabile, ne abbiamo fatto il check-in.<\/p>\n<p>Proviamo a compilare il sorgente (quando avremo creato il makefile, ci sar\u00e0 modo di farlo direttamente da EMACS, con parecchie altre utilit\u00e0):<\/p>\n<pre>gcc main.cpp -o main\n.\/main<\/pre>\n<p>Ora modifichiamo &#8220;main.cpp&#8221; facendo check-out con &#8220;F10 t v c&#8221;; aggiungiamo una riga in modo che diventi come segue:<\/p>\n<pre>\/* Il classico Hello World ! *\/\n#include &lt;stdio.h&gt;\n\nint main (int argc, char** argv) {\n  printf(\"Hello World !\\n\");\n  printf(\"Prova di RCS.\\n\");\n  return 0;\n}<\/pre>\n<p>Salviamo con &#8220;CTRL+x CTRL+s&#8221; e chiediamo a RCS di fare una analisi della cartella con &#8220;F10 t v v&#8221; e INVIO per confermare quella corrente; EMACS elencher\u00e0 quali file sono stati modificati nella cartella. Se con il cursorse si va sul nome di un file e si preme INVIO, EMACS apre quel file.<\/p>\n<p>Proviamo a fare check-in del file cos\u00ec modificato; lo si pu\u00f2 fare sia con &#8220;F10 t v c&#8221;, sia con la scorciatoia &#8220;CTRL+x v v&#8221;.<\/p>\n<p>Ora ci chiede di elencare, in una apposita finestra, le modifiche che abbiamo operato sul file; per coerenza si pu\u00f2 adottare uno stile per modificare il &#8220;VC-log&#8221;, ovvero una sintassi di questo tipo:<\/p>\n<pre>XXX: descrizione modifica<\/pre>\n<p>dove XXX \u00e8 una sigla di tre lettere che pu\u00f2 essere ADD (Aggiunto codice), MOD (Modificato codice), FIX (Corretto BUG) e WRN (Warning, avvertimento).<\/p>\n<p>Il tutto, inizialmente, va scritto su unica riga e quindi formattato con il comando offerto da EMACS, vediamo come con un esempio, scriviamo per il nostro &#8220;main.cpp&#8221; la seguente riga:<\/p>\n<pre>MOD: Aggiunto ulteriore output. Stiamo provando il sistema RCS con EMACS; vediamo come funziona la sua formattazione automatica dentro il VC-log.<\/pre>\n<p>Quando siamo a fine riga, diamo un &#8220;ALT+q&#8221; ed EMACS formatta automaticamente il<br \/>\nritorno a capo; la riga diventa cos\u00ec:<\/p>\n<pre>MOD: Aggiunto ulteriore output. Stiamo provando il sistema RCS con\nEMACS; vediamo come funziona la sua formattazione automatica dentro il\nVC-log.<\/pre>\n<p>Giustifichiamo una rientranza nella seconda riga; ci spostiamo all&#8217;inizio di quest&#8217;ultima e diamo un &#8220;ALT+i&#8221; seguito da un &#8220;ALT+q&#8221;; il risultato \u00e8 il seguente:<\/p>\n<pre>MOD: Aggiunto ulteriore output. Stiamo provando il sistema RCS con\n      EMACS; vediamo come funziona la sua formattazione automatica\n      dentro il VC-log.<\/pre>\n<p>dovremo fare cos\u00ec per ogni eventuale riga che abbiamo scritto dentro al log. Questo consente di tenere traccia delle modifiche che un sorgente ha subito. Confermiamo il check-in, salvando il log, con &#8220;CTRL+c CTRL+c&#8221;. Possiamo vedere il log dei cambiamenti del sorgente corrente con &#8220;F10 t v S&#8221;.<\/p>\n<p>Ora passiamo ad usare il sistema &#8220;<strong>ediff<\/strong>&#8220;, in modo che EMACS ci visualizzi le differenze tra il sorgente attuale e quello &#8220;checkinato&#8221;.<\/p>\n<p>Usiamo &#8220;CTRL+x o&#8221; per passare da un buffer all&#8217;altro e &#8220;CTRL+x 1&#8221; per visualizzarne uno solo; ora facciamo check-out con &#8220;CTRL+x v v&#8221;, quindi modifichiamo il sorgente alla riga 7 in modo che diventi come la seguente:<\/p>\n<pre>printf(\"Prova di RCS; vediamo il sistema ediff in funzione.\\n\");<\/pre>\n<p>Salviamo con &#8220;CTRL+x CTRL+s&#8221; e usiamo l&#8217;ediff con &#8220;F10 t v w&#8221;; EMACS mostrer\u00e0 le differenze; in grigio il codice rimasto uguale, in bianco quello cambiato con un &#8220;!&#8221; in testa.<\/p>\n<p>Possiamo avere una conferma che &#8220;main.cpp&#8221; \u00e8 stato cambiato usando l&#8217;analisi della cartella &#8220;F10 t v v&#8221; e INVIO.<\/p>\n<p>Se il file cos\u00ec cambiato non ci sta bene, possiamo annullare la modifica con (ritornare nel buffer del file modificato con &#8220;CTRL+x o&#8221;) &#8220;F10 t v R&#8221;; EMACS si accorge che il file \u00e8 stato modificato ed elenca da solo le modifiche eseguite, chiedendoci se le vogliamo scartare. Rispondiamo scrivendo &#8220;yes&#8221; (\u00e8 fiscale, vuole proprio &#8220;yes&#8221; per esteso, per essere sicuro che sappiamo cosa stiamo facendo).<\/p>\n<p>Magicamente il file torna esattamente come prima ed \u00e8 in read-only.<br \/>\nDando un&#8217;occhiata al menu che appare con &#8220;F10 t v&#8221; si pu\u00f2 notare come siano presenti numerose altre opzioni che possono tornare utili.<\/p>\n<p>Vediamo un&#8217;altra peculiarit\u00e0 di emacs; creiamo il makefile con &#8220;CTRL+x f makefile&#8221; e INVIO, quindi scriviamo quanto segue (<strong>notare che ci sono delle rientranze che vanno realizzate con il tasto &#8220;TAB&#8221; della tastiera, altrimenti si otterr\u00e0 un messaggio di errore in fase di compilazione<\/strong>):<\/p>\n<pre># A simple MAKEFILE\nCFLAGS=-I.\nDEPS=\nOBJ=main.o\nTARGET=main\nCC=g++\n\n.cpp.o: $(DEPS)\n  $(CC) -g -c -o $@<\/pre>\n<pre><\/pre>\n<pre>lt; $(CFLAGS) $(TARGET): $(OBJ) $(CC) -g -o $@<\/pre>\n<pre><\/pre>\n<pre>lt; $(CFLAGS) clean: rm -fv *~ $(TARGET).exe $(TARGET) *.o<\/pre>\n<p>Salviamo con &#8220;CTRL+x CTRL+s&#8221; e proviamo subito; al terminale diamo<\/p>\n<pre>make clean<\/pre>\n<p>quindi torniamo in EMACS e usiamo &#8220;F10 t c&#8221; confermando con INVIO (salvo non si voglia aggiungere opzioni; ad esempio su Linux uso &#8220;make -k linux&#8221;).<\/p>\n<p>Questo \u00e8 comodo, ma molto pi\u00f9 comodo \u00e8 quando ci sono errori !<\/p>\n<p>In quel caso, appaiono nella finestra di compilazione e, selezionandoli (ci si va sopra e si preme INVIO), EMACS ci apre il file incriminato direttamente alla riga dell&#8217;errore.<\/p>\n<p>Inoltre non dobbiamo necessariamente salvare i file quando li modifichiamo; nel momento in cui chiediamo ad EMACS di compilare, sar\u00e0 lui a chiederci se vogliamo salvarli.<\/p>\n<p>Infine \u00e8 arrivato il momento di usare il DEBUGGER !<\/p>\n<p>EMACS \u00e8 integrato con GDB; usiamo &#8220;F10 t d&#8221; con INVIO per avviare la relativa finestra.<\/p>\n<p>Con r + INVIO si avvia il programma ma, volendo, ci sono anche i pulsanti.<\/p>\n<p>Per inserire un &#8220;breakpoint&#8221; in un sorgente \u00e8 sufficiente aprirlo, andare alla riga desiderata e dare &#8220;CTRL+x barra_spaziatrice&#8221;; EMACS aggiunge un pallino rosso alle righe dove \u00e8 presente un breakpoint.<\/p>\n<p>Ad esempio, facciamo check-out del nostro &#8220;main.cpp&#8221; e modifichiamolo in questo modo:<\/p>\n<pre>\/* Il classico Hello World ! *\/\n\n#include &lt;stdio.h&gt;\n\nint main (int argc, char** argv) {\n  int\u00a0\u00a0\u00a0 iNumero = 0;\n\n  printf(\"Hello World !\\n\");\n\n  if (argc &gt; 1) {\n    sscanf(argv[1], \"%d\", &amp;iNumero);\n    printf(\"Numero Convertito: %d\\n\", iNumero);\n  }\n\n  return 0;\n}<\/pre>\n<p>Quindi compiliamo il tutto con &#8220;F10 t c&#8221;, ci spostiamo alla riga 10 e inseriamo un breakpoint con &#8220;CTRL+x barra_spaziatrice&#8221;; ora passiamo al debugger (in genere rimane attiva la finestra dell&#8217;ultimo sorgente aperto e, nella finestra sotto, viene messo il report della compilazione, quindi uso &#8220;CTRL+x o&#8221; per passare in quest&#8217;ultima e &#8220;CTRL+x k&#8221; per chiuderla, ritornando alla finestra del debugger) e lanciamo il programma passandogli anche un parametro con &#8220;r 099&#8221;.<\/p>\n<p>GDB blocca l&#8217;esecuzione scrivendo:<\/p>\n<pre>Breakpoint 1, main (argc=2, argv=0x3e2510) at main.cpp:10<\/pre>\n<p>Qui possiamo fare diverse cose; ad esempio vedere il &#8220;backtrace&#8221; (si scrive proprio &#8220;backtrace&#8221; e si da INVIO), per conoscere l&#8217;ordine delle chiamate a funzione (nel nostro caso c&#8217;\u00e8 solo una riga, ma se avessimo avuto una serie concatenata di chiamate a funzione, qui avremmo la lista e sapremmo &#8220;come siamo arrivati fino a qui&#8221;).<br \/>\nPossiamo anche vedere il valore di una variabile, sia in modo temporaneo:<\/p>\n<pre>print iNumero<\/pre>\n<p>(sono comandi da dare al prompt, considerando che EMACS, premendo il TAB, pu\u00f2 eseguire il completamento automatico, riconoscendo funzioni e variabili) in modo da ottenere:<\/p>\n<pre>(gdb) print iNumero\n$1 = 0<\/pre>\n<p>o in modo permanente, ad esempio:<\/p>\n<pre>display iNumero<\/pre>\n<p>ottenendo:<\/p>\n<pre>(gdb) display iNumero\n1: iNumero = 0<\/pre>\n<p>ora possiamo passare all&#8217;istruzione successiva con il Next (n + INVIO) e vedere come EMACS sposta la freccia &#8220;&gt;&#8221; di esecuzione alla riga successiva; premendo INVIO si ripete l&#8217;ultimo comando (Next, nel nostro caso) e si pu\u00f2 vedere come varia la variabile quando superiamo la funzione &#8220;sscanf()&#8221;.<\/p>\n<p>Se ci fosse stata una funzione e volevamo entrare dentro al codice di quest&#8217;ultima, anzich\u00e9 &#8220;n&#8221; dovevamo usare &#8220;s&#8221; (Step).<\/p>\n<p>Con &#8220;c&#8221; (Continue) si continua l&#8217;esecuzione del programma fino all&#8217;istruzione successiva.<\/p>\n<p>Con il comando &#8220;delete&#8221; cancelliamo tutti i breakpoints, mentre con &#8220;undisplay&#8221; tutte le variabili automaticamente monitorate.<\/p>\n<p>Un sommario delle parole chiave di GDB puoi trovarlo qui:<br \/>\n<a title=\"GDB - Parole Chiave\" href=\"http:\/\/refcards.com\/docs\/peschr\/gdb\/gdb-refcard-a4.pdf\" target=\"_blank\" rel=\"noopener\"> http:\/\/refcards.com\/docs\/peschr\/gdb\/gdb-refcard-a4.pdf<\/a><\/p>\n<p>Per dimostrare quanto \u00e8 potente GDB operiamo una modifica al sorgente:<\/p>\n<pre>\/* Il classico Hello World ! *\/\n\n#include &lt;stdio.h&gt;\n\nint main (int argc, char** argv) {\n  int\u00a0\u00a0\u00a0 iNumero = 0;\n\n  printf(\"Hello World !\\n\");\n\n  if (argc &gt; 1) {\n    sscanf(argv[1], \"%d\", &amp;iNumero);\n    printf(\"Numero Convertito: %d\\n\", iNumero);\n\n    for (int i = iNumero; i &gt; 0; i--) {\n      printf(\"Countdown: %d\\n\", i);\n    }\n  }\n\n  return 0;\n}<\/pre>\n<p>Cancelliamo tutti i breakpoints con &#8220;delete&#8221; (con &#8220;info b&#8221; otteniamo una lista di quelli attivi) e ne aggiungiamo uno realmente utile:<\/p>\n<pre>break main.cpp:15 if i == 80<\/pre>\n<p>S\u00ec, hai capito bene, questo ferma l&#8217;esecuzione del ciclo nel momento in cui la variabile &#8220;i&#8221; raggiunge il valore &#8220;80&#8221;. Ma quanto \u00e8 utile ???<\/p>\n<p>E poi che non ho mai provato ad usare tutto il resto, ma fare le cose &#8220;a printf&#8221; \u00e8 una pazzia &#8230;<\/p>\n<p>Infine, per uscire da GDB usare il comando &#8220;q&#8221; (\u00e8 indispensabile, altrimenti EMACS si incazza).<\/p>\n<p>Per uscire da EMACS usare &#8220;CTRL+x CTRL+c&#8221;. Se ci sono dei buffers aperti e si desidera chiuderli, usare &#8220;CTRL+x k&#8221;.<\/p>\n<p>Un&#8217;altra cosa che non sto qui a spiegare ma vale senz&#8217;altro la pena guardare \u00e8 il sistema EDIFF, simile a quello dell&#8217;RCS, ma che oltre ad analizzare le differenze tra due sorgenti, consente anche di &#8220;allinearli&#8221; (cio\u00e8 trasferire le differenze riscontrate da una parte all&#8217;altra) in modo che oserei definire &#8220;intelligente&#8221; (lo trovi nel menu &#8220;F10 t 1&#8221;).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Da anni uso l&#8217;ambiente di sviluppo in oggetto per fare i miei &#8220;programmini&#8221;.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[57,25,6],"tags":[76,81,74,75,77,82,72,73,79,80,78],"class_list":["post-91","post","type-post","status-publish","format-standard","hentry","category-development","category-operating-system","category-software","tag-c","tag-ediff","tag-emacs","tag-fltk","tag-gdb","tag-makefile","tag-mingw","tag-msys","tag-rcs","tag-revision-control-system","tag-udc"],"_links":{"self":[{"href":"https:\/\/www.budus.it\/Blog\/wp-json\/wp\/v2\/posts\/91","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.budus.it\/Blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.budus.it\/Blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.budus.it\/Blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.budus.it\/Blog\/wp-json\/wp\/v2\/comments?post=91"}],"version-history":[{"count":13,"href":"https:\/\/www.budus.it\/Blog\/wp-json\/wp\/v2\/posts\/91\/revisions"}],"predecessor-version":[{"id":1349,"href":"https:\/\/www.budus.it\/Blog\/wp-json\/wp\/v2\/posts\/91\/revisions\/1349"}],"wp:attachment":[{"href":"https:\/\/www.budus.it\/Blog\/wp-json\/wp\/v2\/media?parent=91"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.budus.it\/Blog\/wp-json\/wp\/v2\/categories?post=91"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.budus.it\/Blog\/wp-json\/wp\/v2\/tags?post=91"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}