This file is indexed.

/usr/share/doc/HOWTO/fr-html/GCC-HOWTO.html is in doc-linux-fr-html 2013.01-3ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for HTML5 for Linux version 5.2.0">
<meta name="GENERATOR" content="LinuxDoc-Tools 0.9.72">
<title>GCC HOWTO pour Linux</title>
</head>
<body>
<h1>GCC HOWTO pour Linux</h1>
<h2>par Daniel Barlow
<code>&lt;dan@detached.demon.co.uk&gt;</code></h2>
v1.17, 28 février 1996
<hr>
<em>(Adaptation française par Eric Dumas
<code>&lt;dumas@freenix.fr&gt;</code>, 8 Avril 1996). Ce document
présente la manière de configurer le compilateur GNU C et les
bibliothèques de développement sous Linux. Il donne un aperçu de la
compilation, de l'édition de liens, de l'exécution et du débogage
de programmes sous Linux. Bon nombre de passages de ce document
sont empruntés à la FAQ GCC rédigée par Mitch D'Souza's et au HowTo
ELF. Ceci est la première version publique (en dépit du numéro de
version : en fait, ça vient de RCS). N'hésitez pas à me joindre
pour toute remarque.</em>
<hr>
<h2><a name="s1">1. Préliminaires</a></h2>
<h2><a name="index.1"></a> <a name="index.0"></a> <a name=
"ss1.1">1.1 ELF et a.out</a></h2>
<p>Le développement de Linux est actuellement dans une phase de
transition. En résumé, il existe deux formats de binaires que Linux
reconnaît et exécute, et cela dépend de la manière dont votre
système est configuré : vous pouvez avoir les deux, l'un ou
l'autre. En lisant ce document, vous pourrez savoir quels binaires
votre système est capable de gérer.</p>
<p><a name="index.2"></a></p>
<p>Comment le savoir ? Utilisez la commande <code>file</code> (par
exemple, <code>file /bin/bash</code>). Pour un programme ELF, cette
commande va vous répondre quelque chose dans lequel se trouve le
mot ELF. Dans le cas d'un programme en a.out, il vous indiquera
quelque chose comme <code>Linux/i386</code>.</p>
<p>Les différences entre ELF et a.out sont détaillées plus tard
dans ce document. ELF est le nouveau format et il est considéré
comme étant meilleur.</p>
<h2><a name="index.3"></a> <a name="ss1.2">1.2 Du côté du
copyright</a></h2>
<p>Le copyright et autres informations légales peuvent être trouvés
à la <em>fin</em> de ce document, avec les avertissements
conventionnels concernant la manière de poser des questions sur
Usenet pour éviter d'avoir à révéler votre ignorance du langage C
en annonçant des bogues qui n'en sont pas, etc.</p>
<h2><a name="ss1.3">1.3 Typographie</a></h2>
<p>Si vous lisez ce document au format Postscript, dvi, ou HTML,
vous pouvez voir quelques différence entre les styles d'écriture
alors que les gens qui consultent ce document au format texte pur
ne verront aucune différence. En particulier, les noms de fichiers,
le nom des commandes, les messages donnés par les programmes et les
codes sources seront écrits avec le style suivant : <code>style
d'écriture</code>, alors que les noms de variables entre autres
choses seront en <em>italique</em>.</p>
<p>Vous aurez également un index. Avec les formats dvi ou
postscript, les chiffres dans l'index correspondent au numéros de
paragraphes. Au format HTML, il s'agit d'une numérotation
séquentielle pour que vous puissiez cliquer dessus. Avec le format
texte, ce ne sont que des nombres. Il vous est donc conseillé de
prendre un autre format que le format texte !</p>
<p>L'interpréteur de commande (<em>shell</em>) utilisé dans les
exemples sera la Bourne shell (plutôt que le C-Shell). Les
utilisateurs du C-Shell utiliseront plutôt :</p>
<blockquote>
<pre><code>
% setenv soif JD
</code></pre></blockquote>
là où j'ai écrit
<blockquote>
<pre><code>
$ soif=JD; export soif
</code></pre></blockquote>
<p>Si l'invite (<em>prompt</em> dans la langue de Shakespeare) est
<code>#</code> plutôt que <code>$</code>, la commande ne
fonctionnera que si elle est exécutée au nom de Root. Bien sur, je
décline toute responsabilité de ce qui peut se produire sur votre
système lors de l'exécution de ces exemples. Bonne chance
<code>:-)</code></p>
<h2><a name="s2">2. Où récupérer de la documentation et les
programmes ?</a></h2>
<h2><a name="ss2.1">2.1 Ce document</a></h2>
<p>Ce document fait partie de la série des HOWTO pour Linux, et il
est donc disponible ainsi que ces collègues dans les répertoires
HowTo pour Linux, comme sur <a href=
"http://sunsite.unc.edu/pub/linux/docs/HOWTO/">http://sunsite.unc.edu/pub/linux/docs/HOWTO/</a>.
La version HTML peut également être consultée sur <a href=
"http://ftp.linux.org.uk/~barlow/howto/gcc-howto.html">http://ftp.linux.org.uk/~barlow/howto/gcc-howto.html</a>.</p>
<p>Note du traducteur : vous pouvez obtenir tous les HowTos en
langue anglaise et française sur
<code>ftp.ibp.fr:/pub/linux</code>. Les versions françaises se
trouvent dans le répertoire
<code>/pub/linux/french/HOWTO</code>.</p>
<h2><a name="index.4"></a> <a name="ss2.2">2.2 Autres
documentation</a></h2>
<p>La documentation officielle pour gcc se trouve dans les sources
de la distribution (voir plus bas) sous la forme de fichiers
texinfo et de fichiers <code>.info</code>. Si vous possédez une
connexion rapide, un CD-ROM ou une certaine patience, vous pouvez
désarchiver la documentation et l'installer dans le répertoire
<code>/usr/info</code>. Sinon, vous pouvez toujours les trouver sur
<a href="ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">tsx-11</a>,
mais ce n'est pas nécessairement toujours la dernière version.</p>
<p><a name="index.5"></a></p>
<p>Il existe deux sources de documentation pour la libc. La libc
GNU est fournie avec des fichiers info qui décrivent assez
précisément la libc Linux sauf pour la partie des entrées-sorties.
Vous pouvez également trouver sur <a href=
"ftp://sunsite.unc.edu/pub/Linux/docs/">sunsite</a> des documents
écrits pour Linux ainsi que la description de certaines appels
systèmes (section 2) et certaines fonctions de la libc (section
3).</p>
<p>Note du traducteur : un bémol concernant cette partie... La libc
Linux n'est pas GNU et tend à être relativement différente sur
certains points.</p>
<h2><a name="index.6"></a> <a name="ss2.3">2.3 GCC</a></h2>
<p>Il existe deux types de réponses</p>
<p>(a) La distribution officielle de GCC pour Linux peut toujours
être récupérée sous la forme de binaires (déjà compilée) sur
<a href=
"ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/</a>.
Vous pouvez la trouver sur le miroir français <a href=
"ftp://ftp.ibp.fr:/pub/linux/packages/GCC/">ftp://ftp.ibp.fr:/pub/linux/packages/GCC/</a>.
A l'heure où j'écris ces lignes, la dernière version est gcc 2.7.2
(<code>gcc-2.7.2.bin.tar.gz</code>).</p>
<p>(b) La dernière distribution des sources de GCC de la <em>Free
Software Foundation</em> peut-être récupérée sur <a href=
"ftp://prep.ai.mit.edu/pub/gnu/">prep.ai.mit.edu</a> ou <a href=
"ftp://ftp.ibp.fr/pub/gnu/">ftp.ibp.fr</a>. Ce n'est pas toujours
la même version que celle présentée ci-dessus. Les mainteneurs de
GCC pour Linux ont rendu la compilation de GCC plus facile grâce à
l'utilisation du script <code>configure</code> qui effectue la
configuration d'une manière automatique. Regardez dans <a href=
"ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">tsx-11</a> ou
<a href="ftp://ftp.ibp.fr:/pub/linux/packages/GCC/">ftp.ibp.fr</a>
pour récupérer d'éventuels patches.</p>
<p>Quelle que soit la complexité de votre programme, vous aurez
également besoin de la <em>libc</em>.</p>
<h2><a name="index.7"></a> <a name="ss2.4">2.4 Les fichiers
d'en-tête et la bibliothèque C</a></h2>
<p>Ce que vous allez trouver dans ce paragraphe dépend</p>
<ul>
<li>de votre système (ELF ou a.out) ;</li>
<li>du type de binaire que vous désirez générer.</li>
</ul>
Si vous êtes en train de mettre à jour votre libc 4 en libc 5, vous
devriez consulter le ELF HowTo qui se trouve au même endroit que ce
document.
<p>Les libc sont disponibles sur <a href=
"ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">tsx-11</a> ou
<a href="ftp://ftp.ibp.fr:/pub/linux/packages/GCC/">ftp.ibp.fr</a>.
Voici une description des fichiers situés dans ce répertoire :</p>
<dl>
<dt><b><code>libc-5.2.18.bin.tar.gz</code></b></dt>
<dd>
<p>--- bibliothèques dynamiques et statiques ELF plus les fichiers
d'en-tête pour la bibliothèque C et la bibliothèque
mathématique.</p>
</dd>
<dt><b><code>libc-5.2.18.tar.gz</code></b></dt>
<dd>
<p>--- Code source pour la bibliothèque ci-dessus. Vous aurez
également besoin du paquetage <code>.bin.</code> pour avoir les
fichiers d'en-tête. Si vous hésitez entre compiler la bibliothèque
C vous-même et utiliser les binaires, la bonne réponse est dans la
majorité des cas est d'utiliser les binaires. Toutefois, si vous
désirer utiliser NYS (NdT : NYS != NIS) ou bien les mots de passe
<em>shadow</em>, vous devrez recompiler la libc par vous-même.</p>
</dd>
<dt><b><code>libc-4.7.5.bin.tar.gz</code></b></dt>
<dd>
<p>--- bibliothèques dynamiques et statiques a.out pour la version
4.7.5 de la libc. Cette bibliothèque a été conçue pour pouvoir
coexister avec le paquetage de la libc 5 décrit ci-dessus, mais
c'est uniquement nécessaire si vous désirez utiliser ou développer
des programmes au format a.out.</p>
</dd>
</dl>
<h2><a name="index.11"></a> <a name="index.10"></a> <a name=
"index.9"></a> <a name="index.8"></a> <a name="ss2.5">2.5 Outils
associés (as, ld, ar, strings, etc.)</a></h2>
<p>Ces outils se trouvent comme les bibliothèques dans le
répertoire <a href=
"ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">tsx-11</a>, et
<a href="ftp://ftp.ibp.fr:/pub/linux/packages/GCC/">ftp.ibp.fr</a>.
La version actuelle est
<code>binutils-2.6.0.2.bin.tar.gz</code>.</p>
<p>Il est utile de remarquer que ces outils ne sont disponibles
qu'au format ELF, que la libc actuelle est ELF et que la libc a.out
ne pose pas de problème lorsqu'elle est utilisée avec la libc ELF.
Le développement de la libc est relativement rapide et à moins que
n'ayez de bonnes raisons pour utiliser le format a.out, vous êtes
encouragés à suivre le mouvement.</p>
<h2><a name="s3">3. Installation et configuration de GCC</a></h2>
<h2><a name="index.14"></a> <a name="index.13"></a> <a name=
"index.12"></a> <a name="ss3.1">3.1 Les versions de GCC</a></h2>
<p>Vous pouvez savoir quelle est la version de GCC que vous
possédez en tapant <code>gcc -v</code> lors de l'invite. C'est
également une bonne technique pour savoir si votre configuration
est ELF ou a.out. Sur mon système, cela donne ceci :</p>
<blockquote>
<pre><code>
$ gcc -v
Reading specs from /usr/lib/gcc-lib/i486-zorglub-linux/2.7.2/specs
gcc version 2.7.2
</code></pre></blockquote>
<p>Les mots-clefs à remarquer</p>
<ul>
<li><code>i486</code>. Cela vous indique que la version de gcc que
vous utilisez a été compilée pour être utilisée sur un processeur
486 --- mais vous pouvez avoir un autre processeur comme un 386 ou
un Pentium (586). Tous ces processeurs peuvent exécuter le code
compilé avec n'importe quel processeur. La seule différence réside
dans le fait que le code 486 rajoute un peu de code à certains
endroits pour aller plus vite sur un 486. Cela n'a pas d'effet
néfaste côté performance sur un 386 mais cela rend les exécutables
un peu plus importants.</li>
<li><code>zorglub</code>. Ce n'est pas réellement important, et il
s'agit généralement d'un commentaire (comme <code>slackware</code>
or <code>debian</code>) ou même, cela peut-être vide (lorsque vous
avez comme nom de répertoire <code>i486-linux</code>). Si vous
construisez votre propre gcc, vous pouvez fixer ce paramètre selon
vos désirs, comme je l'ai fait. <code>:-)</code></li>
<li><code>linux</code>. Cela peut être à la place
<code>linuxelf</code> ou <code>linuxaout</code> et en fait, la
signification varie en fonction de la version que vous possédez.
<ul>
<li><code>linux</code> signifie ELF si la version est 2.7.0 ou
supérieure, sinon, c'est du a.out.</li>
<li><code>linuxaout</code> signifie a.out. Cela a été introduit
comme cible lorsque le format des binaires a changé de a.out vers
ELF dans <b>Linux</b>. Normalement, vous ne verrez plus de
<code>linuxaout</code> avec une version de gcc supérieure à 2.7.0.
<a name="index.15"></a></li>
<li><code>linuxelf</code> est dépassé. Il s'agit généralement de
gcc version 2.6.3 configuré pour générer des exécutables ELF. Notez
que gcc 2.6.3 est connu pour générer de nombreuses erreurs
lorsqu'il produit du code ELF --- une mise à jour est très
fortement recommandée.</li>
</ul>
</li>
<li><code>2.7.2</code> est le numéro de la version de GCC.</li>
</ul>
<p>Donc, en résumé, nous possédons gcc 2.7.2 qui génère du code
ELF. <em>Quelle surprise</em> (NdT: En français dans le texte)
!</p>
<h2><a name="ss3.2">3.2 A quel endroit s'installe GCC ?</a></h2>
<p>Si vous avez installé gcc sans regarder, ou bien si vous l'avez
eu à partir d'une distribution, vous pouvez avoir envie de savoir
où il se trouve dans votre arborescence. Les mots clefs permettant
cela sont</p>
<ul>
<li>
<code>/usr/lib/gcc-lib/</code><em>machine-cible</em><code>/</code><em>version</em><code>/</code>
(et ses sous-répertoires) est généralement l'endroit où se trouve
le plus souvent le compilateur. Ceci inclut les exécutables qui
réalisent la compilation ainsi que certaines bibliothèques et
quelques fichiers d'en-tête.</li>
<li><code>/usr/bin/gcc</code> est le lanceur du compilateur ---
c'est en fait le programme que vous lancez. Il peut être utilisé
avec plusieurs versions de gcc lorsque vous possédez plusieurs
répertoires installés (voir plus bas). Pour trouver la version par
défaut utilisée, lancez <code>gcc -v</code>. Pour forcer
l'utilisation d'une autre version, lancez <code>gcc -V</code>
<em>version</em>. Par exemple,
<blockquote>
<pre><code>
# gcc -v
Reading specs from /usr/lib/gcc-lib/i486-zorglub-linux/2.7.2/specs
gcc version 2.7.2
# gcc -V 2.6.3 -v
Reading specs from /usr/lib/gcc-lib/i486-zorglub-linux/2.6.3/specs
gcc driver version 2.7.2 executing gcc version 2.6.3
</code></pre></blockquote>
</li>
<li>
<code>/usr/</code><em>machine-cible</em><code>/(bin|lib|include)/</code>.
Si vous avez installé plusieurs cibles possibles (par exemple a.out
et elf, ou bien un compilateur croisé, les bibliothèques, les
binutils (<code>as</code>, <code>ld</code>, etc.) et les fichiers
d'en-tête pour les cibles différente de celle par défaut peuvent
être trouvés à cet endroit. Même si vous n'avez qu'une seule
version de gcc installée, vous devriez toutefois trouver à cet
endroit un certain nombre de fichiers. Si ce n'est pas la cas,
regardez dans <code>/usr/(bin|lib|include)</code>.</li>
<li><code>/lib/</code>, <code>/usr/lib</code> et autres sont les
répertoires pour les bibliothèques pour le système initial. Vous
aurez également besoin du programme <code>/lib/cpp</code> pour un
grand nombre d'applications (X l'utilise beaucoup) --- soit vous le
copiez à partir de
<code>/usr/lib/gcc-lib/</code><em>machine-cible</em><code>/</code><em>version</em><code>/</code>,
soit vous faites pointer un lien symbolique dessus. <a name=
"index.16"></a></li>
</ul>
<h2><a name="index.17"></a> <a name="ss3.3">3.3 Où se trouvent les
fichiers d'en-tête ?</a></h2>
<p>Si l'on excepte les fichier fichiers d'en-tête que vous
installez dans le répertoire <code>/usr/local/include</code>, il y
a en fait trois types de fichiers d'en-tête :</p>
<ul>
<li>La grande majorité des fichiers situés dans le répertoire
<code>/usr/include/</code> et dans ses sous-répertoires proviennent
du paquetage de la libc dont s'occupe H.J. Lu. Je dis bien la
"grande majorité" car vous pouvez avoir également certains fichiers
provenant d'autres sources (par exemple des bibliothèques
<code>curses</code> et <code>dbm</code>), ceci est d'autant plus
vrai si vous possédez une distribution de la libc récente (où les
bibliothèques curses et dbm ne sont pas intégrées). <a name=
"index.18"></a> <a name="index.19"></a></li>
<li>Les répertoires <code>/usr/include/linux</code> et
<code>/usr/include/asm</code> (pour les fichiers
<code>&lt;linux/*.h&gt;</code> et <code>&lt;asm/*.h&gt;</code>)
doivent être des liens symboliques vers les répertoires
<code>linux/include/linux</code> et <code>linux/include/asm</code>
situés dans les sources du noyau. Vous devrez installer ces sources
si vous désirez pouvoir développer : ces sources ne sont pas
utilisés uniquement pour compiler le noyau. Il est probable que
vous ayez besoin de lancer la commande suivante <code>make
config</code> dans le répertoire des sources du noyau après les
avoir installés. Beaucoup de fichiers ont besoin du fichier
d'en-tête <code>&lt;linux/autoconf.h&gt;</code> qui n'existe pas
sans cette commande. Il est à noter que dans certaines versions du
noyau, le répertoire <code>asm</code> est en fait un lien
symbolique qui n'est créé qu'avec l'exécution de <code>make
config</code>. Donc, si vous installez les sources du noyau dans le
répertoire <code>/usr/src/linux</code>, il suffit de faire :
<blockquote>
<pre><code>
$ cd /usr/src/linux
$ su
# make config
[repondez aux questions. A moins que vous ne recompiliez votre
noyau, les reponses importent peu]
# cd /usr/include
# ln -s ../src/linux/include/linux .
# ln -s ../src/linux/include/asm .
</code></pre></blockquote>
<a name="index.20"></a> <a name="index.21"></a> <a name=
"index.22"></a> <a name="index.23"></a> <a name=
"index.24"></a></li>
<li>Les fichiers tels que <code>&lt;float.h&gt;</code>,
<code>&lt;limits.h&gt;</code>, <code>&lt;varargs.h&gt;</code>,
<code>&lt;stdarg.h&gt;</code> et <code>&lt;stddef.h&gt;</code>
changent en fonction de la version du compilateur, et peuvent être
trouvés dans le répertoire
<code>/usr/lib/gcc-lib/i486-box-linux/2.7.2/include/</code> pour la
version <code>2.7.2</code>.</li>
</ul>
<h2><a name="ss3.4">3.4 Construire un compilateur croisé</a></h2>
<h3>Linux comme plate-forme de destination</h3>
<p>Nous supposons que vous avez récupéré les sources de gcc, et
normalement, il vous suffit de suivre les instructions données dans
le fichier <code>INSTALL</code> situé dans les sources de gcc.
Ensuite, il suffit de lancer <code>configure --target=i486-linux
--host=XXX</code> sur une plateforme <code>XXX</code>, puit un
<code>make</code> devrait compiler gcc correctement. Il est à noter
que vous aurez besoin des fichiers d'en-tête de Linux, ainsi que
les sources de l'assembleur et du l'éditeur de liens croisés que
vous pouvez trouver sur <a href=
"ftp://tsx-11.mit.edu/pub/linux/packages/GCC/">ftp://tsx-11.mit.edu/pub/linux/packages/GCC/</a>
ou <a href=
"ftp://ftp.ibp.fr/pub/linux/GCC/">ftp://ftp.ibp.fr/pub/linux/GCC/</a>.</p>
<h3>Linux comme plate-forme origine et MSDOS comme destination</h3>
<p>Arggg. Apparemment, cela est possible en utilisant le paquetage
� emx � ou l'extension � go �. Regardez <a href=
"ftp://sunsite.unc.edu/pub/Linux/devel/msdos">ftp://sunsite.unc.edu/pub/Linux/devel/msdos</a>
pour plus d'informations.</p>
<p>Je n'ai pas testé cela et je ne pense pas le faire !</p>
<h2><a name="s4">4. Portage et compilation</a></h2>
<h2><a name="index.25"></a> <a name="ss4.1">4.1 Symboles définis
automatiquement</a></h2>
<p>Vous pouvez trouver quels symboles votre version de gcc définit
automatiquement en le lançant avec l'option <code>-v</code>. Par
exemple cela donne ça chez moi :</p>
<blockquote>
<pre><code>
$ echo 'main(){printf("Bonjour !\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__ -
</code></pre></blockquote>
Si vous écrivez du code qui utilise des spécificités Linux, il est
souhaitable d'implémenter le code non portable de la manière
suivante
<blockquote>
<pre><code>
#ifdef __linux__
/* ... code linux ... */
#endif /* linux */
</code></pre></blockquote>
<p>Utilisez <code>__linux__</code> pour cela, et <em>pas</em>
<code>linux</code>. Bien que cette macro soit définie, ce n'est pas
une spécification POSIX.</p>
<h2><a name="ss4.2">4.2 Options de compilation</a></h2>
<p>La documentation des options de compilation se trouve dans les
pages <em>info</em> de gcc (sous Emacs, utilisez <code>C-h i</code>
puis sélectionnez l'option `gcc'). Votre distribution peut ne pas
avoir installé la documentation ou bien vous pouvez en avoir une
ancienne. Dans ce cas, la meilleure chose à faire est de récupérer
les sources de gcc depuis <a href=
"ftp://prep.ai.mit.edu/pub/gnu">ftp://prep.ai.mit.edu/pub/gnu</a>
ou l'un des ses nombreux miroirs dont <a href=
"ftp://ftp.ibp.fr/pub/gnu">ftp://ftp.ibp.fr/pub/gnu</a>.</p>
<p>La page de manuel gcc (<code>gcc.1</code>) est en principe,
complètement dépassée. Cela vous met en garde si vous désirez la
consulter.</p>
<h3><a name="index.27"></a> <a name="index.26"></a> Options de
compilation</h3>
<p>gcc peut réaliser un certain nombre d'optimisations sur le code
généré en ajoutant l'option <code>-O</code><em>n</em> à la ligne de
commandes, où <em>n</em> est un chiffre. La valeur de <em>n</em>,
et son effet exact, dépend de la version de gcc, mais s'échelonne
normalement entre 0 (aucune optimisation) et 2 (un certain nombre)
ou 3 (toutes les optimisations possibles).</p>
<p>En interne, gcc interprète les options telles que
<code>-f</code> et <code>-m</code>. Vous pouvez voir exactement ce
qu'effectue le niveau spécifié dans l'option <code>-O</code> en
lançant gcc avec l'option <code>-v</code> et l'option (non
documentée) <code>-Q</code>. Par exemple, l'option
<code>-O2</code>, effectue les opérations suivantes sur ma machine
:</p>
<blockquote>
<pre><code>
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
</code></pre></blockquote>
<p>Utiliser un niveau d'optimisation supérieur à celui que le
compilateur supporte (par exemple <code>-O6</code>) aura le même
effet qu'utiliser le plus haut niveau géré. Distribuer du code où
la compilation est configurée de cette manière est une très
mauvaise idée -- si d'autres optimisations sont incorporées dans de
versions futures, vous (ou d'autres utilisateurs) pouvez vous
apercevoir que cela ne compile plus, ou bien que le code généré ne
fait pas les actions désirées.</p>
<p><a name="index.28"></a> Les utilisateurs de gcc 2.7.0 à 2.7.2
devraient noter qu'il y a un bogue dans l'option <code>-O2</code>.
Plus précisément, la <em>strength reduction</em> ne fonctionne pas.
Un patch a été implémenté pour résoudre ce problème, mais vous
devez alors recompiler gcc. Sinon, vous devrez toujours compiler
avec l'option <code>-fno-strength-reduce</code>.</p>
<h3>Spécification du processeur</h3>
<p>Il existe d'autres options <code>-m</code> qui ne sont pas
positionnées lors de l'utilisation de <code>-O</code> mais qui sont
néanmoins utiles dans certains cas. C'est le cas pour les options
<code>-m386</code> et <code>-m486</code>, qui indiquent à gcc de
générer un code plus ou moins optimisé pour l'un ou l'autre type de
processeur. Le code continuera à fonctionner sur les deux
processeurs. Bien que le code pour 486 soit plus important, il ne
ralentit pas l'exécution du programme sur 386.</p>
<p>Il n'existe pas actuellement de <code>-mpentium</code> ou
<code>-m586</code>. Linus a suggéré l'utilisation des options
<code>-m486 -malign-loops=2 -malign-jumps=2
-malign-functions=2</code>, pour exploiter les optimisations du 486
tout en perdant de la place due aux problèmes d'alignements (dont
le Pentium n'a que faire). Michael Meissner (de Cygnus) nous dit
:</p>
<blockquote>� Mon avis est que l'option
<code>-mno-strength-reduce</code> permet d'obtenir un code plus
rapide sur un x86 (nota : je ne parle pas du bogue <em>strength
reduction</em>, qui est un autre problème). Cela s'explique en
raison du peu de registres dont disposent ces processeurs (et la
méthode de GCC qui consiste à grouper les registres dans l'ordre
inverse au lieu d'utiliser d'autres registres n'arrange rien). La
<em>strength reduction</em> consiste en fait à rajouter des
registres pour remplacer les multiplications par des additions. Je
suspecte également <code>-fcaller-saves</code> de ne pas arranger
la situation. �</blockquote>
<blockquote>Une autre idée est que
<code>-fomit-frame-pointer</code> n'est pas obligatoirement une
bonne idée. D'un côté, cela peut signifier qu'un autre registre est
disponible pour une allocation. D'un autre côté, vue la manière
dont les processeurs x86 codent leur jeu d'instruction, cela peut
signifier que la pile des adresses relatives prend plus de place
que les adresses de fenêtres relatives, ce qui signifie en clair
que moins de cache est disponible pour l'exécution du processus. Il
faut préciser que l'option <code>-fomit-frame-pointer</code>,
signifie que le compilateur doit constamment ajuster le pointeur de
pile après les appels, alors qu'avec une fenêtre, il peut laisser
plusieurs appels dans la pile.</blockquote>
<p>Le mot final sur le sujet provient de Linus :</p>
<blockquote>Remarquez que si vous voulez des performances
maximales, ne me croyez pas : testez ! Il existe tellement
d'options de gcc, et il est possible que cela ne soit une réelle
optimisation que pour vous.</blockquote>
<h3><a name="index.33"></a> <a name="index.32"></a> <a name=
"index.31"></a> <a name="index.30"></a> <a name="index.29"></a>
<code>Internal compiler error: cc1 got fatal signal 11</code></h3>
<p>Signal 11 correspond au signal SIGSEGV, ou bien <em>segmentation
violation</em>. Normalement, cela signifie que le programme s'est
mélangé les pointeurs et a essayé d'écrire là où il n'en a pas le
droit. Donc, cela pourrait être un bug de gcc.</p>
<p>Toutefois, gcc est un logiciel assez testé et assez remarquable
de ce côté. Il utilise un grand nombre de structures de données
complexes, et un nombre impressionnant de pointeurs. En résumé,
c'est le plus pointilleux des testeurs de mémoire existants. Si
vous <em>n'arrivez pas à reproduire le bogue</em> --- si cela ne
s'arrête pas au même endroit lorsque vous retentez la compilation
--- c'est plutôt un problème avec votre machine (processeur,
mémoire, carte mère ou bien cache). <b>N'annoncez pas</b> la
découverte d'un nouveau bogue si votre ordinateur traverse tous les
tests du BIOS, ou s'il fonctionne correctement sous Windows ou
autre : ces tests ne valent rien. Il en va de même si le noyau
s'arrête lors du `<code>make zImage</code>' ! `<code>make
zImage</code>' doit compiler plus de 200 fichiers, et il en faut
bien moins pour arriver à faire échouer une compilation.</p>
<p>Si vous arrivez à reproduire le bogue et (mieux encore) à écrire
un petit programme qui permet de mettre en évidence cette erreur,
alors vous pouvez envoyer le code soit à la FSF, soit dans la liste
linux-gcc. Consultez la documentation de gcc pour plus de détails
concernant les informations nécessaires.</p>
<h2><a name="ss4.3">4.3 Portabilité</a></h2>
<p>Cette phrase a été dite un jour : si quelque chose n'a pas été
porté vers Linux alors ce n'est pas important de l'avoir :-).</p>
<p>Plus sérieusement, en général seules quelques modifications
mineures sont nécessaires car Linux répond à 100% aux
spécifications POSIX. Il est généralement sympathique d'envoyer à
l'auteur du programme les modifications effectuées pour que le
programme fonctionne sur Linux, pour que lors d'une future version,
un `make' suffise pour générer l'exécutable.</p>
<h3>Spécificités BSD (notamment <code>bsd_ioctl</code>,
<code>daemon</code> et <code>&lt;sgtty.h&gt;</code>)</h3>
<p>Vous pouvez compiler votre programme avec l'option
<code>-I/usr/include/bsd</code> et faire l'édition de liens avec
<code>-lbsd</code> (en ajoutant <code>-I/usr/include/bsd</code> à
la ligne <code>CFLAGS</code> et <code>-lbsd</code> à la ligne
<code>LDFLAGS</code> dans votre fichier <code>Makefile</code>). Il
est également nécessaire de ne <b>pas</b> ajouter
<code>-D__USE_BSD_SIGNAL</code> si vous voulez que les signaux BSD
fonctionnent car vous les avez inclus automatiquement avec la ligne
<code>-I/usr/include/bsd</code> et en incluant le fichier d'en-tête
<code>&lt;signal.h&gt;</code>.</p>
<h3><a name="index.38"></a> <a name="index.37"></a> <a name=
"index.36"></a> <a name="index.35"></a> <a name="index.34"></a>
Signaux <em>manquants</em> (<code>SIGBUS</code>,
<code>SIGEMT</code>, <code>SIGIOT</code>, <code>SIGTRAP</code>,
<code>SIGSYS</code>, etc.)</h3>
<p>Linux respecte les spécifications POSIX. Ces signaux n'en font
pas partie (cf. ISO/IEC 9945-1:1990 - IEEE Std 1003.1-1990,
paragraphe B.3.3.1.1) :</p>
<blockquote>� Les signaux SIGBUS, SIGEMT, SIGIOT, SIGTRAP, et
SIGSYS ont été omis de la norme POSIX.1 car leur comportement est
dépendant de l'implémentation et donc ne peut être répertorié d'une
manière satisfaisante. Certaines implémentations peuvent fournir
ces signaux mais doivent documenter leur effet �</blockquote>
<p>La manière la plus élégante de régler ce problème est de
redéfinir ces signaux à <code>SIGUNUSED</code>. La manière
<em>normale</em> de procéder est d'entourer le code avec les
<code>#ifdef</code> appropriés :</p>
<blockquote>
<pre><code>
#ifdef SIGSYS
/* ... code utilisant les signaux non posix  .... */
#endif
</code></pre></blockquote>
<h3><a name="index.39"></a> Code K &amp; R</h3>
<p>GCC est un compilateur ANSI, or il existe beaucoup de code qui
ne soit pas ANSI.</p>
<p>Il n'y a pas grand chose à faire, sauf rajouter l'option
<code>-traditional</code> lors de la compilation. Il effectue
certaines vérifications supplémentaires. Consultez les pages info
gcc.</p>
<p>Notez que l'option <code>-traditional</code> a pour unique effet
de changer la forme du langage accepté par gcc. Par exemple, elle
active l'option <code>-fwritable-strings</code>, qui déplace toutes
les chaînes de caractères vers l'espace de données (depuis l'espace
de texte, où elle ne peuvent pas être modifiées). Ceci augmente la
taille de la mémoire occupée par le programme.</p>
<h3><a name="index.41"></a> <a name="index.40"></a> Les symboles du
préprocesseur produisent un conflit avec les prototypes du
code</h3>
<p>Un des problèmes fréquents se produit lorsque certaines
fonctions standards sont définies comme macros dans les fichiers
d'en-tête de Linux et le préprocesseur refusera de traiter des
prototypes identiques. Par exemple, cela peut arriver avec
<code>atoi()</code> et <code>atol()</code>.</p>
<h3><a name="index.42"></a> <code>sprintf()</code></h3>
<p>Parfois, soyez prudent lorsque vous effectuez un portage à
partir des sources de programmes fonctionnant sous SunOs, surtout
avec la fonction <code>sprintf(string, fmt, ...)</code> car elle
renvoie un pointeur sur la chaîne de caractères alors que Linux
(suivant la norme ANSI) retourne le nombre de caractères recopiés
dans la chaîne de caractères.</p>
<h3><a name="index.49"></a> <a name="index.48"></a> <a name=
"index.47"></a> <a name="index.46"></a> <a name="index.45"></a>
<a name="index.44"></a> <a name="index.43"></a> <code>fcntl</code>
et ses copains. Où se trouve la définition de <code>FD_*</code> et
compagnie ?</h3>
<p>Dans <code>&lt;sys/time.h&gt;</code>. Si vous utilisez
<code>fcntl</code> vous voudrez probablement inclure
<code>&lt;unistd.h&gt;</code> également, pour avoir le prototype de
la fonction.</p>
<p>D'une manière générale, la page de manuel pour une fonction
donne la liste des fichiers d'en-tête à inclure.</p>
<h3><a name="index.50"></a> Le timeout de <code>select()</code>.
Les programmes commencent dans un état d'attente active</h3>
<p>A une certaine époque, le paramètre timeout de la fonction
<code>select()</code> était utilisé en lecture seule. C'est
pourquoi la page de manuel comporte une mise en garde :</p>
<blockquote>select() devrait retourner normalement le temps écoulé
depuis le timeout initial, s'il s'est déclenché, en modifiant la
valeur pointée par le paramètre <code>time</code>. Cela sera
peut-être implémenté dans les versions ultérieures du système.
Donc, il n'est pas vraiment prudent de supposer que les données
pointées ne seront pas modifiées lors de l'appel à
select().</blockquote>
<p>Mais tout arrive avec le temps ! Lors d'un retour de
<code>select()</code>, l'argument <code>timeout</code> recevra le
temps écoulé depuis la dernière réception de données. Si aucune
donnée n'est arrivée, la valeur sera nulle, et les futurs appels à
cette fonction utilisant le même <code>timeout</code> auront pour
résultat un retour immédiat.</p>
<p>Pour résoudre le problème, il suffit de mettre la valeur
<code>timeout</code> dans la structure à chaque appel de
<code>select()</code>. Le code initial était</p>
<blockquote>
<pre><code>
      struct timeval timeout;
      timeout.tv_sec = 1; 
      timeout.tv_usec = 0;
      while (some_condition)
            select(n,readfds,writefds,exceptfds,&amp;timeout); 
</code></pre></blockquote>
et doit devenir :
<blockquote>
<pre><code>
      struct timeval timeout;
      while (some_condition) 
      {
            timeout.tv_sec = 1; 
            timeout.tv_usec = 0;
            select(n,readfds,writefds,exceptfds,&amp;timeout);
      }
</code></pre></blockquote>
<p>Certaines versions de Mosaic étaient connues à une certaine
époque pour avoir ce problème.</p>
<p>La vitesse de rotation du globe terrestre était inversement
proportionnelle à la vitesse de transfert des données !</p>
<h3><a name="index.52"></a> <a name="index.51"></a> Appels systèmes
interrompus</h3>
<h3>Symptomes :</h3>
<p>Lorsqu'un processus est arrêté avec un Ctrl-Z et relancé - ou
bien lorsqu'un autre signal est déclenché dans une situation
différente : par exemple avec un Ctrl-C, la terminaison d'un
processus, etc, on dit qu'il y a � interruption d'un appel système
� , ou bien � write : erreur inconnue � ou des trucs de ce
genre.</p>
<h3>Problèmes :</h3>
<p>Les systèmes POSIX vérifient les signaux plus souvent que
d'autres Unix plus anciens. Linux peux lancer les gestionnaires de
signaux :</p>
<ul>
<li>d'une manière asynchrone (sur un top d'horloge)</li>
<li>lors d'un retour de n'importe quel appel système</li>
<li>pendant l'exécution des appels systèmes suivants :
<code>select()</code>, <code>pause()</code>,
<code>connect()</code>, <code>accept()</code>, <code>read()</code>
sur des terminaux, des sockets, des pipes ou des fichiers situés
dans <code>/proc</code>, <code>write()</code> sur des terminaux,
des sockets, des pipes ou des imprimantes, <code>open()</code> sur
des FIFOs, des lignes PTYs ou séries, <code>ioctl()</code> sur des
terminaux, <code>fcntl()</code> avec la commande
<code>F_SETLKW</code>, <code>wait4()</code>, <code>syslog()</code>,
et toute opération d'ordre TCP ou NFS.</li>
</ul>
<p>Sur d'autres systèmes d'exploitation, il est possible que vous
ayez à inclure dans cette catégorie les appels systèmes suivants :
<code>creat()</code>, <code>close()</code>, <code>getmsg()</code>,
<code>putmsg()</code>, <code>msgrcv()</code>,
<code>msgsnd()</code>, <code>recv()</code>, <code>send()</code>,
<code>wait()</code>, <code>waitpid()</code>, <code>wait3()</code>,
<code>tcdrain()</code>, <code>sigpause()</code>,
<code>semop()</code>.</p>
<p>Si un signal (que le programme désire traiter) est lancé pendant
l'exécution d'un appel système, le gestionnaire est lancé. Lorsque
le gestionnaire du signal se termine, l'appel système détecte qu'il
a été interrompu et se termine avec la valeur -1 et <code>errno =
EINTR</code>. Le programme n'est pas forcément au courant de ce qui
s'est passé et donc s'arrête.</p>
<p>Vous pouvez choisir deux solutions pour résoudre ce
problème.</p>
<p>(1)Dans tout gestionnaire de signaux que vous mettez en place,
ajoutez l'option <code>SA_RESTART</code> au niveau de
<em>sigaction</em>. Par exemple, modifiez</p>
<blockquote>
<pre><code>
  signal (signal_id, mon_gestionnaire_de_signaux);
</code></pre></blockquote>
en
<blockquote>
<pre><code>
  signal (signal_id, mon_gestionnaire_de_signaux);
  { 
        struct sigaction sa;
        sigaction (signal_id, (struct sigaction *)0, &amp;sa);
#ifdef SA_RESTART
        sa.sa_flags |= SA_RESTART;
#endif
#ifdef SA_INTERRUPT
        sa.sa_flags &amp;= ~ SA_INTERRUPT;
#endif
        sigaction (signal_id, &amp;sa, (struct sigaction *)0);
  }
</code></pre></blockquote>
<p>Notez que lors de certains appels systèmes vous devrez souvent
regarder si <code>errno</code> n'a pas été positionnée à
<code>EINTR</code> par vous même comme avec <code>read()</code>,
<code>write()</code>, <code>ioctl()</code>, <code>select()</code>,
<code>pause()</code> et <code>connect()</code>.</p>
<p>(2) A la recherche de <code>EINTR</code> :</p>
<p>Voici deux exemples avec <code>read()</code> et
<code>ioctl()</code>,</p>
<p>Voici le code original utilisant <code>read()</code></p>
<blockquote>
<pre><code>
int result;
while (len &gt; 0) 
{ 
  result = read(fd,buffer,len);
  if (result &lt; 0) 
        break;
  buffer += result; 
  len -= result;
}
</code></pre></blockquote>
et le nouveau code
<blockquote>
<pre><code>
int result;
while (len &gt; 0) 
{ 
  result = read(fd,buffer,len);
  if (result &lt; 0) 
  { 
        if (errno != EINTR) 
                break; 
  }
  else 
  { 
        buffer += result; 
        len -= result; 
  }
}
</code></pre></blockquote>
Voici un code utilisant <code>ioctl()</code>
<blockquote>
<pre><code>
int result;
result = ioctl(fd,cmd,addr);
</code></pre></blockquote>
et cela devient
<blockquote>
<pre><code>
int result;
do 
{ 
   result = ioctl(fd,cmd,addr); 
}
while ((result == -1) &amp;&amp; (errno == EINTR));
</code></pre></blockquote>
<p>Il faut remarquer que dans certaines versions d'Unix de type BSD
on a l'habitude de relancer l'appel système. Pour récupérer les
interruptions d'appels systèmes, vous devez utiliser les options
<code>SV_INTERRUPT</code> ou <code>SA_INTERRUPT</code>.</p>
<h3><a name="index.56"></a> <a name="index.55"></a> <a name=
"index.54"></a> <a name="index.53"></a> Les chaînes et leurs accès
en écritures (ou les programmes qui provoquent des � segmentation
fault � d'une manière aléatoire)</h3>
<p>GCC a une vue optimiste en ce qui concerne ses utilisateurs, en
croyant qu'ils respectent le fait qu'une chaîne dite constante
l'est réellement. Donc, il les range dans la zone
<em>texte(code)</em> du programme, où elles peuvent être chargées
puis déchargées à partir de l'image binaire de l'exécutable située
sur disque (ce qui évite d'occuper de l'espace disque). Donc, toute
tentative d'écriture dans cette chaîne provoque un � segmentation
fault �.</p>
<p>Cela peut poser certains problèmes avec d'anciens codes, par
exemple ceux qui utilisent la fonction <code>mktemp()</code> avec
une chaîne constante comme argument. <code>mktemp()</code> essaye
d'écrire dans la chaîne passée en argument.</p>
<p>Pour résoudre ce problème,</p>
<ol>
<li>compilez avec l'option <code>-fwritable-strings</code> pour
indiquer à gcc de mettre les chaînes constantes dans l'espace de
données</li>
<li>réécrire les différentes parties du code pour allouer une
chaîne non constante puis effectuer un strcpy des données dedans
avant d'effectuer l'appel.</li>
</ol>
<h3><a name="index.57"></a> Pourquoi l'appel à <code>execl()</code>
échoue ?</h3>
<p>Tout simplement parce que vous l'utilisez mal. Le premier
argument d'<code>execl</code> est le programme que vous désirez
exécuter. Le second et ainsi de suite sont en fait le éléments du
tableau <code>argv</code> que vous appelez. Souvenez-vous que
<code>argv[0]</code> est traditionnellement fixé même si un
programme est lancé sans argument. Vous devriez donc écrire :</p>
<blockquote>
<pre><code>
execl("/bin/ls","ls",NULL);
</code></pre></blockquote>
et pas
<blockquote>
<pre><code>
execl("/bin/ls", NULL);
</code></pre></blockquote>
<p>Lancer le programme sans argument est considéré comme étant une
demande d'affichage des bibliothèques dynamiques associées au
programme, si vous utilisez le format a.out. ELF fonctionne d'une
manière différente.</p>
<p>(Si vous désirez ces informations, il existe des outils plus
simples; consultez la section sur le chargement dynamique, ou la
page de manuel de <code>ldd</code>).</p>
<h2><a name="s5">5. Déboguer et optimiser</a></h2>
<h2><a name="index.58"></a> <a name="ss5.1">5.1 Etude préventive du
code (lint)</a></h2>
<p>Il n'existe pas de lint qui soit réellement utilisable, tout
simplement parce que la grande majorité des développeurs sont
satisfaits des messages d'avertissement de gcc. Il est probable que
l'option la plus utile est l'option <code>-Wall</code> --- qui a
pour effet d'afficher tous les avertissements possibles.</p>
<p>Il existe une version du domaine public du programme lint que
vous pouvez trouver à l'adresse suivante : <a href=
"ftp://larch.lcs.mit.edu/pub/Larch/lclint">ftp://larch.lcs.mit.edu/pub/Larch/lclint</a>.
Je ne sais pas ce qu'elle vaut.</p>
<h2><a name="index.59"></a> <a name="ss5.2">5.2 Déboguer</a></h2>
<h3><a name="index.62"></a> <a name="index.61"></a> <a name=
"index.60"></a> Comment rendre débogable un programme ?</h3>
<p>Vous devez compiler et effectuer l'édition de liens avec
l'option <code>-g</code>, et sans l'option
<code>-fomit-frame-pointer</code>. En fait, vous ne devez compiler
que les modules que vous avez besoin de déboguer.</p>
<p>Si vous possédez un système a.out, les bibliothèques dynamiques
sont compilées avec l'option <code>-fomit-frame-pointer</code>, que
gcc ne peut pas gérer. Lorsque vous compilez avec l'option
<code>-g</code>, alors par défaut vous effectuez une édition de
liens statique, ce qui permet de résoudre le problème.</p>
<p>Si l'éditeur de liens échoue avec un message disant qu'il
n'arrive pas à trouver la bibliothèque libg.a, c'est que vous ne
possédez pas la bibliothèque <code>/usr/lib/libg.a</code>, qui est
la bibliothèque C standard permettant le débogage. Cette
bibliothèque est fournie dans le paquetage des binaires de la
libc., ou (dans les nouvelles versions) vous aurez besoin de
récupérer le source et de le compiler vous-même. Vous n'avez pas
réellement besoin de cela en fait, vous pouvez faire un lien
logique vers <code>/usr/lib/libc.a</code></p>
<h3><a name="index.63"></a> Comment réduire la taille des
exécutables ?</h3>
<p>Bon nombre de produits GNU sont fournis pour compiler avec
l'option <code>-g</code>, ce qui génère des exécutables d'une
taille très importante (et souvent l'édition de liens s'effectue
d'une manière statique). Ce n'est pas une idée lumineuse...</p>
<p>Si le programme possède le script <code>configure</code> généré
par autoconf, vous pouvez modifier les options de débogage en
effectuant un <code>./configure CFLAGS=</code> ou <code>./configure
CFLAGS=-O2</code>. Sinon, vous pouvez aller modifier le Makefile.
Bien sûr, si vous utilisez le format ELF, l'édition de liens sera
effectuée de manière dynamique même avec l'option <code>-g</code>.
Dans ce cas, vous pouvez effectuer un strip sur l'exécutable.</p>
<h3><a name="index.64"></a> Programmes disponibles</h3>
<p>Beaucoup de gens utilisent <b>gdb</b>, que vous pouvez récupérer
sur le site <a href=
"ftp://prep.ai.mit.edu/pub/gnu">prep.ai.mit.edu</a>, sous une forme
binaire sur <a href=
"ftp://tsx-11.mit.edu/pub/linux/packages/GCC">tsx-11</a> ou sur
sunsite. <b>xxgdb</b> est une surcouche X de gdb (c.a.d. que vous
avez besoin de gdb pour utiliser xxgdb). Les sources peuvent être
récupérés sur <a href=
"ftp://ftp.x.org/contrib/xxgdb-1.08.tar.gz">ftp://ftp.x.org/contrib/xxgdb-1.08.tar.gz</a></p>
<p>Il existe également le débogueur <b>UPS</b> qui a été porté par
Rick Sladkey. Il fonctionne sous X également, mais à la différence
d'xxgdb, ce n'est qu'une surcouche X pour un débogueur en mode en
texte. Il possède certaines caractéristiques très intéressantes et
si vous utilisez beaucoup ce genre d'outils, vous l'essayerez
sûrement. Les patches ainsi que des versions précompilées pour
Linux peuvent être trouvées sur <a href=
"ftp://sunsite.unc.edu/pub/Linux/devel/debuggers/">ftp://sunsite.unc.edu/pub/Linux/devel/debuggers/</a>,
et les sources peuvent être récupérés sur <a href=
"ftp://ftp.x.org/contrib/ups-2.45.2.tar.Z">ftp://ftp.x.org/contrib/ups-2.45.2.tar.Z</a>.</p>
<p>Un autre outil que vous pouvez trouver utile pour déboguer est �
<b>strace</b> � , qui affiche les appels systèmes que le processus
lance. Il possède d'autres caractéristiques telles que donner les
chemins d'accès où ont été compilés les binaires, donner les temps
passés dans chacun des appels systèmes, et il vous permet également
de connaître les résultats des appels. La dernière version de
strace (actuellement la version 3.0.8) peut être trouvée sur
<a href=
"ftp://ftp.std.com/pub/jrs/">ftp://ftp.std.com/pub/jrs/</a>.</p>
<h3>Programmes en tâche de fond (démon)</h3>
<p>Les démons lancent typiquement un <code>fork()</code> dès leur
lancement et terminent donc le père. Cela fait une session de
déboguage très courte.</p>
<p>La manière la plus simple de résoudre ce problème est de poser
un point d'arrêt sur <code>fork</code>, et lorsque le programme
s'arrête, forcer le retour à 0.</p>
<blockquote>
<pre><code>
(gdb) list 
1       #include &lt;stdio.h&gt;
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
Single stepping until exit from function fork, 
which has no line number information.
child
7       }
</code></pre></blockquote>
<h3>Fichiers core</h3>
<p>Lorsque Linux se lance, il n'est généralement pas configuré pour
produire des fichiers core. Si vous les voulez vous devez utiliser
votre shell pour ça en faisant sous csh (ou tcsh) :</p>
<blockquote>
<pre><code>
% limit core unlimited
</code></pre></blockquote>
avec sh, bash, zsh, pdksh, utilisez
<blockquote>
<pre><code>
$ ulimit -c unlimited
</code></pre></blockquote>
<p>Si vous voulez pousser le vice à nommer votre fichier core (par
exemple si vous utilisez un débogueur bogué... ce qui est un
comble) vous pouvez simplement modifier le noyau. Editez les
fichiers <code>fs/binfmt_aout.c</code> et
<code>fs/binfmt_elf.c</code> (dans les nouveaux noyaux, vous devrez
chercher ailleurs) :</p>
<blockquote>
<pre><code>
        memcpy(corefile,"core.",5);
#if 0
        memcpy(corefile+5,current-&gt;comm,sizeof(current-&gt;comm));
#else
        corefile[4] = '\0';
#endif
</code></pre></blockquote>
<p>et changez les <code>0</code> par des <code>1</code>.</p>
<h2><a name="ss5.3">5.3 Caractéristiques du programme</a></h2>
<p>Il est possible d'examiner un peu le programme pour savoir quels
sont les appels de fonctions qui sont effectués le plus souvent ou
bien qui prennent du temps. C'est une bonne manière d'optimiser le
code en déterminant là où l'on passe le plus de temps. Vous devez
compiler tous les objets avec l'option <code>-p</code>, et pour
mettre en forme la sortie écran, vous aurez besoin du programme
<code>gprof</code> (situé dans les <code>binutils</code>).
Consultez les pages de manuel <code>gprof</code> pour plus de
détails.</p>
<h2><a name="s6">6. Edition de liens</a></h2>
<p>Entre les deux formats de binaires incompatibles, bibliothèques
statiques et dynamiques, on peut comparer l'opération d'édition de
lien en fait à un jeu ou l'on se demanderait qu'est-ce qui se passe
lorsque je lance le programme ? Cette section n'est pas vraiment
simple...</p>
<p>Pour dissiper la confusion qui règne, nous allons nous baser sur
ce qui se passe lors d'exécution d'un programme, avec le chargement
dynamique. Vous verrez également la description de l'édition de
liens dynamiques, mais plus tard. Cette section est dédiée à
l'édition de liens qui intervient à la fin de la compilation.</p>
<h2><a name="ss6.1">6.1 Bibliothèques partagées contre
bibliothèques statiques</a></h2>
<p>La dernière phase de construction d'un programme est de réaliser
l'édition de liens, ce qui consiste à assembler tous les morceaux
du programme et de chercher ceux qui sont manquants. Bien
évidement, beaucoup de programmes réalisent les mêmes opérations
comme ouvrir des fichiers par exemple, et ces pièces qui réalisent
ce genre d'opérations sont fournies sous la forme de bibliothèques.
Sous Linux, ces bibliothèques peuvent être trouvées dans les
répertoires <code>/lib</code> et<code>/usr/lib/</code> entre
autres.</p>
<p><a name="index.65"></a> <a name="index.66"></a></p>
<p>Lorsque vous utilisez une bibliothèque statique, l'éditeur de
liens cherche le code dont votre programme a besoin et en effectue
une copie dans le programme physique généré. Pour les bibliothèques
partagées, c'est le contraire : l'éditeur de liens laisse du code
qui lors du lancement du programme chargera automatiquement la
bibliothèque. Il est évident que ces bibliothèques permettent
d'obtenir un exécutable plus petit; elles permettent également
d'utiliser moins de mémoire et moins de place disque. Linux
effectue par défaut une édition de liens dynamique s'il peut
trouver les bibliothèques de ce type sinon, il effectue une édition
de liens statique. Si vous obtenez des binaires statiques alors que
vous les voulez dynamiques vérifiez que les bibliothèques existent
(<code>*.sa</code> pour le format a.out, et <code>*.so</code> pour
le format ELF) et que vous possédez les droits suffisants pour y
accéder (lecture).</p>
<p>Sous Linux, les bibliothèques statiques ont pour nom
<code>libnom.a</code>, alors que les bibliothèques dynamiques sont
appelées <code>libnnom.so.x.y.z</code><code>x.y.z</code>
représente le numéro de version. Les bibliothèques dynamiques ont
souvent des liens logiques qui pointent dessus, et qui sont très
importants. Normalement, les bibliothèques standards sont livrées
sous la double forme dynamique et statique.</p>
<p>Vous pouvez savoir de quelles bibliothèques dynamiques un
programme a besoin en utilisant la commande <code>ldd</code>
(<em>List Dynamic Dependencies</em>)</p>
<blockquote>
<pre><code>
$ ldd /usr/bin/lynx
        libncurses.so.1 =&gt; /usr/lib/libncurses.so.1.9.6
        libc.so.5 =&gt; /lib/libc.so.5.2.18
</code></pre></blockquote>
<p>Cela indique sur mon système que l'outil <code>lynx</code>
(outil WWW) a besoin des bibliothèques dynamiques
<code>libc.so.5</code> (la bibliothèque C) et de
<code>libncurses.so.1</code> (nécessaire pour le contrôle du
terminal). Si un programme ne possède pas de dépendances,
<code>ldd</code> indiquera `<em>statically linked</em>' (édition de
liens statique).</p>
<h2><a name="index.69"></a> <a name="index.68"></a> <a name=
"index.67"></a> <a name="ss6.2">6.2 A la recherche des fonctions...
ou dans quelle bibliothèque se trouve la fonction
<code>sin()</code> ?')</a></h2>
<p><code>nm</code> <em>nomdebibliothèque</em> vous donne tous les
symboles référencés dans la bibliothèque. Cela fonctionne que cela
soit du code statique ou dynamique. Supposez que vous vouliez
savoir où se trouve définie la fonction <code>tcgetattr()</code>
:</p>
<blockquote>
<pre><code>
$ nm libncurses.so.1 |grep tcget
         U tcgetattr
</code></pre></blockquote>
<p>La lettre <code>U</code> vous indique que c'est indéfini
(<em>Undefined</em>) --- cela indique que la bibliothèque ncurses
l'utilise mais ne la définit pas. Vous pouvez également faire :</p>
<blockquote>
<pre><code>
$ nm libc.so.5 | grep tcget
00010fe8 T __tcgetattr
00010fe8 W tcgetattr
00068718 T tcgetpgrp
</code></pre></blockquote>
<p>La lettre `<code>W</code>' indique que le symbole est défini
mais de telle manière qu'il peut être surchargé par une autre
définition de la fonction dans une autre bibliothèque (W pour
<em>weak</em> : faible). Une définition normale est marquée par la
lettre `<code>T</code>' (comme pour <code>tcgetpgrp</code>).</p>
<p><a name="index.70"></a></p>
<p>La réponse à la question située dans le titre est
<code>libm.(so|a)</code>. Toutes les fonctions définies dans le
fichier d'en-tête <code>&lt;math.h&gt;</code> sont implémentées
dans la bibliothèque mathématique donc vous devrez effectuer
l'édition de liens grâce à <code>-lm</code>.</p>
<h2><a name="ss6.3">6.3 Trouver les fichiers</a></h2>
<p>Supposons que vous ayez le message d'erreur suivant de la part
de l'éditeur de liens :</p>
<p><code>ld: Output file requires shared library
`libfoo.so.1`</code></p>
<p>La stratégie de recherche de fichiers de ld ou de ses copains
diffère de la version utilisée, mais vous pouvez être sûr que les
fichiers situés dans le répertoire <code>/usr/lib</code> seront
trouvés. Si vous désirez que des fichiers situés à un endroit
différent soient trouvés, il est préférable d'ajouter l'option
<code>-L</code> à gcc ou ld.</p>
<p>Si cela ne vous aide pas clairement, vérifiez que vous avez le
bon fichier à l'endroit spécifié. Pour un système a.out, effectuer
l'édition de liens avec <code>-ltruc</code> implique que ld
recherche les bibliothèques <code>libtruc.sa</code> (bibliothèques
partagées), et si elle n'existe pas, il recherche
<code>libtruc.a</code> (statique). Pour le format ELF, il cherche
<code>libtruc.so</code> puis <code>libtruc.a</code>.
<code>libtruc.so</code> est généralement un lien symbolique vers
<code>libtruc.so.x</code>.</p>
<h2><a name="ss6.4">6.4 Compiler votre propre bibliothèque</a></h2>
<h3>Numéro de la version</h3>
<p>Comme tout programme, les bibliothèques ont tendance à avoir
quelques bogues qui sont corrigés au fur et à mesure. De nouvelles
fonctionnalités sont ajoutées et qui peuvent changer l'effet de
celles qui existent ou bien certaines anciennes peuvent êtres
supprimées. Cela peut être un problème pour les programmes qui les
utilisent.</p>
<p>Donc, nous introduisons la notion de numéro de version. Nous
répertorions les modifications effectuées dans la bibliothèques
comme étant soit mineures soit majeures. Cela signifie qu'une
modification mineure ne peut pas modifier le fonctionnement d'un
programme (en bref, il continue à fonctionner comme avant). Vous
pouvez identifier le numéro de la version de la bibliothèque en
regardant son nom (en fait c'est un mensonge pour les bibliothèques
ELF... mais continuez à faire comme si !) :
<code>libtruc.so.1.2</code> a pour version majeure 1 et mineure 2.
Le numéro de version mineur peut être plus ou moins élevé --- la
bibliothèque C met un numéro de patch, ce qui produit un nom tel
que <code>libc.so.5.2.18</code>, et c'est également courant d'y
trouver des lettres ou des blancs soulignés ou tout autre caractère
ASCII affichable.</p>
<p>Une des principales différences entre les formats ELF et a.out
se trouve dans la manière de construire la bibliothèque partagée.
Nous traiterons les bibliothèques partagées en premier car c'est
plus simple.</p>
<h3><a name="index.71"></a> ELF, qu'est-ce que c'est ?</h3>
<p>ELF (<em>Executable and Linking Format</em>) est format de
binaire initialement conçu et développé par USL (<em>UNIX System
Laboratories</em>) et utilisé dans les systèmes Solaris et System
R4. En raison de sa facilité d'utilisation par rapport à l'ancien
format dit a.out qu'utilisait Linux, les développeurs de GCC et de
la bibliothèque C ont décidé l'année dernière de basculer tout le
système sous le format ELF. ELF est désormais le format binaire
standard sous Linux.</p>
<h3>ELF, le retour !</h3>
<p>Ce paragraphe provient du groupe
'/news-archives/comp.sys.sun.misc'.</p>
<blockquote>ELF (<em>Executable Linking Format</em>) est le �
nouveau et plus performant � format de fichier introduit dans SVR4.
ELF est beaucoup plus puissant que le sacro-saint format COFF, dans
le sens où il est extensible. ELF voit un fichier objet comme une
longue liste de sections (plutôt qu'un tableau de taille fixe
d'éléments). Ces sections, à la différence de COFF ne se trouvent
pas à un endroit constant et ne sont pas dans un ordre particulier,
etc. Les utilisateurs peuvent ajouter une nouvelle section à ces
fichiers objets s'il désirent y mettre de nouvelles données. ELS
possède un format de débogage plus puissant appelé DWARF
(<em>Debugging With Attribute Record Format</em>) - par encore
entièrement géré par Linux (mais on y travaille !). Une liste
chaînée de � DWARF DIEs � (ou <em>Debugging Information
Entries</em> - NdT... le lecteur aura sûrement noté le jeu de mot
assez noir : dwarf = nain; dies = morts) forment la section
<em>.debug</em> dans ELF. Au lieu d'avoir une liste de petits
enregistrements d'information de taille fixes, les DWARF DIEs
contiennent chacun une longue liste complexe d'attributs et sont
écrits sous la forme d'un arbre de données. Les DIEs peuvent
contenir une plus grande quantité d'information que la section
<em>.debug</em> du format COFF ne le pouvait (un peu comme les
graphes d'héritages du C++).</blockquote>
<blockquote>Les fichiers ELF sont accessibles grâce à la
bibliothèque d'accès de SVR4 (Solaris 2.0 peut-être ?), qui fournit
une interface simple et rapide aux parties les plus complexes
d'ELF. Une des aubaines que permet la bibliothèque d'accès ELF est
que vous n'avez jamais besoin de connaître les méandres du format
ELF. Pour accéder à un fichier Unix, on utilise un Elf *, retourné
par un appel à elf_open(). Ensuite, vous effectuez des appels à
elf_foobar() pour obtenir les différents composants au lieu d'avoir
à triturer le fichier physique sur le disque (chose que beaucoup
d'utilisateurs de COFF ont fait...).</blockquote>
<p>Les arguments pour ou contre ELF, et les problèmes liés à la
mise à jour d'un système a.out vers un système ELF sont décrits
dans le ELF-HOWTO et je ne veux pas effectuer de copier coller ici
(NdT: ce HowTo est également traduit en français). Ce HowTo se
trouve au même endroit que les autres.</p>
<h3>Les bibliothèque partagées ELF</h3>
<p>Pour construire <code>libtruc.so</code> comme une bibliothèque
dynamique, il suffit de suivre les étapes suivantes :</p>
<blockquote>
<pre><code>
$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname,libtruc.so.1 -o libtruc.so.1.0 *.o
$ ln -s libtruc.so.1.0 libtruc.so.1
$ ln -s libtruc.so.1 libtruc.so
$ LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH ; export LD_LIBRARY_PATH
</code></pre></blockquote>
<p>Cela va générer une bibliothèque partagée appelée
<code>libtruc.so.1.0</code>, les liens appropriés pour ld
(<code>libtruc.so</code>) et le chargeur dynamique
(<code>libtruc.so.1</code>) pour le trouver. Pour tester, nous
ajoutons le répertoire actuel à la variable d'environnement
<code>LD_LIBRARY_PATH</code>.</p>
<p><a name="index.72"></a></p>
<p>Lorsque vous êtes satisfait et que la bibliothèque fonctionne,
vous n'avez plus qu'à la déplacer dans le répertoire par exemple,
<code>/usr/local/lib</code>, et de recréer les liens appropriés. Le
lien de <code>libtruc.so.1</code> sur <code>libtruc.so.1.0</code>
est enregistré par <code>ldconfig</code>, qui sur bon nombre de
systèmes est lancé lors du processus d'amorçage. Le lien
<code>libfoo.so</code> doit être mis à jour à la main. Si vous
faites attention lors de la mise à jour de la bibliothèque la chose
la plus simple à réaliser est de créer le lien <code>libfoo.so
-&gt; libfoo.so.1</code>, pour que ldconfig conserve les liens
actuels. Si vous ne faites pas cela, vous aurez des problèmes plus
tard. Ne me dites pas que l'on ne vous a pas prévenu !</p>
<blockquote>
<pre><code>
$ /bin/su
# cp libtruc.so.1.0 /usr/local/lib
# /sbin/ldconfig
# ( cd /usr/local/lib ; ln -s libtruc.so.1 libtruc.so )
</code></pre></blockquote>
<h3><a name="index.74"></a> <a name="index.73"></a> Les numéros de
version, les noms et les liens</h3>
<p>Chaque bibliothèque possède un nom propre (<em>soname</em>).
Lorsque l'éditeur de liens en trouve un qui correspond à un nom
cherché, il enregistre le nom de la bibliothèque dans le code
binaire au lieu d'y mettre le nom du fichier de la bibliothèque.
Lors de l'exécution, le chargeur dynamique va alors chercher un
fichier ayant pour nom le nom propre de la bibliothèque, et pas le
nom du fichier de la bibliothèque. Par exemple, une bibliothèque
ayant pour nom <code>libtruc.so</code> peut avoir comme nom propre
<code>libbar.so</code>, et tous les programmes liés avec vont alors
chercher <code>libbar.so</code> lors de leur exécution.</p>
<p>Cela semble être une nuance un peu pointilleuse mais c'est la
clef de la compréhension de la coexistence de plusieurs versions
différentes de la même bibliothèque sur le même système. On a pour
habitude sous Linux d'appeler une bibliothèque
<code>libtruc.so.1.2</code> par exemple, et de lui donner comme nom
propre <code>libtruc.so.1</code>. Si cette bibliothèque est
rajoutée dans un répertoire standard (par exemple dans
<code>/usr/lib</code>), le programme <code>ldconfig</code> va créer
un lien symbolique entre <code>libtruc.so.1 -&gt;
libtruc.so.1.2</code> pour que l'image appropriée soit trouvée lors
de l'exécution. Vous aurez également besoin d'un lien symbolique
<code>libtruc.so -&gt; libtruc.so.1</code> pour que ld trouve le
nom propre lors de l'édition de liens.</p>
<p>Donc, lorsque vous corrigez des erreurs dans la bibliothèque ou
bien lorsque vous ajoutez de nouvelles fonctions (en fait, pour
toute modification qui n'affecte pas l'exécution des programmes
déjà existants), vous reconstruisez la bibliothèque, conservez le
nom propre tel qu'il était et changez le nom du fichier. Lorsque
vous effectuez des modifications que peuvent modifier le
déroulement des programmes existants, vous pouvez tout simplement
incrémenter le nombre situé dans le nom propre --- dans ce cas,
appelez la nouvelle version de la bibliothèque
<code>libtruc.so.2.0</code>, et donnez-lui comme nom propre
<code>libtruc.so.2</code>. Maintenant, faites pointer le lien de
<code>libfoo.so</code> vers la nouvelle version et tout est bien
dans le meilleur des mondes !</p>
<p>Il est utile de remarquer que vous n'êtes pas obligé de nommer
les bibliothèques de cette manière, mais c'est une bonne
convention. Elf vous donne une certaine liberté pour nommer des
bibliothèques tant et si bien que cela peut perturber certains
utilisateurs, mais cela ne veut pas dire que vous êtes obligé de le
faire.</p>
<p>Résumé : supposons que choisissiez d'adopter la méthode
traditionnelle avec les mises à jour majeures qui peuvent ne pas
être compatibles avec les versions précédentes et les mises à jour
mineures qui ne posent pas ce problème. Il suffit de créer la
bibliothèque de cette manière :</p>
<blockquote>
<pre><code>
gcc -shared -Wl,-soname,libtruc.so.majeur -o libtruc.so.majeur.mineur
</code></pre></blockquote>
et tout devrait être parfait !
<h3>a.out. Le bon vieux format</h3>
<p>La facilité de construire des bibliothèque partagées est la
raison principale de passer à ELF. Ceci dit, il est toujours
possible de créer des bibliothèques dynamiques au format a.out.
Récupérez le fichier archive <a href=
"ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.17.tar.gz">
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.17.tar.gz</a>
et lisez les 20 pages de documentation que vous trouverez dedans
après l'avoir désarchivé. Je n'aime pas avoir l'air d'être aussi
partisan, mais il est clair que je n'ai jamais aimé ce format
:-).</p>
<h3><a name="index.76"></a> <a name="index.75"></a> ZMAGIC contre
QMAGIC</h3>
<p>QMAGIC est le format des exécutables qui ressemble un peu aux
vieux binaires a.out (également connu comme ZMAGIC), mais qui
laisse la première page libre. Cela permet plus facilement de
récupérer les adresses non affectées (comme NULL) dans l'intervalle
0-4096 (NdT : Linux utilise des pages de 4Ko).</p>
<p>Les éditeurs de liens désuets ne gèrent que le format ZMAGIC,
ceux un peu moins rustiques gèrent les deux, et les plus récents
uniquement le QMAGIC. Cela importe peu car le noyau gère les deux
types.</p>
<p>La commande <code>file</code> est capable d'identifier si un
programme est de type QMAGIC.</p>
<h3>Gestion des fichiers</h3>
<p>Une bibliothèque dynamique a.out (DLL) est composée de deux
fichiers et d'un lien symbolique. Supposons que l'on utilise la
bibliothèque <em>truc</em>, les fichiers seraient les suivants :
<code>libtruc.sa</code> et <code>libtruc.so.1.2</code>; et le lien
symbolique aurait pour nom <code>libtruc.so.1</code> et pointerait
sur le dernier des fichiers. Mais à quoi servent-ils ?</p>
<p>Lors de la compilation, <code>ld</code> cherche
<code>libtruc.sa</code>. C'est le fichier de description de la
bibliothèque : il contient toutes les données exportées et les
pointeurs vers les fonctions nécessaires pour l'édition de
liens.</p>
<p>Lors de l'exécution, le chargeur dynamique cherche
<code>libtruc.so.1</code>. C'est un lien symbolique plutôt qu'un
réel fichier pour que les bibliothèques puissent être mise à jour
sans avoir à casser les applications qui utilisent la bibliothèque.
Après la mise à jour, disons que l'on est passé à la version
<code>libfoo.so.1.3</code>, le lancement de ldconfig va positionner
le lien. Comme cette opération est atomique, aucune application
fonctionnant n'aura de problème.</p>
<p>Les bibliothèques DLL (Je sais que c'est une tautologie... mais
pardon !) semblent être très souvent plus importantes que leur
équivalent statique. En fait, c'est qu'elles réservent de la place
pour les extensions ultérieures sous la simple forme de trous qui
sont fait de telle manière qu'ils n'occupent pas de place disque
(NdT : un peu comme les fichiers <code>core</code>). Toutefois, un
simple appel à <code>cp</code> ou à <code>makehole</code> les
remplira... Vous pouvez effectuer une opération de
<code>strip</code> après la construction de la bibliothèque, comme
les adresses sont à des endroits fixes. <b>Ne faites pas la même
opération avec les bibliothèques ELF !</b></p>
<h3>� libc-lite � ?</h3>
<p>Une � libc-lite � (contraction de <em>libc</em> et
<em>little</em>) est une version épurée et réduite de la
bibliothèque libc construite de telle manière qu'elle puisse tenir
sur une disquette avec un certain nombre d'outil Unix. Elle
n'inclut pas curses, dbm, termcap, ... Si votre
<code>/lib/libc.so.4</code> est liée avec une bibliothèque de ce
genre il est très fortement conseillé de la remplacer avec une
version complète.</p>
<h3>Edition de liens : problème courants</h3>
<p>Envoyez-les moi !</p>
<dl>
<dt><b>Des programmes statiques lorsque vous les voulez
partagés</b></dt>
<dd>
<p><a name="index.77"></a> <a name="index.78"></a></p>
<p>Vérifiez que vous avez les bons liens pour que <code>ld</code>
puisse trouver les bibliothèques partagées. Pour ELF cela veut dire
que <code>libtruc.so</code> est un lien symbolique sur son image,
pour a.out un fichier <code>libtruc.sa</code>. Beaucoup de
personnes ont eu ce problème après être passés des outils ELF 2.5 à
2.6 (<code>binutils</code>) --- la dernière version effectue une
recherche plus intelligente pour les bibliothèques dynamiques et
donc ils n'avaient pas créé tous les liens symboliques nécessaires.
Cette caractéristique avait été supprimée pour des raisons de
compatibilité avec d'autres architectures et parce qu'assez souvent
cela ne marchait pas bien. En bref, cela posait plus de problèmes
qu'autre chose.</p>
</dd>
<dt><b>Le programme `mkimage' n'arrive pas à trouver
libgcc</b></dt>
<dd>
<p><a name="index.79"></a></p>
<p>Comme <code>libc.so.4.5.x</code> et suivantes, libgcc n'est pas
une bibliothèque partagée. Vous devez remplacer les
`<code>-lgcc</code>' sur la ligne de commande par <code>`gcc
-print-libgcc-file-name`</code> (entre quotes)</p>
<p>Egalement, détruisez tous les fichiers situés dans
<code>/usr/lib/libgcc*</code>. C'est important.</p>
</dd>
<dt><b>Le message <code>__NEEDS_SHRLIB_libc_4 multiply
defined</code></b></dt>
<dd>
<p>Sont une conséquence du même problème.</p>
</dd>
<dt><b>Le message ``Assertion failure'' apparaît lorsque vous
reconstruisez une DLL</b></dt>
<dd>
<p>Ce message énigmatique signifie qu'un élément de votre table
<em>jump</em> a dépassé la table car trop peu de place était
réservée dans le fichier <code>jump.vars</code> file. Vous pouvez
trouver le(s) coupable(s) en lançant la commande
<code>getsize</code> fournie dans le paquetage tools-2.17.tar.gz.
La seule solution est de passer à une nouvelle version majeure,
même si elle sera incompatible avec les précédentes.</p>
</dd>
<dt><b><code>ld: output file needs shared library
libc.so.4</code></b></dt>
<dd>
<p>Cela arrive lorsque vous effectuez l'édition de liens avec des
bibliothèques différentes de la libc (comme les bibliothèques X) et
que vous utilisez l'option <code>-g</code> sans utiliser l'option
<code>-static</code>.</p>
<p>Les fichiers <code>.sa</code> pour les bibliothèques dynamiques
ont un symbole non résolu <code>_NEEDS_SHRLIB_libc_4</code> qui est
défini dans <code>libc.sa</code>. Or, lorsque vous utilisez
<code>-g</code> vous faites l'édition de liens avec
<code>libg.a</code> ou <code>libc.a</code> et donc ce symbole n'est
jamais défini.</p>
<p>Donc, pour résoudre le problème, ajoutez l'option
<code>-static</code> lorsque vous compilez avec l'option
<code>-g</code>, ou n'utilisez pas <code>-g</code> lors de
l'édition de liens !</p>
</dd>
</dl>
<h2><a name="s7">7. Chargement dynamique</a></h2>
<p><em>Ce paragraphe est en fait un peu court : il sera étendu dans
une version ultérieure dès que j'aurai récupéré le HowTo
ELF</em></p>
<h2><a name="ss7.1">7.1 Concepts</a></h2>
<p>Linux possède des bibliothèques dynamiques, comme on vous le
répète depuis le début de ce document ! Or, il existe un système
pour reporter le travail d'association des noms des symboles et de
leur adresse dans la bibliothèque, qui est normalement effectué
lors de l'édition de liens en l'effectuant lors du chargement du
programme.</p>
<h2><a name="ss7.2">7.2 Messages d'erreur</a></h2>
<p>Envoyez moi vos erreurs ! Je n'en fait pas grand chose sauf les
insérer dans ce paragraphe...</p>
<dl>
<dt><b><code>can't load library: /lib/libxxx.so, Incompatible
version</code></b></dt>
<dd>
<p>(seulement a.out) Cela signifie que vous n'avez pas la version
correcte de la bibliothèque (numéro dit majeur). Non, il n'est pas
possible d'effectuer un lien symbolique sur la bibliothèque que
vous possédez : si vous avez de la chance, vous obtiendrez un
<em>segmentation fault</em>. Récupérez la nouvelle version. Un
message un peu équivalent existe également sur les systèmes ELF
:</p>
<blockquote>
<pre><code>
ftp: can't load library 'libreadline.so.2'
</code></pre></blockquote>
</dd>
<dt><b><code>warning using incompatible library version
xxx</code></b></dt>
<dd>
<p>(seulement a.out) Vous avez un numéro de version de bibliothèque
(mineur) inférieur à la version avec laquelle a été compilé le
programme. Le programme fonctionnera sûrement. Une mise à jour est
toutefois conseillée.</p>
</dd>
</dl>
<h2><a name="index.81"></a> <a name="index.80"></a> <a name=
"ss7.3">7.3 Contrôler l'opération de chargement dynamique</a></h2>
<p>Il existe certaines variables d'environnements que le chargeur
dynamique utilise. Beaucoup sont exploitées par le programme
<code>ldd</code> lorsqu'il s'agit de particularités de
l'environnement de l'utilisateur, ce qui peuvent être positionnées
pour lancer ldd avec des options particulières. Voici une
description des différentes variables d'environnement que vous
pouvez rencontrer :</p>
<ul>
<li><code>LD_BIND_NOW</code> --- normalement, les fonctions ne sont
pas cherchées dans les bibliothèques avant leur appel. En
positionnant cette option, vous vérifiez que toutes les fonctions
employées dans votre programmes se trouvent bien dans la
bibliothèque lors de son chargement, ce qui ralentit le lancement
du programme. C'est utile lorsque vous voulez tester que l'édition
de liens s'est parfaitement déroulée et que tous les symboles sont
bien associés.</li>
<li><code>LD_PRELOAD</code> peut être défini avec un nom de fichier
qui contient des fonctions surchargeant des fonctions déjà
existantes. Par exemple, si vous testez une stratégie d'allocation
mémoire, et que vous voulez remplacer le malloc de la bibliothèque
C par le vôtre situé dans un module ayant pour nom
<code>malloc.o</code>, il vous suffit de faire :
<blockquote>
<pre><code>
$ export LD_PRELOAD=malloc.o
$ test_mon_malloc
</code></pre></blockquote>
<code>LD_ELF_PRELOAD</code> et <code>LD_AOUT_PRELOAD</code> sont
similaires, mais leur utilisation est spécifique au type de binaire
utilisé. Si
<code>LD_</code><em>TypeBinaire</em><code>_PRELOAD</code> et
<code>LD_PRELOAD</code> sont positionnés, celui correspondant le
mieux à la machine est utilisé.</li>
<li><code>LD_LIBRARY_PATH</code> contient une liste de répertoires
contenant les bibliothèques dynamiques. Cela n'affecte pas
l'édition de liens : cela n'a qu'un effet lors de l'exécution. Il
faut noter qu'elle est désactivée pour des programmes qui
s'exécutent avec un setuid ou un setgid. Enfin,
<code>LD_ELF_LIBRARY_PATH</code> et
<code>LD_AOUT_LIBRARY_PATH</code> peuvent être utilisés pour
orienter le mode de compilation du binaire.
<code>LD_LIBRARY_PATH</code> ne devrait pas être nécessaire en
principe : ajoutez les répertoires dans le fichier
<code>/etc/ld.so.conf/</code> et relancez ldconfig.</li>
<li><code>LD_NOWARN</code> s'applique au format a.out uniquement.
Lorsqu'elle est positionnée (c.a.d si elle existe par exemple avec
<code>LD_NOWARN=true; export LD_NOWARN</code>) cela arrête le
chargeur du programme même sur des avertissements insignifiants
(tels que des messages d'incompatibilités de numéros mineurs de
version).</li>
<li><code>LD_WARN</code> s'applique à ELF uniquement. Lorsqu'elle
est positionnée, on transforme le message habituellement fatal
<em>Can't find library</em> en un avertissement. Ce n'est pas
positionné par défaut mais c'est important pour un programme comme
ldd.</li>
<li><code>LD_TRACE_LOADED_OBJECTS</code> s'applique à ELF
uniquement, et permet de simuler l'exécution des programmes comme
s'ils l'étaient par <code>ldd</code> :
<blockquote>
<pre><code>
$ LD_TRACE_LOADED_OBJECTS=true /usr/bin/lynx
        libncurses.so.1 =&gt; /usr/lib/libncurses.so.1.9.6
        libc.so.5 =&gt; /lib/libc.so.5.2.18
</code></pre></blockquote>
</li>
</ul>
<h2><a name="index.83"></a> <a name="index.82"></a> <a name=
"ss7.4">7.4 Ecrire des programmes en utilisant le chargement
dynamique</a></h2>
<p>Cela ressemble énormément au système de chargement dynamique
utilisé sous Solaris 2.x. Ce système est décrit d'une manière
précise dans le document expliquant la programmation avec ELF écrit
par H J Lu et dans la page de manuel <code>dlopen(3)</code>, qui se
trouve dans le paquetage ld.so. Voici un exemple simple : pensez à
faire l'édition de liens avec <code>-ldl</code></p>
<blockquote>
<pre><code>
#include &lt;dlfcn.h&gt;
#include &lt;stdio.h&gt;

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

  if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
  {
    printf_call = dlsym(libc,"printf");
    (*printf_call)("Bonjour ! Ha ben ca marche pil poil sous Linux !\n");
  }

}
</code></pre></blockquote>
<h2><a name="s8">8. Contacter les développeurs</a></h2>
<h2><a name="index.84"></a> <a name="ss8.1">8.1 Annoncer des
bogues</a></h2>
<p>Commencez par mettre en doute le problème. Est-ce spécifique à
Linux ou bien cela arrive avec gcc mais sur d'autres plates-formes
? Est-ce spécifique à la version du noyau ? A la version de la
bibliothèque C ? Est-ce que ce problème disparaît lorsque vous
effectuez une édition de liens statique ? Pouvez-vous produire un
code très court mettant en évidence le problème ?</p>
<p>Après avoir répondu après ces quelques questions, vous saurez
quel programme est à l'origine du problème. Pour un problème direct
avec GCC, le mieux est de consulter le fichier d'information livré
avec : la procédure pour rapporter un bogue y est détaillé. Pour un
problème avec ld.so, la bibliothèque C ou mathématique, envoyez un
courrier électronique à <code>linux-gcc@vger.rutgers.edu</code>. Si
possible, donnez un court exemple mettant en évidence le problème
ainsi qu'une courte description indiquant ce que le programme
aurait normalement dû faire, et ce qu'il fait en réalité.</p>
<h2><a name="ss8.2">8.2 Participer au développement</a></h2>
<p>Si vous désirez participer au développement de GCC ou de la
bibliothèque C, la première chose à faire est de rejoindre la liste
de diffusion <code>linux-gcc@vger.rutgers.edu</code>. Si vous
désirez uniquement savoir de quoi ça parle, il existe des archives
à l'adresse <a href=
"http://homer.ncm.com/linux-gcc/">http://homer.ncm.com/linux-gcc/</a>.
Tout dépend de ce que vous désirez faire ou apporter à ce projet
!</p>
<h2><a name="s9">9. Divers</a></h2>
<h2><a name="ss9.1">9.1 Ce document</a></h2>
<p>Ce HowTo est basé sur la FAQ de Mitchum DSouza's. Bon nombre des
informations en proviennent. D'une manière générale, il est
fréquent de dire une phrase du genre � je n'ai pas tout testé et
donc ne me blâmez pas si vous cassez votre disque, votre système ou
si vous rompez avec votre épouse �.</p>
<p>Le nom des contributeurs à ce document sont donnés par ordre
alphabétique : 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,
et bien sûr Linus Torvalds, sans qui ce genre d'exercice aurait été
difficile, voir impossible :-)</p>
<p>Ne soyez pas offensé si votre nom n'apparaît pas dans la liste
et que vous ayez contribué à ce document (sous la forme d'un HowTo
ou d'une FAQ). Envoyez-moi un courrier électronique et
j'effectuerai la correction.</p>
<h2><a name="ss9.2">9.2 Traduction</a></h2>
<p>A l'heure ou j'écris ces lignes, je ne connais pas de traduction
de ce document. Si vous en réalisez une, s'il vous plaît dites-le
moi. Je suis disponible pour toute aide concernant l'explication du
texte, je serai très content d'y répondre.</p>
<p>Note du traducteur : <b>Cocorico !</b> La version française est
la première traduction de ce document.</p>
<h2><a name="ss9.3">9.3 Contacts</a></h2>
<p>Tout contact est le bienvenu. Envoyez-moi un courrier
électronique à l'adresse suivante : <a href=
"mailto:dan@detached.demon.co.uk">dan@detached.demon.co.uk</a>. Ma
clef publique PGP (ID 5F263625) est disponible sur mes <a href=
"http://ftp.linux.org.uk/~barlow/">pages WWW</a>, Si vous souhaitez
rendre confidentiel certains messages.</p>
<h2><a name="ss9.4">9.4 Copyright</a></h2>
<p>Toutes les remarques appartiennent à leurs auteurs
respectifs.</p>
<p>Ce document est copyrighté (C) 1996 Daniel Barlow
<code>&lt;dan@detached.demon.co.uk&gt;</code>. Il peut être
reproduit et distribué en partie ou entièrement, sur tout support
physique ou électronique, du moment où ce copyright se trouve sur
toute les copies. La redistribution commerciale est autorisée et
encouragée. Toutefois l'auteur de ce document doit être mis au
courant de ce genre de distributions.</p>
<p>Toute traduction, adaptation, ou bien tout travail incorporant
tout document HowTo Linux doit posséder ce copyright. De cette
manière, vous ne pouvez pas imposer de restriction à la
distribution de ce document. Des exceptions peuvent être
éventuellement accordées sous certaines conditions : contactez le
coordinateur des HowTo's Linux à l'adresse donnée ci-dessous.</p>
<p>En résumé, nous souhaitons voir diffuser l'information de la
manière la plus large qui soit. Toutefois, nous souhaitons garder
la maîtrise de ces documents et nous aimerions être consultés avant
toute diffusion des HowTo's.</p>
<p>Si vous avez des questions, vous pouvez contacter Greg Hankins,
le coordinateur des HowTo Linux HOWTO à l'adresse électronique
suivante : <code>gregh@sunsite.unc.edu</code></p>
<h2><a name="s10">10. Index</a></h2>
<p>Les entrées de cet index sont triées dans l'ordre
alphabétique.</p>
<ul>
<li><code>-fwritable-strings</code> <a href="#index.39">39</a>,
<a href="#index.56">56</a></li>
<li>/lib/cpp <a href="#index.16">16</a></li>
<li>a.out <a href="#index.1">1</a></li>
<li><code>ar</code> <a href="#index.10">10</a></li>
<li><code>as</code> <a href="#index.8">8</a></li>
<li>&lt;asm/*.h&gt; <a href="#index.19">19</a></li>
<li><code>atoi()</code> <a href="#index.40">40</a></li>
<li><code>atol()</code> <a href="#index.41">41</a></li>
<li>exécutables trop gros <a href="#index.63">63</a>, <a href=
"#index.65">65</a>, <a href="#index.77">77</a></li>
<li>chewing gum <a href="#index.3">3</a></li>
<li><code>cos()</code> <a href="#index.68">68</a></li>
<li>deboguer <a href="#index.59">59</a></li>
<li>divers <a href="#index.72">72</a></li>
<li><code>dlopen()</code> <a href="#index.82">82</a></li>
<li><code>dlsym()</code> <a href="#index.83">83</a></li>
<li>documentation <a href="#index.4">4</a></li>
<li>EINTR <a href="#index.52">52</a></li>
<li>elf <a href="#index.0">0</a>, <a href="#index.71">71</a></li>
<li><code>execl()</code> <a href="#index.57">57</a></li>
<li><code>fcntl</code> <a href="#index.47">47</a></li>
<li><code>FD_CLR</code> <a href="#index.44">44</a></li>
<li><code>FD_ISSET</code> <a href="#index.45">45</a></li>
<li><code>FD_SET</code> <a href="#index.43">43</a></li>
<li><code>FD_ZERO</code> <a href="#index.46">46</a></li>
<li><code>fichier</code> <a href="#index.2">2</a></li>
<li>&lt;float.h&gt; <a href="#index.20">20</a></li>
<li>gcc <a href="#index.6">6</a></li>
<li><code>gcc -fomit-frame-pointer</code> <a href=
"#index.61">61</a></li>
<li><code>gcc -g</code> <a href="#index.60">60</a></li>
<li>gcc -v <a href="#index.14">14</a></li>
<li>gcc, bogues <a href="#index.15">15</a>, <a href=
"#index.28">28</a>, <a href="#index.29">29</a>, <a href=
"#index.84">84</a></li>
<li>gcc, options de compilation <a href="#index.13">13</a>,
<a href="#index.25">25</a>, <a href="#index.26">26</a></li>
<li>gdb <a href="#index.64">64</a></li>
<li>fichiers d'en-tête <a href="#index.17">17</a></li>
<li>appels systèmes interrompus <a href="#index.51">51</a></li>
<li><code>ld</code> <a href="#index.9">9</a></li>
<li><code>LD_*</code> : variables d'environnement <a href=
"#index.80">80</a></li>
<li>ldd <a href="#index.81">81</a></li>
<li>libc <a href="#index.7">7</a></li>
<li><code>libg.a</code> <a href="#index.62">62</a></li>
<li>libgcc <a href="#index.79">79</a></li>
<li>&lt;limits.h&gt; <a href="#index.21">21</a></li>
<li>lint <a href="#index.58">58</a></li>
<li>&lt;linux/*.h&gt; <a href="#index.18">18</a></li>
<li><code>&lt;math.h&gt;</code> <a href="#index.70">70</a></li>
<li>maths <a href="#index.69">69</a></li>
<li><code>mktemp()</code> <a href="#index.55">55</a></li>
<li>numéro de version <a href="#index.12">12</a>, <a href=
"#index.74">74</a></li>
<li>optimisation <a href="#index.27">27</a></li>
<li>pages de manuel <a href="#index.5">5</a></li>
<li>QMAGIC <a href="#index.76">76</a></li>
<li>segmentation fault <a href="#index.30">30</a>, <a href=
"#index.54">54</a></li>
<li>segmentation fault, in GCC <a href="#index.33">33</a></li>
<li>select() <a href="#index.50">50</a></li>
<li><code>SIGBUS</code> <a href="#index.34">34</a></li>
<li><code>SIGEMT</code> <a href="#index.35">35</a></li>
<li><code>SIGIOT</code> <a href="#index.36">36</a></li>
<li>SIGSEGV <a href="#index.31">31</a>, <a href=
"#index.53">53</a></li>
<li>SIGSEGV, in gcc <a href="#index.32">32</a></li>
<li><code>SIGSYS</code> <a href="#index.38">38</a></li>
<li><code>SIGTRAP</code> <a href="#index.37">37</a></li>
<li><code>sin()</code> <a href="#index.67">67</a></li>
<li>soname <a href="#index.73">73</a></li>
<li><code>sprintf()</code> <a href="#index.42">42</a></li>
<li>binaires linkés statiquement <a href="#index.66">66</a>,
<a href="#index.78">78</a></li>
<li>&lt;stdarg.h&gt; <a href="#index.23">23</a></li>
<li>&lt;stddef.h&gt; <a href="#index.24">24</a></li>
<li><code>strings</code> <a href="#index.11">11</a></li>
<li><code>&lt;sys/time.h&gt;</code> <a href="#index.48">48</a></li>
<li><code>&lt;unistd.h&gt;</code> <a href="#index.49">49</a></li>
<li>&lt;varargs.h&gt; <a href="#index.22">22</a></li>
<li>ZMAGIC <a href="#index.75">75</a></li>
</ul>
</body>
</html>