File: GCC-HOWTO

package info (click to toggle)
doc-linux-it 2000.01-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 8,136 kB
  • ctags: 19
  • sloc: perl: 249; makefile: 50; sh: 42
file content (2178 lines) | stat: -rw-r--r-- 73,697 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
  The Linux GCC HOWTO
  Daniel Barlow (dan@detached.demon.co.uk)
  v1.17, 28 Febbraio 1996

  Questo documento tratta la configurazione del compilatore C GNU e
  delle librerie di sviluppo sotto Linux, e fornisce una panoramica
  sulla compilazione, il link, l'esecuzione e la correzione (debug) dei
  programmi. La maggior parte del materiale contenuto nel documento 
  stato preso dal GCC-FAQ di Mitch D'Souza, che sostituisce, o dall'ELF-
  HOWTO (per la traduzione in italiano vedi [1]). Quella che state
  leggendo  la prima versione rilasciata pubblicamente (nonostante il
  numero). Ogni feedback  benvenuto.  Revisione e manutenzione della
  traduzione italiana: Andrea Girotto (andrea.girotto@usa.net)

  1.  Preliminari

  1.1.  Confronto tra ELF e a.out

  Lo sviluppo di Linux si trova attualmente in uno stato di continua
  evoluzione. Brevemente, esistono due formati di file binari che Linux
   in grado di eseguire, ed a seconda di come  stato costruito, un
  sistema potrebbe usare uno o l'altro dei due. Leggendo questo HOWTO si
  scoprir quale.



  Per riconoscere il tipo di un binario  possibile utilizzare l'utility
  file (ad esempio: file /bin/bash). Per un programma ELF, dar una
  risposta contenente ELF; per un programma a.out la risposta sar
  qualcosa del tipo Linux/i386.

  Le differenze tra ELF e a.out sono descritte ampiamente in questo
  documento. ELF  il formato pi recente, generalmente ritenuto il
  migliore.


  1.2.  Questioni amministrative

  Informazioni riguardo al copyright si trovano alla fine di questo
  documento, insieme a dovute avvertenze relative a certe stupide
  domande poste su Usenet, che, segnalando problemi inesistenti,
  rivelano un'ignoranza del linguaggio C.


  1.3.  Tipografia

  La versione in formato Postscipt, dvi, o html, di questo documento ha
  una maggiore variet tipografica rispetto a quella in solo testo. In
  particolare, i nomi di file, i comandi, l'output dei comandi e gli
  stralci di codice sorgente sono impostati con un carattere tipo
  macchina da scrivere, come pure sono state messe in evidenza le
  "variabili" ed altre parti che dovevano essere enfatizzate.

  Inoltre,  presente un utile indice. In dvi o postscript, la
  numerazione dell'indice corrisponde a quella dei paragrafi. In HTML si
  tratta di numeri assegnati sequenzialmente che rimandano ad altre
  parti del testo. Nella versione a solo testo, si tratta solo di
  numeri.  Si consiglia una versione avanzata piuttosto che quella in
  modalit testo.

  Negli esempi viene utilizzata la sintassi dell'interprete dei comandi
  (shell) Bourne (al posto di quella C). Gli utenti di C-shell potranno
  utilizzare il comando:



  % setenv FOO bar




  al posto di:



       $ FOO=bar; export FOO




  Se il prompt mostrato  # invece di $, il comando indicato
  probabilmente funzioner solo se digitato come root. Naturalmente, non
  si assumere alcuna responsabilit per qualsiasi cosa accada al sistema
  nell'utilizzo di questi esempi.


  2.  Dove ottenere quello che serve.

  2.1.  Questo documento.

  Questo documento fa parte della serie dei Linux HOWTO, pertanto si pu
  ottenere da tutti gli archivi di Linux HOWTO, come
  http://sunsite.unc.edu/pub/linux/docs/HOWTO/ (le traduzioni italiane
  sono disponibili presso [2]). La versione HTML in inglese pu anche
  essere trovata (probabilmente leggermente pi aggiornata) su
  http://ftp.linux.org.uk/~barlow/howto/gcc-howto.html (traduzione
  italiana [3]).


  2.2.  Ulteriore documentazione.

  La documentazione ufficiale di gcc si trova nella distribuzione
  sorgente (si veda sotto) sotto forma di file texinfo, e come file
  .info. Se si dispone di una connessione di rete veloce, un cd-rom o
  una buona dose di pazienza,  possibile eseguirne l'untar e copiare le
  parti rilevanti in /usr/info. In caso contrario, possono essere
  trovati presso ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/, ma non
  necessariamente si tratter della versione pi recente.



  Esistono due sorgenti di documentazione per libc. La GNU libc contiene
  dei file info che descrivono piuttosto accuratamente la libc Linux,
  fatta eccezione per stdio. Inoltre, le pagine di manuale dell'archivio
  ftp://sunsite.unc.edu/pub/Linux/docs/ sono state scritte per Linux e
  descrivono numerose chiamate di sistema (sezione 2) e funzioni libc
  (sezione 3).


  2.3.  GCC

  La distribuzione ufficiale del GCC Linux pu sempre essere trovata in
  formato binario (gi compilato) all'indirizzo
  ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/. Nel momento in cui
  viene scritto questo documento, la versione pi recente  la 2.7.2
  (gcc-2.7.2.bin.tar.gz).

   possibile ottenere la distribuzione sorgente pi recente di GCC
  fornita dalla Free Software Foundation dagli archivi
  ftp://prep.ai.mit.edu/pub/gnu/. I gestori del GCC Linux hanno reso
  molto semplice la compilazione dell'ultima versione - il programma di
  configurazione (configure) dovrebbe impostare tutto da solo. Si
  verifichi anche l'eventuale presenza di patch da applicare presso:
  ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/.

  Per compilare qualcosa di non banale (ma anche alcune cose banali)
  sar necessario possedere anche quanto descritto nel paragrafo che
  segue.


  2.4.  Libreria C e header file

  Quello che si desidera a questo punto dipende da due fattori:


  1. se il proprio sistema  ELF oppure a.out

  2. quale dei due si desidera avere.

  Se si sta passando da libc 4 a libc 5, si raccomanda di leggere l'ELF-
  HOWTO, rintracciabile pi o meno nello stesso luogo in cui  stato
  trovato questo documento (traduzione italiana [1]).

  Da ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/ sono disponibili:


     libc-5.2.18.bin.tar.gz
        Immagini di librerie condivise ELF, librerie statiche e file
        include per le librerie C e matematiche.


     libc-5.2.18.tar.gz
        Sorgenti per quanto descritto sopra. Sar necessario anche il
        pacchetto .bin. per gli header file. Se si  indecisi tra
        compilarsi in proprio la libreria C o utilizzare il formato
        binario, la scelta migliore consiste nell'usare il codice gi
        compilato. Nel caso in cui si desideri il supporto NIS o per le
        shadow password di dovr comunque gestirli in prima persona.


     libc-4.7.5.bin.tar.gz
        Immagini di libreria condivisa a.out e librerie statiche per la
        versione 4.7.5 della libreria C e simili.  Questo  stato
        studiato per coesistere con il pacchetto libc 5 sopra
        menzionato, ma  necessario solo se si desidera continuare a
        utilizzare o sviluppare programmi in formato a.out.


  2.5.



  Strumenti associati (as, ld, ar, strings, ecc.)

  Si possono trovare su ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/,
  come ogni altra cosa sinora descritta. La versione corrente 
  binutils-2.6.0.2.bin.tar.gz.

  Le binutils sono disponibili unicamente in ELF, la versione corrente
  di libc si trova in ELF ed inoltre  meglio utilizzare la versione
  a.out di libc in congiunzione con una ELF. Lo sviluppo della libreria
  C si sta muovendo verso ELF: se non c' un particolare motivo per
  l'utilizzo di a.out, si consiglia di fare altrettanto.





  3.  Installazione e impostazione di GCC

  3.1.


  Versioni GCC

   possibile scoprire quale versione GCC si sta eseguendo digitando gcc
  -v alla richiesta dell'interprete comandi. Si tratta di un metodo
  piuttosto affidabile anche per scoprire se la propria impostazione 
  ELF o a.out. Il risultato potrebbe essere:



       $ gcc -v
       Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
       gcc version 2.7.2




  Le cose da notare sono:


     i486
        Indica che il gcc  stato compilato per un processore 486 -
        altre possibilit sono 386 o 586. Tutti i processori possono
        eseguire il codice compilato per ciascuna delle altre versioni;
        la differenza consiste nell'ottimizzazione che non ha effetti
        sulle prestazioni in un 386, ma rende il codice eseguibile
        leggermente pi grande.


     box
        Non  affatto importante, potrebbe esserci qualcosa di diverso
        (come slackware o debian) o anche nulla (in tal caso, il nome di
        directory completa sar i486-linux). Se si esegue personalmente
        la compilazione di gcc,  possibile impostare questa
        caratteristica al momento della compilazione, a fini puramente
        estetici.


     linux
        In alternativa, potrebbe essere linuxelf o linuxaout, il
        significato varia a seconda della versione utilizzata, fatto che
        potrebbe confondere le idee.


        linux
           significa ELF se la versione  la 2.7.0 o seguente,
           altrimenti significa a.out.


        linuxaout
           significa a.out.  stato introdotto quando la definizione di
           linux  stata modificata da a.out in ELF, in modo che non sia
           possibile vedere un gcc linuxaout pi vecchio della versione
           2.7.0.


        linuxelf
            obsoleto. Si tratta generalmente di una versione di gcc
           2.6.3 impostata per produrre eseguibili ELF. Si noti che il
           gcc 2.6.3 contiene degli errori nella produzione di codice
           per ELF - si consiglia un aggiornamento.

     2.7.2
        numero della versione.

  In conclusione, si tratta di gcc 2.7.2 che produce del codice ELF.


  3.2.  Dov' finito?

  Se gcc  stato installato senza prestare attenzione, oppure se  stato
  ottenuto come parte di una distribuzione, potrebbe essere necessario
  scoprire dove si trova all'interno del filesystem. Le parti chiave
  sono:


    /usr/lib/gcc-lib/destinazione/versione/ (e sottodirectory) posto in
     cui si trova la maggior parte del compilatore, i programmi
     eseguibili che effettuano la compilazione, alcune librerie e file
     include specifici per la versione che si sta utilizzando.

    /usr/bin/gcc driver del compilatore - la parte che si esegue dalla
     riga di comando. Pu essere utilizzato con diverse versioni di gcc,
     a patto che siano state installate pi directory di compilatore
     (come descritto sopra). Per scoprire la versione predefinita,
     digitare gcc -v. Per forzare un'altra versione, digitare gcc -V
     versione. Ad esempio:



       # gcc -v
       Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
       gcc version 2.7.2
       # gcc -V 2.6.3 -v
       Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.6.3/specs
       gcc driver version 2.7.2 executing gcc version 2.6.3





    /usr/destinazione/(bin|lib|include)/. Se sono stati installati pi
     destinazioni (target) (ad esempio, a.out ed elf, o un cross
     compilatore di qualche tipo), le librerie, le binutils (come as, ld
     o altri) e gli header file per destinazioni non native possono
     essere trovati in questa posizione. Se  stato installato un solo
     tipo di gcc, diverse parti di esso sono poste o in questa directory
     o, alternativamente, in /usr/(bin|lib|include).

    /lib/, /usr/lib e altre sono directory di libreria per il sistema
     nativo. Sar anche necessaria la directory /lib/cpp per molte
     applicazioni (ad esempio X ne fa un grande utilizzo) -  possibile
     copiarla da /usr/lib/gcc-lib/destinazione/versione/ o creare un
     collegamento (link) simbolico.



  3.3.  Dove si trovano gli header file?

  Indipendentemente dalla posizione in cui sono stati installati i
  propri, sotto /usr/local/include, esistono tre sorgenti principali
  degli header file in Linux:


    la maggior parte di /usr/include/ e relative subdirectory sono
     sostituiti con il pacchetto binario di libc da H. J. Lu.  In tali
     posizioni si potrebbero anche trovare file da altri sorgenti
     (librerie curses e dbm, ad esempio) specialmente se si sta
     utilizzando la distribuzione libc pi recente (che non contiene
     curses o dbm, come invece accadeva nelle pi vecchie).




    /usr/include/linux e /usr/include/asm (per i file <linux/*.h> e
     <asm/*.h>) dovrebbero essere link simbolici alle directory
     linux/include/linux e linux/include/asm nella distribuzione
     sorgente del kernel.  necessario installarli se si pensa di
     eseguire lo sviluppo di un qualsiasi programma non banale; non
     servono solo per la compilazione del kernel.

     Potrebbe essere anche necessario eseguire il make config nelle
     directory del kernel dopo aver scaricato i sorgenti. Molti file
     dipendono da <linux/autoconf.h> che potrebbe non esistere, e in
     alcune versioni di kernel, asm  un link simbolico che viene creato
     al momento del make config.  Pertanto, se si scaricano i sorgenti
     del kernel sotto /usr/src/linux:



       $ cd /usr/src/linux
       $ su
       # make config
       [rispondere alle domande. A meno che non si abbia intenzione di
        proseguire con la compilazione del kernel, la risposta non ha
        molta importanza]
       # cd /usr/include
       # ln -s ../src/linux/include/linux .
       # ln -s ../src/linux/include/asm .










    File come <float.h>, <limits.h>, <varargs.h>, <stdarg.h> e
     <stddef.h> variano a seconda della versione del compilatore,
     pertanto si trovano in /usr/lib/gcc-lib/i486-box-
     linux/2.7.2/include/ e posizioni simili.


  3.4.  Compilazione di cross compilatori

  3.4.1.  Linux come piattaforma di destinazione

  Supponendo di aver ottenuto il codice sorgente per gcc, solitamente 
  sufficiente seguire le istruzioni contenute nel file INSTALL di GCC.
  Un comando configure -target=i486-linux -host=XXX sulla piattaforma
  XXX seguito da un make dovrebbe funzionare. Si noti che saranno
  necessari gli include di Linux, gli include del kernel e sar
  necessario eseguire anche la compilazione del cross assembler e del
  cross linker dai sorgenti in
  ftp://tsx-11.mit.edu/pub/linux/packages/GCC/.


  3.4.1.1.  Linux come piattaforma sorgente, MSDOS come destinazione

  Apparentemente dovrebbe essere possibile utilizzando il pacchetto
  "emx" o l'extender "go". Si invita a dare un'occhiata a
  ftp://sunsite.unc.edu/pub/Linux/devel/msdos.
  L'autore, non ha ancora verificato le funzionalit e pertanto non pu
  dare alcuna garanzia in merito.


  4.  Il porting e la compilazione

  4.1.  Simboli definiti automaticamente

   possibile elencare i simboli definiti automaticamente dalla propria
  versione di gcc eseguendolo con l'opzione -v. Ad esempio:



       $ echo 'main(){printf("hello world\n");}' | gcc -E -v -
       Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
       gcc version 2.7.2
       /usr/lib/gcc-lib/i486-box-linux/2.7.2/cpp -lang-c -v -undef
       -D__GNUC__=2 -D__GNUC_MINOR__=7 -D__ELF__ -Dunix -Di386 -Dlinux
       -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__i386
       -D__linux -Asystem(unix) -Asystem(posix) -Acpu(i386)
       -Amachine(i386) -D__i486__ -




  Se si sta scrivendo del codice che utilizza delle caratteristiche
  specifiche per Linux,  una buona idea includere le parti non
  portabili in



       #ifdef __linux__
       /* ... altro codice ... */
       #endif /* linux */




  Si utilizzi __linux__ per questo scopo, non semplicemente linux.
  Sebbene anche il secondo sia definito, non  conforme a POSIX.


  4.2.  Chiamata del compilatore

  La documentazione per le opzioni del compilatore  rappresentata dalla
  info page di gcc (in Emacs, si utilizzi C-h i quindi si selezioni la
  voce 'gcc'). Il proprio distributore potrebbe non aver incluso questa
  parte nel sistema, o la versione che si possiede potrebbe essere
  vecchia; la cosa migliore da fare in questo caso consiste nello
  scaricare l'archivio sorgente gcc da ftp://prep.ai.mit.edu/pub/gnu o
  da uno dei suoi siti mirror.

  La pagina di manuale gcc (gcc.1) di solito  obsoleta. Tentando di
  leggerla si trover questo avvertimento.


  4.2.1.

  Opzioni del compilatore

  L'output di gcc pu essere ottimizzato aggiungendo -On alla sua riga
  di comando, dove n rappresenta un intero opzionale. I valori
  significativi di n, ed il loro esatto effetto, variano a seconda della
  versione; tipicamente vanno da 0 (nessuna ottimizzazione) a 2 (molte
  ottimizzazioni) a 3 (moltissime ottimizzazioni).

  Internamente, gcc le traduce in una serie di opzioni -f e -m. 
  possibile vedere esattamente quale livello -O si lega a ogni opzione
  eseguendo gcc -v -Q (Q  un'opzione non documentata).  Ad esempio, -O2
  sul sistema dell'autore produce questo risultato:



       enabled:        -fdefer-pop -fcse-follow-jumps -fcse-skip-blocks
                   -fexpensive-optimizations
                   -fthread-jumps -fpeephole -fforce-mem -ffunction-cse -finline
                   -fcaller-saves -fpcc-struct-return -frerun-cse-after-loop
                   -fcommon -fgnu-linker -m80387 -mhard-float -mno-soft-float
                   -mno-386 -m486 -mieee-fp -mfp-ret-in-387




  L'utilizzo di un livello di ottimizzazione maggiore di quanto previsto
  per il proprio compilatore (ad esempio, -O6) avr lo stesso risultato
  che utilizzare il livello pi alto che  in grado di supportare.
  Tuttavia, la distribuzione di codice impostato per la compilazione in
  questo modo non  una buona idea - se in versioni future saranno
  incorporate ulteriori ottimizzazioni, potrebbe accadere che
  interrompano il proprio codice.


  Gli utenti di gcc dalla versione 2.7.0 fino alla 2.7.2 dovrebbero
  notare che esiste un errore in -O2. In particolare, '-fstrenght-
  reduction' non funziona.  disponibile una patch per risolvere questo
  problema, che necessita della ricompilazione del gcc, altrimenti 
  sufficiente assicurarsi di usare sempre l'opzione -fno-strength-
  reduce.


  4.2.1.1.  Opzioni specifiche per il processore

  Esistono altre opzioni -m che non sono attivate da nessun -O, e si
  dimostrano utili in molti casi. Le principali sono -m386 e -m486, che
  indicano a gcc di favorire rispettivamente 386 o 486. Il codice
  compilato con una di queste due opzioni funzioner anche su macchine
  dell'altro tipo; il codice 486  pi voluminoso, ma non  pi lento se
  eseguito su 386.

  Attualmente non esiste un'opzione -mpentium o -m586.  Linus suggerisce
  di utilizzare -m486 -malign-loops=2 -malign-jumps=2 -malign-
  functions=2, per ottenere l'ottimizzazione del codice 486 ma senza i
  salti necessari per l'allineamento (di cui il pentium non ha bisogno).
  Michael Meissner (di Cygnus) dice:


       La mia impressione  che -mno-strength-reduce produca anche
       un codice pi veloce sull'x86 (si noti che non mi sto rifer
       endo all'errore relativo all'opzione '-fstrength-reduction':
       altra questione). Ci  dovuto alla carenza di registri
       dell'x86 (ed il metodo di GCC di raggruppare i registri in
       registri sparsi piuttosto che in altri registri non aiuta
       molto). 'strenght-reduce' ha come effetto l'utilizzo di reg
       istri addizionali per sostituire moltiplicazioni con
       addizioni.  Sospetto anche che -fcaller-saves possa causare
       una perdita di prestazioni.



       Un'altra considerazione consiste nel fatto che -fomit-frame-
       pointer possa o meno rappresentare un vantaggio. Da un lato,
       rende disponibile un altro registro per l'uso; tuttavia, il
  modo in cui x86 codifica il suo set di istruzioni comporta
  che gli indirizzi relativi di stack occupino pi spazio
  rispetto agli indirizzi relativi di frame; di conseguenza,
  sar disponibile ai programmi una quantit (leggermente)
  inferiore di Icache.  Inoltre, -fomit-frame-pointer implica
  il continuo aggiustamento del puntatore allo stack da parte
  del compilatore, dopo ogni chiamata, quando, con un frame,
  pu lasciare che lo stack esegua un accumulo per alcune
  chiamate.


  L'ultima parola su questo argomento viene ancora da Linus:


       Se si desidera ottenere prestazioni ottimali, non credete
       alle mie parole, effettuate delle prove. Esistono molte
       opzioni nel compilatore gcc, e pu darsi che un insieme par
       ticolare dia l'ottimizzazione migliore per la propria
       impostazione.



  4.2.2.  Internal compiler error: cc1 got fatal signal 11

  (Ovvero: "Errore interno del compilatore: cc1 ha ricevuto il segnale
  fatale 11").

  Il segnale 11  SIGSEGV, o 'segmentation violation'.  Solitamente
  significa che il programma ha confuso i puntatori e ha tentato di
  scrivere su una porzione di memoria che non possedeva. Potrebbe
  trattarsi di un errore di gcc.

  Tuttavia, gcc  ben verificato ed affidabile, nella maggior parte dei
  casi. Utilizza anche un gran numero di strutture dati complesse, e una
  grande quantit di puntatori. In breve,  il miglior tester di RAM tra
  quelli disponibili comunemente. Se non  possibile replicare l'errore
  - il sistema non si ferma nello stesso punto quando si riavvia la
  compilazione - molto probabilmente si tratta di un problema legato
  all'hardware (CPU, memoria, scheda madre o cache). Non lo si deve
  considerare un errore del compilatore solo perch il proprio computer
  supera i controlli di avvio del sistema o  in grado di eseguire
  Windows o qualunque altro programma; questi 'test' sono comunemente
  ritenuti, a ragione, di nessun valore.  Comunque  sbagliato ritenere
  che si tratti di un errore, perch una compilazione del kernel si
  blocca sempre durante `make zImage' -  logico che ci accada: `make
  zImage' probabilmente compila pi di 200 file. In genere si ricerca un
  bug in un insieme pi piccolo di cos.

  Se  possibile duplicare l'errore, e (ancora meglio) produrre un breve
  programma che lo dimostra,  possibile inviarlo come report di errori
  all'FSF, o alla mailing list di linux-gcc. Si faccia riferimento alla
  documentazione di gcc per i dettagli relativi alle informazioni
  effettivamente necessarie.


  4.3.  Portabilit

   stato detto che, in questi giorni, se non pu essere portato a
  Linux, allora  qualcosa che non vale la pena di possedere. :-)

  In generale, sono necessarie solo piccole modifiche per ottenere la
  conformit POSIX al 100% di Linux.  Sarebbe anche molto utile
  restituire agli autori ogni modifica al codice in modo che, in futuro,
  si possa ottenere un eseguibile funzionante tramite il solo comando
  'make'.

  4.3.1.  BSD (inclusi bsd_ioctl, demone e <sgtty.h>)

   possibile compilare il proprio programma con -I/usr/include/bsd ed
  eseguire il link con -lbsd (ossia, aggiungere -I/usr/include/bsd a
  CFLAGS e -lbsd alla riga LDFLAGS nel proprio Makefile). Non  pi
  necessario aggiungere -D__USE_BSD_SIGNAL se si desidera un
  comportamento dei segnali di tipo BSD, dal momento che questa
  caratteristica viene ottenuta automaticamente quando si ha
  -I/usr/include/bsd e l'include <signal.h>.


  4.3.2.  SIGIOT , SIGTRAP , SIGSYS  ecc) Segnali 'mancanti' ( SIGBUS ,
  SIGEMT ,

  Linux  conforme a POSIX. Quelli elencati nel seguito sono segnali non
  definiti in POSIX - ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990),
  paragrafo B.3.3.1.1:


       "I segnali SIGBUS, SIGEMT, SIGIOT, SIGTRAP, e SIGSYS sono
       stati omessi da POSIX.1 perch il loro comportamento dipende
       dall'implementazione e non  stato possibile classificarlo
       adeguatamente. Implementazioni conformi potranno contenere
       questi segnali, ma devono documentare le circostanze in cui
       sono rilasciati ed elencare ogni restrizione riguardante il
       loro rilascio."


  Il modo pi economico e scadente di gestire la cosa consiste nel
  ridefinire questi segnali in SIGUNUSED. Il modo corretto consiste
  nell'inserire il codice che li gestisce in appropriati #ifdef



       #ifdef SIGSYS
       /* ... codice SIGSYS non-posix .... */
       #endif





  4.3.3.  Codice K & R

  GCC  un compilatore ANSI; una grande quantit di codice esistente non
   ANSI. Non c' molto da fare per risolvere questo problema, oltre
  all'aggiungere -traditional alle opzioni del compilatore. Si invita a
  consultare l'info page di gcc.

  Si noti che -traditional ha altri effetti oltre a cambiare il
  linguaggio accettato da gcc. Ad esempio, attiva -fwritable-strings,
  che sposta le stringhe costanti nello spazio dati (dallo spazio di
  codice, dove non possono essere scritte).  Questo aumenta
  l'occupazione di memoria del programma.


  4.3.4.  Conflitto dei simboli di preprocessore con prototipi nel
  codice

  Uno dei problemi pi frequenti consiste nel fatto che alcune funzioni
  comuni sono definite come macro negli header file di Linux e il
  preprocessore si rifiuter di eseguire il parsing di definizioni
  prototipo simili. I pi comuni sono atoi() e atol().



  4.3.5.  sprintf()

  Soprattutto quando si esegue il porting da SunOS,  necessario essere
  consapevoli del fatto che sprintf(string, fmt, ...) restituisce un
  puntatore a stringhe, mentre Linux (seguendo ANSI) restituisce il
  numero di caratteri che sono stati messi nella stringa.


  4.3.6.  fcntl  e affini. Quali sono le definizioni di FD_* ?

  Le definizioni si trovano in <sys/time.h>. Se si sta utilizzando
  fcntl, probabilmente si vorr includere anche <unistd.h>.

  In genere, la pagina di manuale di una funzione elenca gli #include
  necessarie nella sua sezione SYNOPSIS.


  4.3.7.  Il timeout di select() .  Programmi in busy-waiting

  Una volta, il parametro timeout di select() era utilizzato a sola
  lettura. Gi allora, le pagine di manuale avvertivano:


       select() dovrebbe probabilmente restituire il tempo rima
       nente dal timeout originale, se esistente, modificando il
       valore del tempo. Questo potr essere implementato in ver
       sioni future del sistema. Pertanto, sarebbe sbagliato
       ritenere che il puntatore al timeout non sar modificato
       dalla chiamata select().


  Ora il futuro  arrivato. Di ritorno da una select(), l'argomento di
  timeout sar impostato al tempo rimanente che si sarebbe atteso se i
  dati non fossero arrivati. Se non  arrivato alcun dato, il valore
  sar zero, e le chiamate future utilizzando la stessa struttura
  timeout eseguiranno immediatamente il return.

  Per rimediare, in caso di errore, si metta il valore di timeout nella
  struttura ogni volta che si chiama select(). Si modifichi il codice
  come:


  ______________________________________________________________________
  struct timeval timeout;
  timeout.tv_sec = 1; timeout.tv_usec = 0;
  while (some_condition)
          select(n,readfds,writefds,exceptfds,&timeout);
  ______________________________________________________________________



  in


  ______________________________________________________________________
  struct timeval timeout;
  while (some_condition) {
          timeout.tv_sec = 1; timeout.tv_usec = 0;
          select(n,readfds,writefds,exceptfds,&timeout);
  }
  ______________________________________________________________________



  Alcune versioni di Mosaic evidenziavano questo problema. La velocit
  dell'animazione del globo rotante era inversamente correlata alla
  velocit con cui i dati giungevano dalla rete!


  4.3.8.  Chiamate di sistema interrotte

  4.3.8.1.  Sintomo

  Quando un programma viene interrotto utilizzando Ctrl-Z e poi viene
  riavviato - o in altre situazioni che generano dei segnali:
  interruzione con Ctrl-C, terminazione di un processo figlio ecc. - si
  ottengono messaggi del tipo "interrupted system call" o "write:
  unknown error".


  4.3.8.2.  Problema

  I sistemi POSIX controllano la presenza di segnali pi frequentemente
  rispetto a sistemi UNIX pi vecchi. Linux pu eseguire dei gestori di
  segnali:


    in modo asincrono (tramite un timer)

    al ritorno da ogni chiamata di sistema

    durante l'esecuzione delle seguenti chiamate di sistema: select(),
     pause(), connect(), accept(), read() su terminali, su socket, su
     pipe o su file in /proc, write() su terminali, su socket, su pipe o
     sulla line printer; open() su FIFO, su PTY o su linee seriali,
     ioctl() su terminali; fcntl() con il comando F_SETLKW; wait4(),
     syslog(), ogni operazione TCP o NFS.

  Per altri sistemi operativi potrebbe essere necessario includere in
  questa lista le chiamate di sistema creat(), close(), getmsg(),
  putmsg(), msgrcv(), msgsnd(), recv(), send(), wait(), waitpid(),
  wait3(), tcdrain(), sigpause(), semop().

  Se un segnale (per il quale il programma ha installato un gestore)
  avviene durante una chiamata di sistema, viene chiamato il gestore.
  Quando il gestore restituisce il controllo (alla chiamata di sistema),
  essa rileva che  stata interrotta e restituisce immediatamente -1 e
  errno = EINTR. Il programma non si aspetta che questo accada, pertanto
  si blocca.

   possibile scegliere tra due alternative, per rimediare.


    Per ogni gestore di segnali che viene installato, aggiungere
     SA_RESTART ai flag sigaction. Per esempio, modificare


     ___________________________________________________________________
     signal (sig_nr, my_signal_handler);
     ___________________________________________________________________



  in








  ______________________________________________________________________
  signal (sig_nr, my_signal_handler);
  { struct sigaction sa;
    sigaction (sig_nr, (struct sigaction *)0, &sa);
  #ifdef SA_RESTART
    sa.sa_flags |= SA_RESTART;
  #endif
  #ifdef SA_INTERRUPT
    sa.sa_flags &= ~ SA_INTERRUPT;
  #endif
    sigaction (sig_nr, &sa, (struct sigaction *)0);
  }
  ______________________________________________________________________



  Si noti che mentre questo viene applicato alla maggior parte delle
  chiamate di sistema,  necessario controllare EINTR personalmente
  riguardo a read(), write(), ioctl(), select(), pause() e connect() .
  Si veda sotto.

    Controllare EINTR esplicitamente.

  Seguono due esempi per read() e ioctl().

  Una parte di codice originale utilizzante read()


  ______________________________________________________________________
  int result;
  while (len > 0) {
          result = read(fd,buffer,len);
          if (result < 0) break;
          buffer += result; len -= result;
  }
  ______________________________________________________________________



  diventa


  ______________________________________________________________________
  int result;
  while (len > 0) {
          result = read(fd,buffer,len);
          if (result < 0) { if (errno != EINTR) break; }
          else { buffer += result; len -= result; }
  }
  ______________________________________________________________________



  e una parte di codice utilizzante ioctl()


  ______________________________________________________________________
      int result;
      result = ioctl(fd,cmd,addr);
  ______________________________________________________________________



  diventa


  ______________________________________________________________________
      int result;
      do { result = ioctl(fd,cmd,addr); }
      while ((result == -1) && (errno == EINTR));
  ______________________________________________________________________



  Si noti che in alcune versioni di Unix BSD il comportamento
  predefinito consiste nel riavviare le chiamate di sistema. Per
  ottenere l'interruzione delle chiamate di sistema  necessario
  utilizzare i flag SV_INTERRUPT o SA_INTERRUPT.


  4.3.9.  Stringhe scrivibili (il programma genera 'segmentation fault'
  in modo casuale)

  GCC ha una visione ottimistica dei suoi utenti, considerando le
  costanti stringa esattamente quello che sono - delle costanti.
  Pertanto, le memorizza nell'area del codice, dove possono essere
  inserite ed estratte dall'immagine di disco del programma (invece di
  occupare uno swapspace). Ne consegue che ogni tentativo di riscriverle
  causer 'segmentation fault'.

  Questo pu causare dei problemi a vecchi programmi che, per esempio
  eseguono una chiamata mktemp() con una stringa costante come
  argomento. mktemp() tenta di riscrivere il suo argomento.

  Per correggere,

    compilare con l'opzione -fwritable-strings, per fare in modo che
     gcc posizioni le costanti nello spazio dati, oppure

    riscrivere le parti che causano dei problemi per allocare una
     stringa non costante ed eseguire la strcpy dei dati in essa prima
     della chiamata.


  4.3.10.  Perch la chiamata execl()  fallisce?

  Probabilmente accade perch viene eseguita in modo errato. Il primo
  argomento per execl  il nome del programma da eseguire.  Il secondo e
  i successivi diventano l'array argv del programma che si sta
  chiamando. Ricordare che: argv[0] viene impostato anche per un
  programma eseguito senza argomenti. Pertanto si dovrebbe scrivere


  ______________________________________________________________________
      execl("/bin/ls","ls",NULL);
  ______________________________________________________________________



  e non solo


  ______________________________________________________________________
      execl("/bin/ls", NULL);
  ______________________________________________________________________



  L'esecuzione del programma senza nessun argomento  interpretata come
  un invito a stampare le sue dipendenze a librerie dinamiche, almeno
  utilizzando a.out. ELF si comporta diversamente.

  (Se si desidera questa informazione di libreria, esistono interfacce
  pi semplici; si veda il paragrafo relativo al caricamento dinamico, o
  la pagina di manuale per ldd).


  5.  Debugging e Profiling

  5.1.  Manutenzione preventiva (lint)

  Non esiste un lint ampiamente utilizzato per Linux, dal momento che la
  maggior parte della gente si accontenta degli avvertimenti che gcc pu
  generare. Probabilmente, quello pi utile  il -Wall opzione che
  significa 'Warnings, all' ma probabilmente ha un maggior valore
  mnemonico, se pensato come qualcosa contro cui si sbatte la testa
  (NdT. "wall" in inglese significa "muro").

  Esiste un lint di dominio pubblico disponibile su
  ftp://larch.lcs.mit.edu/pub/Larch/lclint. Putroppo non sono in grado
  di giudicare la sua validit.


  5.2.  Debugging

  5.2.1.  Come si ottengono le informazioni di debug in un programma?

   necessario compilare ed eseguire il link di tutte le sue parti con
  l'opzione -g, e senza -fomit-frame-pointer. Non  necessario
  ricompilarlo interamente, solo le parti di cui si esegue il debug.

  Nelle configurazioni a.out le librerie condivise sono compilate con
  -fomit-frame-pointer, con la quale gdb non funzioner. Questo perch
  l'opzione -g implica un link statico.

  Se il linker va in errore fornendo un messaggio che indica
  l'impossibilit di trovare libg.a, significa che non si possiede
  /usr/lib/libg.a, che consiste nella speciale libreria C abilitata al
  debugging. Tale libreria pu essere fornita nel pacchetto binario
  libc, oppure (in versioni di libreria C pi recenti) pu essere
  necessario ottenere il codice sorgente libc ed eseguire personalmente
  la compilazione.  Tuttavia,  possibile ottenere sufficienti
  informazioni per la maggior parte degli scopi semplicemente
  sostituendola con un collegamento simbolico con /usr/lib/libc.a.


  5.2.1.1.  Come eliminarle?

  Molto software GNU  impostato affinch la compilazione e il link
  siano eseguite con l'opzione -g, che determina la generazione di
  eseguibili molto voluminosi (e spesso statici). Questa non  una buona
  idea.

  Se il programma possiede uno script di configurazione `autoconf', 
  possibile disabilitare le informazioni di debugging controllando il
  Makefile. Naturalmente, se si sta utilizzando ELF, il link del
  programma viene eseguito in modo dinamico indipendentemente
  dall'impostazione -g, pertanto si pu semplicemente usare strip.


  5.2.2.  Software disponibile

  Molte persone utilizzano gdb, che pu essere ottenuto in forma
  sorgente dai siti di archivio GNU ftp://prep.ai.mit.edu/pub/gnu,
  oppure in formato binario da tsx-11
  (ftp://tsx-11.mit.edu/pub/linux/packages/GCC) o da sunsite. xxgdb  un
  debugger X basato su gdb (ossia,  necessario che sia installato gdb).
   possibile trovare i sorgenti presso
  ftp://ftp.x.org/contrib/xxgdb-1.08.tar.gz.

  Rick Sladkey ha eseguito il porting del debugger UPS. Pu essere
  eseguito anche sotto X, ma a differenza di xxgdb, non  un semplice
  front end X per un debugger basato su testo. Possiede diverse
  caratteristiche molto interessanti, e se si ha la necessit di
  eseguire diversi debug,  il caso di provarlo. La versione
  precompilata per Linux e i patch per i sorgenti UPS possono essere
  trovati in ftp://sunsite.unc.edu/pub/Linux/devel/debuggers/, mentre i
  sorgenti originali in ftp://ftp.x.org/contrib/ups-2.45.2.tar.Z.

  Un altro strumento utile per il debug  'strace', che visualizza le
  chiamate di sistema fatte da un processo. Questo strumento possiede
  anche molti altri utilizzi, inclusa la possibilit di sapere i nomi di
  file compilati, di cui non si possiede il sorgente; di esasperare i
  race condition in programmi che si sospettano contenerle, e in
  generale di imparare come funzionano le cose. La versione pi recente
  di strace (attualmente la 3.0.8) pu essere trovata in
  ftp://ftp.std.com/pub/jrs/.


  5.2.3.  Programmi background (demone)

  I programmi demone tipicamente eseguono presto la fork(), e terminano
  il programma chiamante. Questo rende la sessione di debug molto breve.

  Il modo pi semplice per aggirare questo ostacolo consiste
  nell'impostare un breakpoint per fork, e quando il programma si
  blocca, forzare la restituzione di 0.



       (gdb) list
       1               #include <stdio.h>
       2
       3               main()
       4               {
       5               if(fork()==0) printf("child\n");
       6               else printf("parent\n");
       7               }
       (gdb) break fork
       Breakpoint 1 at 0x80003b8
       (gdb) run
       Starting program: /home/dan/src/hello/./fork
       Breakpoint 1 at 0x400177c4

       Breakpoint 1, 0x400177c4 in fork ()
       (gdb) return 0
       Make selected stack frame return now? (y or n) y
       #0  0x80004a8 in main ()
       at fork.c:5
       5               if(fork()==0) printf("child\n");
       (gdb) next
       Step singolo fino all'uscita dalla funzione fork,
       che non contiene informazioni sul numero di riga.
       child
       7               }





  5.2.4.  Core file

  Quando Linux viene avviato, solitamente  configurato per non produrre
  core file. Se si desidera,  possibile utilizzare il comando interno
  dell'interprete comandi per riabilitarli: per shell compatibili C
  (come tcsh) corrisponde al comando



       % limit core unlimited




  mentre per interpreti comandi di tipo Bourne (sh, bash, zsh, pdksh)
  utilizzare



       $ ulimit -c unlimited




  Se si desidera una maggiore flessibilit nell'assegnazione dei nomi ai
  core file (nel caso, per esempio, di analisi post-mortem con un
  debugger che contiene errori)  possibile eseguire una piccola
  modifica al proprio kernel. Cercare in fs/binfmt_aout.c e
  fs/binfmt_elf.c il codice tipo:


  ______________________________________________________________________
    memcpy(corefile,"core.",5);
  #if 0
    memcpy(corefile+5,current->comm,sizeof(current->comm));
  #else
    corefile[4] = '\0';
  #endif
  ______________________________________________________________________



  e modificare gli 0 in 1.


  5.3.  Profiling

  Il profiling rappresenta un modo per esaminare le parti di un
  programma richiamate pi frequentemente o eseguite pi a lungo. 
  buona norma ottimizzare il codice e vedere dove viene perso del tempo.
   necessario compilare tutti i file oggetto sui quali si desiderano
  informazioni sul tempo di esecuzione con l'opzione -p, e per
  interpretare il file di output sar necessario anche gprof (dal
  pacchetto binutils). Si veda la pagina di manuale gprof per ulteriori
  dettagli.


  6.  Linking

  Questo paragrafo  piuttosto complicato a causa dei due formati binari
  incompatibili, la distinzione tra libreria statica e condivisa, e del
  sovraccarico del verbo 'link' che significa sia 'cosa accade dopo la
  compilazione', sia 'cosa accade quando viene richiamato un programma
  compilato' (e, di fatto, il sovraccarico del verbo 'load' in un senso
  simile ma opposto).

  Per ridurre in qualche modo la confusione, si user il termine
  `caricamento dinamico' (dynamic loading) per quello che accade durante
  l'esecuzione, argomento descritto nel prossimo paragrafo.  Potrebbe
  anche accadere di trovare il termine 'collegamento dinamico' (dynamic
  linking) con lo stesso significato, ma non in questo documento. Questo
  paragrafo, quindi, tratta esclusivamente il tipo di link che avviene
  alla fine di una compilazione.


  6.1.  Librerie condivise e statiche

  L'ultima fase della compilazione di un programma consiste nel
  'collegamento' (link), ossia nell'unire tutte le parti e vedere se
  manca qualcosa. Ovviamente esistono alcune cose che molti programmi
  hanno in comune - ad esempio, aprire file, ed il codice in grado di
  fare queste cose sono fornite sotto forma di librerie.  Nella maggior
  parte dei sistemi Linux si trovano in /lib e /usr/lib/.





  Quando si utilizza una libreria statica, il linker trova le parti
  necessarie ai moduli di programma e le copia fisicamente nel file di
  output eseguibile che viene generato. Al contrario, questo non avviene
  per le librerie condivise - in questo caso nell'output viene inserita
  una nota del tipo 'quando viene eseguito questo programma, 
  necessario caricare questa libreria'.  Ovviamente, le librerie
  condivise tendono a creare eseguibili di dimensioni minori; inoltre
  utilizzano una quantit inferiore di memoria e viene utilizzato meno
  spazio su disco. Il comportamento predefinito di Linux consiste
  nell'eseguire il collegamento di librerie condivise se esistono,
  altrimenti vengono utilizzate quelle statiche. Se si ottengono dei
  binari statici quando, al contrario, si vogliono quelli condivisi,
  controllare che i file di libreria condivisa (*.sa per a.out, *.so per
  ELF) si trovino dove dovrebbero essere e siano leggibili.

  Su Linux, le librerie statiche hanno nomi come libname.a, mentre le
  librerie condivise sono denominate libname.so.x.y.z dove x.y.z
  rappresenta il numero di versione. Le librerie condivise, inoltre,
  contengono spesso dei collegamenti che puntano ad esse, che risultano
  essere molto importanti, e (in configurazioni a.out) contengono dei
  file .sa associati. Le librerie standard sono disponibili sia in
  formato condiviso, sia in formato statico.

   possibile sapere quali librerie condivise sono richieste da un
  programma utilizzando ldd (List Dynamic Dependencies)



       $ ldd /usr/bin/lynx
               libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
               libc.so.5 => /lib/libc.so.5.2.18




  Questo esempio mostra che il browser WWW 'lynx' dipende dalla presenza
  di libc.so.5 (la libreria C) e libncurses.so.1 (utilizzata per il
  controllo del terminale). Se un programma non ha dipendenze, ldd
  risponder 'statically linked' o 'statically linked (ELF)'.


  6.2.  Interrogazione delle librerie ('In quale libreria si trova
  sin()?')

  nm nome_libreria dovrebbe listare tutti i simboli per i quali esistono
  dei riferimenti in nome_libreria. Il comando funziona sia per librerie
  statiche che dinamiche. Si supponga di voler saper dov' definita
  tcgetattr(): si potrebbe utilizzare
       $ nm libncurses.so.1 |grep tcget
                U tcgetattr




  `U' significa 'undefined' - mostra che la libreria ncurses la utilizza
  ma non la definisce. In alternativa, si potrebbe usare



       $ nm libc.so.5 | grep tcget
       00010fe8 T __tcgetattr
       00010fe8 W tcgetattr
       00068718 T tcgetpgrp




  `W' significa 'weak', ossia che il simbolo  definito, ma in modo tale
  da poter essere sostituito da un'altra definizione in una libreria
  diversa. Una definizione 'normale' (come quella per tcgetpgrp) 
  indicata con una 'T'.




  Comunque la risposta breve alla domanda del titolo, consiste in
  libm.(so|a). Tutte le funzioni definite in <math.h> sono tenute nella
  libreria math; ne consegue che sar necessario eseguire il
  collegamento con l'opzione -lm quando si utilizza una di esse.


  6.3.  Ricerca dei file

  ld: Output file requires shared library `libfoo.so.1`
  (Ovvero: "ld: Il file di output richiede la libreria condivisa
  'libfoo.so.1'")

  La strategia di ricerca di un file per ld e simili varia a seconda
  della versione, ma l'unico punto che si pu ritenere predefinito 
  /usr/lib.  Se si vuole che le librerie vengano cercate in altre
  locazioni,  necessario specificare le loro directory tramite
  l'opzione -L in gcc o ld.

  Se non dovesse funzionare, controllare che i file necessari si trovino
  effettivamente in quelle directory. Per a.out, il collegamento con
  -lfoo fa in modo che ld cerchi libfoo.sa (condivisa) e, in caso di
  insuccesso, libfoo.a (statica). Per ELF, verr eseguita la ricerca di
  libfoo.so, quindi di libfoo.a.  libfoo.so  generalmente un
  collegamento simbolico a libfoo.so.x.


  6.4.  Compilazione delle proprie librerie

  6.4.1.  Controllo della versione

  Come qualunque altro programma, le librerie possono contenere errori
  che vengono riscontrati e risolti nel tempo. Inoltre, le librerie
  possono introdurre nuove caratteristiche, modificare l'effetto di
  altre esistenti, o rimuovere quelle vecchie. Questo potrebbe
  costituire un problema per i programmi che le utilizzano.

  Pertanto si  introdutto il concetto di versione della libreria. Tutte
  le modifiche che possono essere fatte a una libreria sono catalogate
  in 'minori' o 'maggiori', dove una modifica 'minore' non interrompe il
  funzionamento dei vecchi programmi che la utilizzano. La versione di
  una libreria pu essere dedotta dal suo nome di file (di fatto, questo
  non  vero per quanto riguarda ELF; nel seguito viene spiegato il
  motivo): libfoo.so.1.2 ha '1' come versione maggiore, e '2' come
  minore. Il numero di versione minore pu essere svariato - libc
  inserisce in esso il 'livello di patch', assegnando alle librerie nomi
  del tipo libc.so.5.2.18, e spesso sono utilizzate lettere, underscore,
  o quasi ogni altro carattere ASCII.

  Una delle differenze principali tra il formato ELF e a.out consiste
  nel modo in cui viene eseguita la compilazione delle librerie
  condivise. Per prima cosa viene descritto ELF, dal momento che  pi
  semplice.


  6.4.2.  ELF. Di cosa si tratta?

  ELF (Executable and Linking Format)  un formato binario
  originariamente sviluppato da USL (UNIX System Laboratories) e
  attualmente utilizzato in Solaris e System V Release 4. A seguito
  della sua aumentata flessibilit rispetto al pi vecchio formato a.out
  utilizzato da Linux, gli sviluppatori di librerie GCC e C hanno deciso
  lo scorso anno di utilizzare ELF come formato binario standard per
  Linux.


  6.4.2.1.  Uteriori dettagli

  Questo paragrafo  tratto dal documento '/news-
  archives/comp.sys.sun.misc'.


       ELF (Executable Linking Format)  il nuovo e migliorato for
       mato di file oggetto introdotto in SVR4. ELF  molto pi
       potente di COFF, nel fatto di essere estendibile
       dall'utente. ELF vede un file oggetto come una lista di
       sezioni arbitrariamente lunga (piuttosto che come un array
       di entit a lunghezza fissa), tali sezioni, a differenza di
       quanto accade in COFF, non si devono trovare in un luogo
       specifico e non devono essere in un ordine specifico ecc.
       Gli utenti possono aggiungere nuove sezioni ai file oggetto,
       se desiderano avere a disposizione nuovi dati. ELF, inoltre,
       possiede un formato di debugging molto pi potente denomi
       nato DWARF (Debugging With Attribute Record Format) -
       attualmente non supportato completamente su Linux (ma ci si
       sta lavorando). Una lista linkata di DIE (o Debugging Infor
       mation Entries) di DWARF costituisce la sezione .debug di
       ELF.  Invece di essere un insieme di piccoli record a dimen
       sione fissa, ogni DIE di DWARF contiene una lista di
       lunghezza arbitraria di attributi complessi ed  scritto
       come un albero di dati di programma. I DIE sono in grado di
       includere una quantit di informazioni di molto maggiore
       rispetto alla sezione .debug di COFF (come grafi di eredit
       del C++ ecc).



       L'accesso ai file ELF avviene tramite la libreria di accesso
       ELF SVR4 (Solaris 2.0 ?), che fornisce un'interfaccia sem
       plice e rapida alle parti pi complicate di ELF.  Uno dei
       vantaggi principali derivanti dall'utilizzo della libreria
       di accesso ELF consiste nel fatto che non sar mai neces
       sario vedere un file ELF come file Unix,  possibile
       eseguire l'accesso come file Elf *, dopo una chiamata
       elf_open() si eseguono chiamate elf_foobar() sulle sue com
       ponenti invece di occuparsi della sua immagine effettiva su
  disco (cosa che con COFF si faceva impunemente).



  I vantaggi e gli svantaggi di ELF, e le evoluzioni necessarie per
  eseguire l'upgrade di un sistema a.out per supportarlo, sono descritti
  nell'ELF-HOWTO e non ho intenzione di ripeterli qui. L'HOWTO dovrebbe
  essere disponibile nello stesso luogo in cui  stato trovato questo
  documento.


  6.4.2.2.  Librerie condivise di ELF

  Per eseguire la compilazione di libfoo.so come libreria condivisa, i
  passi di base hanno la seguente forma:



       $ gcc -fPIC -c *.c
       $ gcc -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 *.o
       $ ln -s libfoo.so.1.0 libfoo.so.1
       $ ln -s libfoo.so.1 libfoo.so
       $ LD_LIBRARY_PATH='pwd':$LD_LIBRARY_PATH ; export LD_LIBRARY_PATH




  Questi comandi genererano una libreria condivisa denominata
  libfoo.so.1.0, i collegamenti appropriati per ld (libfoo.so) e il
  caricamento dinamico (libfoo.so.1) per trovarla. Per eseguire un
  collaudo, si aggiunge la directory corrente a LD_LIBRARY_PATH.



  Quando si  sicuri che la libreria funziona, deve essere spostata, ad
  esempio, in /usr/local/lib, e devono essere creati appropriati
  collegamenti. Il collegamento da libfoo.so.1 a libfoo.so.1.0 
  mantenuto aggiornato da ldconfig, che nella maggior parte dei sistemi
  viene eseguito come parte del processo di avviamento. Il collegamento
  libfoo.so deve essere aggiornato manualmente.  Se si  scrupolosi
  nell'eseguire l'aggiornamento di tutte le parti di una libreria (ossia
  degli header file) contemporaneamente, la cosa pi semplice da fare
  consiste nel rendere libfoo.so -> libfoo.so.1, in modo che ldconfig
  mantenga correnti entrambi i collegamenti. In caso contrario, potrebbe
  in seguito verificarsi ogni genere di stranezza.



       $ su
       # cp libfoo.so.1.0 /usr/local/lib
       # /sbin/ldconfig
       # ( cd /usr/local/lib ; ln -s libfoo.so.1 libfoo.so )





  6.4.2.3.  Numerazione delle versioni, soname e symlink

  Ogni libreria ha un soname. Quando il linker trova uno di questi in
  una libreria in cui sta eseguendo una ricerca, nel binario viene
  incluso il soname in luogo del nome di file effettivo ricercato.
  Durante l'esecuzione, il loader dinamico cercher un file tramite il
  nome di soname, non con il nome di file/libreria. Pertanto, una
  libreria denominata libfoo.so potrebbe avere il soname libbar.so, di
  conseguenza tutti i programmi collegati ad essa, all'avvio,
  cercherebbero libbar.so.

  Sembra essere una caratteristica di poca importanza, invece  la
  chiave per capire come su un sistema possono coesistere diverse
  versioni della stessa libreria. Di fatto, la denominazione standard
  delle librerie in Linux consiste nel chiamare la libreria, ad esempio,
  libfoo.so.1.2, e assegnare ad essa il soname libfoo.so.1. Se aggiunta
  in una directory di libreria 'standard' (ossia, /usr/lib), ldconfig
  creer un collegamento simbolico libfoo.so.1 -> libfoo.so.1.2 in modo
  che sia possibile trovare l'immagine appropriata durante l'esecuzione.
   necessario anche un collegamento libfoo.so -> libfoo.so.1 affinch
  ld possa trovare il soname corretto da utilizzare durante il link.

  Pertanto, quando si risolve un errore nella libreria, o si aggiungono
  nuove funzioni (ogni modifica che non influenzi in modo negativo i
  programmi esistenti), si eseguir nuovamente la compilazione
  mantenendo lo stesso soname, e modificando il nome di file. Quando si
  inseriscono nella libreria delle modifiche che causerebbero
  l'interruzione dei programmi esistenti, incrementare semplicemente il
  numero nel soname - in questo caso, rinominare la nuova versione
  libfoo.so.2.0, e assegnarle il soname libfoo.so.2. Quindi, convertire
  il collegamento a libfoo.so in modo che punti alla nuova versione e
  tutto  a posto.

  Si noti che non  necessario dare un nome alle librerie, ma si tratta
  di una buona convenzione. ELF fornisce una flessibilit nel nominare
  le librerie in modi che potrebbero confondere, ma questo non significa
  che debba farlo per forza.

  Riassumendo: se si suppone di osservare la tradizione secondo cui gli
  aggiornamenti maggiori potrebbero distruggere la compatibilit e che
  quelli minori non lo fanno, eseguire il collegamento con



       gcc -shared -Wl,-soname,libfoo.so.major -o libfoo.so.major.minor




  e tutto funzioner alla perfezione.


  6.4.3.  a.out. Il formato tradizionale

  La facilit con cui si esegue la compilazione di librerie condivise 
  uno dei motivi principali per passare a ELF.  Detto questo,  ancora
  possibile utilizzare a.out. Si prenda
  ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.17.tar.gz e si
  legga il documento di 20 pagine.


  6.4.3.1.  ZMAGIC e QMAGIC

  QMAGIC  un formato eseguibile proprio come i vecchi binari a.out
  (conosciuti anche come ZMAGIC), ma che lascia la prima pagina non
  mappata.  Questo consente che accada pi facilmente un riferimento
  NULL dal momento che non esiste alcun mapping nel range 0-4096. Come
  effetto collaterale, i binari saranno di dimensioni inferiori (di
  circa 1 K).

  I linker obsoleti supportano solamente ZMAGIC, quelli semi-obsoleti
  supportano entrambi i formati, mentre le versioni attuali supportano
  solo QMAGIC. In realt questo non ha importanza, dal momento che il
  kernel riesce ad eseguire entrambi i formati.

  Il proprio comando 'file' dovrebbe essere in grado di identificare se
  un programma  QMAGIC.


  6.4.3.2.  Posizione dei file

  Una libreria condivisa a.out (DLL)  formata da due file reali e da un
  collegamento simbolico. Per la libreria 'foo' utilizzata come esempio,
  questi file sarebbero libfoo.sa e libfoo.so.1.2; il collegamento
  simbolico sarebbe libfoo.so.1 e punterebbe all'ultimo di questi file.
  Ma a cosa servono?

  Durante la compilazione, ld ricerca libfoo.sa. Si tratta del file
  'matrice' della libreria, e contiene tutti i dati esportati e i
  puntatori alle funzioni richieste per il collegamento run time.

  Durante l'esecuzione, il loader dinamico cerca libfoo.so.1. Si tratta
  di un collegamento simbolico anzich di un file reale in modo che le
  librerie possano essere aggiornate con versioni pi recenti e corrette
  senza procurare danni a nessuna delle applicazioni utilizzanti la
  libreria in quel momento. Dopo che la nuova versione, ad esempio
  libfoo.so.1.3 -  stata introdotta, l'esecuzione di ldconfig commuter
  il collegamento affinch punti ad essa tramite un'operazione atomica,
  lasciando illeso ogni programma che stava utilizzando la vecchia
  versione.

  Le librerie DLL appaiono spesso pi grandi delle loro controparti
  statiche. Riservano spazio per future espansioni nella forma di
  'buchi' che possono essere creati senza occupare spazio su disco. Una
  semplice chiamata cp o l'utilizzo del programma makehole raggiunger
  questo scopo. Dopo la compilazione,  anche possibile rimuoverli, dal
  momento che gli indirizzi si trovano in locazioni fisse. Non tentare
  di rimuoverli dalle librerie ELF.


  6.4.3.3.  "libc-lite"?

  Un libc-lite  una versione ridotta della libreria libc per la quale 
  stata eseguita la compilazione in modo tale da stare su un floppy disk
  ed essere sufficiente per tutti i task Unix essenziali. Non include
  codice curse, dbm, termcap ecc.  Se il proprio /lib/libc.so.4 ha un
  collegamento con un lite lib, il sistema avvisa di sostituirlo con una
  versione completa.


  6.4.4.  Linking: problemi comuni

  Inviatemi i problemi derivanti dal linking! Anche se non potr fare
  niente per risolverli, ne scriver un resoconto dettagliato.


     Programmi eseguono il link statico anzich dinamico



        Controllare di avere i collegamenti corretti affinch ld possa
        trovare tutte le librerie condivise. Per ELF questo significa un
        collegamento simbolico libfoo.so per l'immagine, in a.out un
        file libfoo.sa.  Molte persone hanno riscontrato questo problema
        dopo il passaggio dai binutils ELF 2.5 ai 2.6 - la versione
        precedente ricercava le librerie condivise in un modo 'pi
        intelligente' pertanto non avevano bisogno di creare tutti i
        collegamenti. Il comportamento intelligente  stato eliminato
        per compatibilit con altre architetture, e perch molto spesso
        le sue supposizioni erano sbagliate e causando pi guai di
        quanti fossero i problemi risolti.
     Lo strumento DLL 'mkimage' non riesce a trovare libgcc


        Da libc.so.4.5.x e oltre, libgcc non  pi condivisa. Pertanto,
         necessario sostituire le occorrenze di '-lgcc' con 'gcc
        -print-libgcc-file-name'.

        Inoltre, bisogna cancellare tutti i file /usr/lib/libgcc*.
        Questo  molto importante.


     Messaggi __NEEDS_SHRLIB_libc_4 multiply defined
        Altra conseguenza del problema descritto al punto precedente.


     Messaggio ``Assertion failure'' quando si ricompila una DLL?
        Questo messaggio criptico molto probabilmente significa che uno
        degli slot della propria jump table  andato in overflow poich
         stato riservato troppo poco spazio nel file jump.vars
        originale.  possibile localizzare i colpevoli eseguendo il
        comando 'getsize' fornito nel pacchetto tools-2.17.tar.gz.
        Tuttavia, probabilmente l'unica soluzione consiste nel
        sostituire il numero di versione maggiore della libreria,
        forzandolo affinch sia impossibile tornare indietro.


     ld: output file needs shared library libc.so.4
        Questo accade solitamente quando si sta eseguendo il
        collegamento con librerie diverse da libc (come le librerie X),
        e si utilizza l'opzione -g sulla riga di link utilizzando anche
        -static.

        Gli stub .sa per le librerie condivise contengono solitamente un
        simbolo indefinito _NEEDS_SHRLIB_libc_4 che viene risolto da
        libc.sa. Tuttavia, con -g si finisce di eseguire il collegamento
        con libg.a o libc.a, il simbolo non viene mai risolto, portando
        all'errore sopra descritto.

        In conclusione, aggiungere -static quando si compila con
        l'opzione -g, oppure non eseguire il collegamento con -g. Molto
        spesso  possibile ottenere informazioni di debugging
        sufficienti compilando i file individuali con -g, ed eseguendo
        il collegamento senza questa opzione.



  6.5.  Loading dinamico

  Questo paragrafo  per il momento piuttosto breve, verr esteso in
  futuro.


  6.5.1.  Concetti

  Linux possiede delle librerie condivise, come si  visto diverse molte
  volte nell'ultimo paragrafo.  Gran parte del lavoro di associazione
  dei nomi a locazioni, che tradizionalmente era svolto al momento del
  link, deve essere ritardato al momento del load (caricamento).


  6.5.2.  Messaggi di errore

  I lettori sono pregati di inviare i proprii errori di link all'autore,
  che anche se non potr risolverli, comunque scriver un resoconto
  dettagliato.

      can't load library: /lib/libxxx.so, Incompatible version
        (solo in a.out) Questo significa che non si possiede la versione
        maggiore aggiornata della libreria xxx. Non  possibile
        semplicemente creare un collegamento simbolico ad un'altra
        versione che si possiede; nella migliore delle ipotesi questo
        causer un segfault nel proprio programma.  Si consiglia di
        ottenere una nuova versione. Una situazione simile in ELF
        produrr un messaggio del tipo



          ftp: can't load library 'libreadline.so.2'





      warning using incompatible library version xxx
        (solo in a.out) Si possiede una versione minore della libreria
        pi vecchia di quella posseduta dalla persona che ha compilato
        il programma in questione. Il programma funzioner comunque.
        Tuttavia, un aggiornamento non sarebbe una cattiva idea.



  6.5.3.  Controllo delle operazioni del loader dinamico

  Esistono diverse variabili di ambiente a che influenzano il
  comportamento del loader dinamico. La maggior parte di esse sono pi
  utili a ldd di quanto non lo siano per l'utente medio, e possono
  essere impostate eseguendo ldd con diverse opzioni. Includono


    LD_BIND_NOW --- normalmente, le funzioni non sono ricercate nelle
     librerie finch non vengono chiamate. L'impostazione di questa
     opzione attiva la ricerca  all'atto del caricamento della libreria,
     determinando un tempo di avviamento maggiore. Pu essere utile
     quando si vuole collaudare un programma per accertarsi che sia
     eseguito il link di tutte le parti.

    LD_PRELOAD --- pu essere impostato con un file contenente delle
     definizioni di funzioni da sovrapporre. Ad esempio, se si sta
     eseguendo un test delle strategie di allocazione della memoria, e
     si vuole sostituire 'malloc',  possibile scrivere la propria
     routine sostitutiva, compilarla come malloc.o e utilizzare i
     comandi



       $ LD_PRELOAD=malloc.o; export LD_PRELOAD
       $ programma_di_test





  LD_ELF_PRELOAD e LD_AOUT_PRELOAD sono simili, ma possono essere appli
  cati solo al tipo binario appropriato. Se LD_qualcosa_PRELOAD e
  LD_PRELOAD sono entrambi impostati, verr utilizzato quello pi speci
  fico.

    LD_LIBRARY_PATH --- elenco, separato da virgole, di directory in
     cui ricercare le librerie condivise. Non ha effetti su ld, ma solo
     durante l'esecuzione. Inoltre,  disabilitato per programmi che
     eseguono setuid o setgid. LD_ELF_LIBRARY_PATH e
     LD_AOUT_LIBRARY_PATH possono anche essere utilizzati per impostare
     la ricerca in modo differente per diversi tipi di binari.
     LD_LIBRARY_PATH non dovrebbe essere necessario nelle operazioni
     normali; piuttosto aggiungere le directory a /etc/ld.so.conf/ ed
     eseguire ldconfig.

    LD_NOWARN --- si applica solo ad a.out. Quando impostato (ossia con
     LD_NOWARN=true; export LD_NOWARN) evita che il loader fornisca i
     warning non fatali (come i messaggi per incompatibilit di versione
     minore).

    LD_WARN --- si applica solamente a ELF. Quando impostato, rende i
     messaggi, solitamente fatali, "Can't find library" dei semplici
     warning.  Non  molto utilizzato nelle operazioni normali, ma 
     importante per ldd.

    LD_TRACE_LOADED_OBJECTS --- si applica solamente a ELF, e fa in
     modo che i programmi credano di essere in esecuzione sotto ldd:



       $ LD_TRACE_LOADED_OBJECTS=true /usr/bin/lynx
               libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
               libc.so.5 => /lib/libc.so.5.2.18






  6.5.4.  Scrivere programmi con il loading dinamico

  Questo  molto simile al funzionamento del supporto di loading
  dinamico di Solaris 2.x.  L'argomento  trattato ampiamente nel
  documento di programmazione ELF di H J Lu e nella pagina di manuale
  dlopen(3) manual page, che pu essere trovata nel pacchetto ld.so.
  Segue un semplice esempio:  necessario effettuare il link con -ldl



       #include <dlfcn.h>
       #include <stdio.h>

       main()
       {
           void *libc;
           void (*printf_call)();

           if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
           {
               printf_call=dlsym(libc,"printf");
               (*printf_call)("hello, world\n");
           }

       }





  7.  Come contattare gli sviluppatori

  7.1.  Comunicazione degli errori

  Per prima cosa  necessario cominciare a circoscrivere il problema. 
  specifico di Linux, oppure accade con gcc su altri sistemi? 
  specifico della versione di kernel? Della versione di libreria?
  Sparisce se si esegue il link statico?  possibile ritagliare una
  piccola parte del programma che dimostra l'errore?

  Fatto questo, si  a conoscenza del/i programma/i in cui si trova
  l'errore. Per GCC, la procedura di comunicazione degli errori 
  spiegata nel file info. Per ld.so o per le librerie C o maths, inviare
  una mail a linux-gcc@vger.rutgers.edu. Se possibile, includere un
  breve e autonomo programma che possa dimostrare l'errore, e una
  descrizione sia di cosa si intendeva che facesse, sia di cosa fa
  effettivamente.


  7.2.  Aiuto nello sviluppo

  Se si desidera aiutare lo sviluppo di GCC o della libreria C, la prima
  cosa da fare consiste nell'unirsi alla mailing list linux-
  gcc@vger.rutgers.edu. Se si vuole semplicemente dare un'occhiata alle
  discussioni,  possibile consultare http://homer.ncm.com/linux-gcc/.
  La seconda cosa e le successive dipendono solo dalle vostre
  intenzioni!


  8.  Ultime cose

  8.1.  Ringraziamenti


       Only presidents, editors, and people with tapeworms have the
       right to use the editorial "we".  (Mark Twain)


  Ovvero

       Soli i presidenti, gli editori e la gente con il verme soli
       tario hanno il diritto di usare il "noi" editoriale.  (Mark
       Twain)


  Questo HOWTO si basa molto strettamente al GCC-FAQ di Mitchum DSouza;
  la maggior parte delle informazioni (per non dire una grande quantit
  di testo)  derivato direttamente da quel documento. Esperienze
  riferite all'autore all'interno di questo HOWTO potrebbero riferirsi
  anche a Mitchum DSouza; generalmente le frasi del tipo 'Non si  mai
  collaudato questa parte; non maledite l'autore se il vostro
  disco/sistema si  abbrustolito' possono essere applicate a entrambi.
  Inoltre hanno contribuito a questo documento (in ordine ASCII per
  nome): Andrew Tefft, Axel Boldt, Bill Metzenthen, Bruce Evans, Bruno
  Haible, Daniel Barlow, Daniel Quinlan, David Engel, Dirk Hohndel, Eric
  Youngdale, Fergus Henderson, H.J. Lu, Jens Schweikhardt, Kai Petzke,
  Michael Meissner, Mitchum DSouza, Olaf Flebbe, Paul Gortmaker, Rik
  Faith, Steven S. Dick, Tuomas J Lukka, e naturalmente Linus Torvalds,
  senza il quale l'intero lavoro non avrebbe avuto senso.  Vi prego di
  non sentirvi offesi se nella lista non compare il vostro nome e avete
  contribuito a questo documento (come HOWTO o come FAQ). Inviate mail
  ed sar eseguita la correzione.


  8.2.  Traduzioni

  Attualmente, non esistono traduzioni di questo documento Se desiderate
  farne una, siete liberi di farlo ma vi prego di farmelo sapere! Ci
  sono pochissime probabilit che io sia in grado di parlare la lingua
  in cui desiderate tradurre il documento, ma a parte questo sarei lieto
  di aiutarvi in qualsiasi modo.


  8.3.  Comunicazioni, opinioni, correzioni

  Sono benvenute inviate email all'indirizzo dan@detached.demon.co.uk.
  La chiave pubblica PGP (ID 5F263625)  disponibile dalle pagine web
  dell'autore http://ftp.linux.org.uk/~barlow/, se ci sono necessit di
  riservatezza.


  8.4.  Informazioni legali

  All trademarks used in this document are acknowledged as being owned
  by their respective owners.

  This document is copyright (C) 1996 Daniel Barlow
  dan@detached.demon.co.uk. It may be reproduced and distributed in
  whole or in part, in any medium physical or electronic, as long as
  this copyright notice is retained on all copies. Commercial
  redistribution is allowed and encouraged; however, the author would
  like to be notified of any such distributions.

  All translations, derivative works, or aggregate works incorporating
  any Linux HOWTO documents must be covered under this copyright notice.
  That is, you may not produce a derivative work from a HOWTO and impose
  additional restrictions on its distribution. Exceptions to these rules
  may be granted under certain conditions; please contact the Linux
  HOWTO coordinator at the address given below.

  In short, we wish to promote dissemination of this information through
  as many channels as possible. However, we do wish to retain copyright
  on the HOWTO documents, and would like to be notified of any plans to
  redistribute the HOWTOs.

  If you have questions, please contact Tim Bynum, the Linux HOWTO
  coordinator, at linux-howto@sunsite.unc.edu.


       L'unica licenza valida  quella originale in lingua inglese.
       Di seguito ne trovate una traduzione abbastanza fedele che
       per non ha alcun valore.


  Tutti i marchi utilizzati in questo documento sono riconosciuti come
  appartenenti ai rispettivi proprietari.

  Questo documento ha copyright (C) 1996 di Daniel Barlow
  dan@detached.demon.co.uk. Pu essere riprodotto e distribuito
  completamente o in parte, su ogni mezzo fisico o elettronico, purch
  questo messaggio di copyright sia mantenuto in tutte le copie. 
  consentita e incoraggiata la ridistribuzione commerciale; tuttavia,
  l'autore gradirebbe essere informato su ciascuna di tali
  distribuzioni.

  Tutte le traduzioni, lavori derivati, o lavori aggregati che includono
  un qualunque documento Linux deve essere coperto da questo messaggio
  di copyright. Ossia, non  possibile produrre un lavoro derivato da un
  HOWTO e imporre delle restrizioni addizionali sulla sua distribuzione.
  Eccezioni a queste regole possono essere ammesse sotto particolari
  condizioni; si prega di contattare il coordinatore degli HOWTO di
  Linux all'indirizzo sotto riportato.

  In breve, desideriamo promuovere la diffusione di queste informazioni
  attraverso pi canali possibile. Tuttavia, desideriamo anche mantenere
  il copyright sui documenti HOWTO, e vorremmo essere informati se
  qualcuno ha intenzione di ridistribuire gli HOWTO.


  Se avete delle domande, contattate Tim Bynum, il coordinatore degli
  HOWTO di Linux, all'indirizzo linux-howto@sunsite.unc.edu tramite
  email.


  9.  Riferimenti in italiano

  Questa sezione riporta riferimenti a documenti italiani. Nel caso in
  cui un documento non sia ancora tradotto si rimanda al WEB server del
  Pluto.


    [1] http://www.pluto.linux.it/ildp/HOWTO/ELF-HOWTO.html

    [2] http://www.pluto.linux.it/ildp/ WEB server del PLUTO, sono
     disponibili anche le traduzioni di altri HOWTO.

    [3] http://www.pluto.linux.it/ildp/HOWTO/GCC-HOWTO.html


  10.  Indice Analitico




      -fwritable-strings
        ``39'' ``56''


      /lib/cpp
        ``16''


      a.out
        ``1''


      ar
        ``10''


      as
        ``8''


      <asm/*.h>
        ``19''


      atoi()
        ``40''


      atol()
        ``41''


      binaries too big
        ``63'' ``65'' ``77''


      cos()
        ``68''



      debugging
        ``59''


      dlopen()
        ``82''


      dlsym()
        ``83''


      documentazione
        ``4''


      EINTR
        ``52''


      elf
        ``0'' ``71''


      execl()
        ``57''


      fcntl
        ``47''


      FD_CLR
        ``44''


      FD_ISSET
        ``45''


      FD_SET
        ``43''


      FD_ZERO
        ``46''


      file
        ``2''


      <float.h>
        ``20''


      gcc
        ``6''


      gcc -fomit-frame-pointer
        ``61''


      gcc -g
        ``60''
      gcc -v
        ``14''


      gcc, errori (bug)
        ``15'' ``28'' ``29'' ``84''


      gcc, opzioni (flag)
        ``13'' ``25'' ``26''


      gdb
        ``64''


      header file
        ``17''


      chiamate a sistema interrotte
        ``51''


      ld
        ``9''


      LD_* variabili d'ambiente
        ``80''


      ldd
        ``81''


      libc
        ``7''


      libg.a
        ``62''


      libgcc
        ``79''


      <limits.h>
        ``21''


      lint
        ``58''


      <linux/*.h>
        ``18''


      pagine del manuale
        ``5''


      <math.h>
        ``70''
      maths
        ``69''


      mktemp()
        ``55''


      ottimizzazione
        ``27''


      QMAGIC
        ``76''


      segmentation fault
        ``30'' ``54''


      segmentation fault, in GCC
        ``33''


      select()
        ``50''


      SIGBUS
        ``34''


      SIGEMT
        ``35''


      SIGIOT
        ``36''


      SIGSEGV
        ``31'' ``53''


      SIGSEGV, in gcc
        ``32''


      SIGSYS
        ``38''


      SIGTRAP
        ``37''


      sin()
        ``67''


      soname
        ``73''


      sprintf()
        ``42''
      librerie collegate staticamente, in modo inatteso
        ``66'' ``78''


      <stdarg.h>
        ``23''


      <stddef.h>
        ``24''


      strings
        ``11''


      <sys/time.h>
        ``48''


      <unistd.h>
        ``49''


      <varargs.h>
        ``22''


      numeri di versione
        ``12'' ``74''


      cose misteriose
        ``72''


      ZMAGIC
        ``75''