<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9"> <TITLE>Building and Installing Software Packages for Linux: Quarto esempio: Hearts</TITLE> <LINK HREF="Software-Building-HOWTO-13.html" REL=next> <LINK HREF="Software-Building-HOWTO-11.html" REL=previous> <LINK HREF="Software-Building-HOWTO.html#toc12" REL=contents> </HEAD> <BODY> <A HREF="Software-Building-HOWTO-13.html">Avanti</A> <A HREF="Software-Building-HOWTO-11.html">Indietro</A> <A HREF="Software-Building-HOWTO.html#toc12">Indice</A> <HR> <H2><A NAME="s12">12. Quarto esempio: Hearts</A></H2> <P> <P>Ecco il vecchio canuto gioco Hearts, scritto per i sistemi UNIX da Bob Ankeney negli anni '80, rivisto nel 1992 da Mike Yang, ed attualmente mantenuto da <A HREF="mailto:badger@phylo.life.uiuc.edu">Jonathan Badger</A>. Il suo predecessore era un ancor più vecchio programma Pascal di Don Backus della Oregon Software, poi aggiornato da Jeff Hemmerling. Originariamente pensato come client per più giocatori, funziona bene anche per un solo giocatore contro avversari gestiti dal computer. La grafica è bella, benché il gioco manchi di caratteristiche più sofisticate e i giocatori computerizzati non siano molto forti. Nonostante tutto, sembra essere il solo Hearts decente disponibile per macchine UNIX e Linux ancora oggi. <P>A causa della sua stirpe ed età, questo pacchetto è particolarmente difficile da compilare su di un sistema Linux. Richiede la soluzione di una lunga e sconcertante serie di puzzle. È un esercizio di pazienza e determinazione. <P><EM>Prima di iniziare, accertatevi di avere le librerie <CODE>motif</CODE> o le <CODE>lesstif</CODE> installate.</EM> <P> <UL> <LI><B></B></LI> </UL> <P><B>xmkmf</B> <P><B>make</B> <P> <BLOCKQUOTE><CODE> <PRE> client.c: In function `read_card': client.c:430: `_tty' undeclared (first use in this function) client.c:430: (Each undeclared identifier is reported only once client.c:430: for each function it appears in.) client.c: In function `scan': client.c:685: `_tty' undeclared (first use in this function) make: *** [client.o] Error 1 </PRE> </CODE></BLOCKQUOTE> <P> <P>Questi sono i colpevoli nel file <CODE>client.c</CODE>: <P> <BLOCKQUOTE><CODE> <PRE> #ifndef SYSV (buf[2] != _tty.sg_erase) && (buf[2] != _tty.sg_kill)) { #else (buf[2] != CERASE) && (buf[2] != CKILL)) { #endif </PRE> </CODE></BLOCKQUOTE> <P> <P> <P> <P> <UL> <LI><B></B></LI> </UL> In <CODE>client.c</CODE>, aggiungiamo <BLOCKQUOTE><CODE> <PRE> #define SYSV </PRE> </CODE></BLOCKQUOTE> alla linea 39. Ciò bypasserà il riferimento a <EM>_tty</EM>. <P><B>make</B> <P> <BLOCKQUOTE><CODE> <PRE> client.c:41: sys/termio.h: No such file or directory make: *** [client.o] Error 1 </PRE> </CODE></BLOCKQUOTE> <P> <P> <UL> <LI><B></B></LI> </UL> <P>Il file include <CODE>termio.h</CODE> è nella directory <CODE>/usr/include</CODE> su di un sistema Linux, invece che nella <CODE>/usr/include/sys</CODE>, come era sulle vecchie macchine UNIX. Perciò, cambiamo la linea 41 di <CODE>client.c</CODE> da <BLOCKQUOTE><CODE> <PRE> #include <sys/termio.h> </PRE> </CODE></BLOCKQUOTE> a <BLOCKQUOTE><CODE> <PRE> #include <termio.h> </PRE> </CODE></BLOCKQUOTE> <P><B>make</B> <P> <BLOCKQUOTE><CODE> <PRE> gcc -o hearts -g -L/usr/X11R6/lib client.o hearts.o select.o connect.o sockio.o start_dist.o -lcurses -ltermlib /usr/bin/ld: cannot open -ltermlib: No such file or directory collect2: ld returned 1 exit status make: *** [hearts] Error 1 </PRE> </CODE></BLOCKQUOTE> <P> <P> <P> <UL> <LI><B></B></LI> </UL> <P>Le moderne distribuzioni Linux usano il database <EM>terminfo</EM> e/o <EM>termcap</EM>, piuttosto che l'obsoleto <EM>termlib</EM>. <P>Editiamo il <CODE>Makefile</CODE>. <P>Linea 655: <BLOCKQUOTE><CODE> <PRE> CURSES_LIBRARIES = -lcurses -ltermlib </PRE> </CODE></BLOCKQUOTE> <P>cambiamola in: <BLOCKQUOTE><CODE> <PRE> CURSES_LIBRARIES = -lcurses -ltermcap </PRE> </CODE></BLOCKQUOTE> <P> <P><B>make</B> <P> <BLOCKQUOTE><CODE> <PRE> gcc -o xmhearts -g -L/usr/X11R6/lib xmclient.o hearts.o select.o connect.o sockio.o start_dist.o gfx.o -lXm_s -lXt -lSM -lICE -lXext -lX11 -lPW /usr/bin/ld: cannot open -lXm_s: No such file or directory collect2: ld returned 1 exit status </PRE> </CODE></BLOCKQUOTE> <P> <P> <P> <UL> <LI><B></B></LI> </UL> <P>La principale libreria <EM>lesstif</EM> è <CODE>libXm</CODE>, piuttosto che <CODE>libXm_s</CODE>. Quindi, editiamo il <CODE>Makefile</CODE>. <P>Nella linea 653: <BLOCKQUOTE><CODE> <PRE> XMLIB = -lXm_s $(XTOOLLIB) $(XLIB) -lPW </PRE> </CODE></BLOCKQUOTE> <P>cambia in: <BLOCKQUOTE><CODE> <PRE> XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPW </PRE> </CODE></BLOCKQUOTE> <P> <P><B>make</B> <P> <BLOCKQUOTE><CODE> <PRE> gcc -o xmhearts -g -L/usr/X11R6/lib xmclient.o hearts.o select.o connect.o sockio.o start_dist.o gfx.o -lXm -lXt -lSM -lICE -lXext -lX11 -lPW /usr/bin/ld: cannot open -lPW: No such file or directory collect2: ld returned 1 exit status make: *** [xmhearts] Error 1 </PRE> </CODE></BLOCKQUOTE> <P> <P> <P> <UL> <LI><B></B></LI> </UL> <P>Raduniamo i soliti sospetti. <P>Non c'è nessuna libreria <CODE>PW</CODE>. Editiamo il <CODE>Makefile</CODE>. <P>Linea 653: <BLOCKQUOTE><CODE> <PRE> XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPW </PRE> </CODE></BLOCKQUOTE> <P>cambia in: <BLOCKQUOTE><CODE> <PRE> XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPEX5 </PRE> </CODE></BLOCKQUOTE> (La libreria <CODE>PEX5</CODE> è quella più simile alla <CODE>PW</CODE>.) <P> <P> <P><B>make</B> <P> <P> <BLOCKQUOTE><CODE> <PRE> rm -f xmhearts gcc -o xmhearts -g -L/usr/X11R6/lib xmclient.o hearts.o select.o connect.o sockio.o start_dist.o gfx.o -lXm -lXt -lSM -lICE -lXext -lX11 -lPEX5 </PRE> </CODE></BLOCKQUOTE> <P>Il <CODE>make</CODE> finalmente funziona (hurra!) <P> <P> <P> <UL> <LI><B></B></LI> </UL> <P><EM>Installazione:</EM> <P>Come root, <P> <BLOCKQUOTE><CODE> <PRE> [root@localhost hearts]# make install install -c -s hearts /usr/X11R6/bin/hearts install -c -s xmhearts /usr/X11R6/bin/xmhearts install -c -s xawhearts /usr/X11R6/bin/xawhearts install in . done </PRE> </CODE></BLOCKQUOTE> <P> <P> <P> <P> <P> <UL> <LI><B></B></LI> </UL> <P><EM>Esecuzione di prova:</EM> <P><B>rehash</B> <P>(Stiamo eseguendo la shell <CODE>tcsh</CODE>.) <P><B>xmhearts</B> <P> <BLOCKQUOTE><CODE> <PRE> localhost:~/% xmhearts Can't invoke distributor! </PRE> </CODE></BLOCKQUOTE> <P> <P> <P> <UL> <LI><B></B></LI> </UL> <P>Dal file <CODE>README</CODE> nel pacchetto <CODE>hearts</CODE>: <P> <BLOCKQUOTE><CODE> <PRE> Put heartsd, hearts_dist, and hearts.instr in the HEARTSLIB directory defined in local.h and make them world-accessible. </PRE> </CODE></BLOCKQUOTE> (Traducendo: Mettete Heartsd, hearts_dist, e hearts.instr nella directory HEARTSLIB definita in local.h e rendeteli accessibili a chiunque) <P> <P>Dal file <CODE>local.h</CODE>: <P> <BLOCKQUOTE><CODE> <PRE> /* where the distributor, dealer and instructions live */ #define HEARTSLIB "/usr/local/lib/hearts" </PRE> </CODE></BLOCKQUOTE> <P>Questo è un classico caso: RTFM (leggete il fottuto manuale). <P> <P>Come <EM>root</EM>, <P><B>cd /usr/local/lib</B> <P><B>mkdir hearts</B> <P><B>cd !$</B> <P>Copiamo i file di <CODE>distributor</CODE> in questa directory. <P><B>cp /home/username/hearts/heartsd .</B> <P><B>cp /home/username/hearts/hearts_dist .</B> <P><B>cp /home/username/hearts/hearts.instr .</B> <P> <P> <P> <UL> <LI><B></B></LI> </UL> <P><EM>Lanciamo un'altra esecuzione di prova.</EM> <P><B>xmhearts</B> <P>Qualche volta funziona, ma il più delle volte si pianta con un messaggio <CODE>dealer died!</CODE>. <P> <P> <P> <UL> <LI><B></B></LI> </UL> <P>Il "distributor" e il "dealer" esaminano le porte hardware. Dovremmo perciò sospettare che quei programmi abbiano bisogno dei privilegi di root. <P>Proviamo, come <EM>root</EM>, <P><B>chmod u+s /usr/local/lib/heartsd</B> <P><B>chmod u+s /usr/local/lib/hearts_dist</B> <P>(Osserviamo che, come discusso precedentemente, i binari <EM>suid</EM> possono creare dei buchi di sicurezza.) <P><B>xmhearts</B> <P> <P><EM>Alla fine funziona!</EM> <P> <P><CODE><EM>Hearts</EM> è disponibile da <A HREF="ftp://metalab.unc.edu/pub/Linux/games/multiplayer/hearts.tgz">Sunsite</A>.</CODE> <P> <P> <HR> <A HREF="Software-Building-HOWTO-13.html">Avanti</A> <A HREF="Software-Building-HOWTO-11.html">Indietro</A> <A HREF="Software-Building-HOWTO.html#toc12">Indice</A> </BODY> </HTML>