@@ -1536,17 +1536,19 @@ class GCCInstallationDetector {
1536
1536
}
1537
1537
1538
1538
llvm::Triple::ArchType HostArch = llvm::Triple (GccTriple).getArch ();
1539
- // The directories which may contain x86-64 triple GCC installations.
1539
+ // The library directories which may contain GCC installations.
1540
1540
SmallVector<StringRef, 2 > CandidateLibDirs;
1541
- // The compatible GCC triples for an x86-64 Linux Clang .
1541
+ // The compatible GCC triples for this particular architecture .
1542
1542
SmallVector<StringRef, 10 > CandidateTriples;
1543
1543
if (HostArch == llvm::Triple::arm || HostArch == llvm::Triple::thumb) {
1544
- static const char *const LibDirs[] = { " /usr/ lib/gcc" };
1544
+ static const char *const LibDirs[] = { " /lib/gcc" };
1545
1545
static const char *const Triples[] = { " arm-linux-gnueabi" };
1546
1546
CandidateLibDirs.append (LibDirs, LibDirs + llvm::array_lengthof (LibDirs));
1547
1547
CandidateTriples.append (Triples, Triples + llvm::array_lengthof (Triples));
1548
1548
} else if (HostArch == llvm::Triple::x86_64) {
1549
- static const char *const LibDirs[] = { " /usr/lib64/gcc" , " /usr/lib/gcc" };
1549
+ static const char *const LibDirs[] = {
1550
+ " /lib64/gcc" , " /lib/gcc" , " /lib64" , " /lib"
1551
+ };
1550
1552
static const char *const Triples[] = {
1551
1553
" x86_64-linux-gnu" ,
1552
1554
" x86_64-unknown-linux-gnu" ,
@@ -1561,7 +1563,9 @@ class GCCInstallationDetector {
1561
1563
CandidateLibDirs.append (LibDirs, LibDirs + llvm::array_lengthof (LibDirs));
1562
1564
CandidateTriples.append (Triples, Triples + llvm::array_lengthof (Triples));
1563
1565
} else if (HostArch == llvm::Triple::x86) {
1564
- static const char *const LibDirs[] = { " /usr/lib32/gcc" , " /usr/lib/gcc" };
1566
+ static const char *const LibDirs[] = {
1567
+ " /lib32/gcc" , " /lib/gcc" , " /lib32" , " /lib"
1568
+ };
1565
1569
static const char *const Triples[] = {
1566
1570
" i686-linux-gnu" ,
1567
1571
" i386-linux-gnu" ,
@@ -1574,35 +1578,27 @@ class GCCInstallationDetector {
1574
1578
CandidateLibDirs.append (LibDirs, LibDirs + llvm::array_lengthof (LibDirs));
1575
1579
CandidateTriples.append (Triples, Triples + llvm::array_lengthof (Triples));
1576
1580
} else if (HostArch == llvm::Triple::ppc) {
1577
- static const char *const LibDirs[] = { " /usr/lib32/gcc" , " /usr/lib/gcc" };
1581
+ static const char *const LibDirs[] = {
1582
+ " /lib32/gcc" , " /lib/gcc" , " /lib32" , " /lib"
1583
+ };
1578
1584
static const char *const Triples[] = {
1579
1585
" powerpc-linux-gnu" ,
1580
1586
" powerpc-unknown-linux-gnu"
1581
1587
};
1582
1588
CandidateLibDirs.append (LibDirs, LibDirs + llvm::array_lengthof (LibDirs));
1583
1589
CandidateTriples.append (Triples, Triples + llvm::array_lengthof (Triples));
1584
1590
} else if (HostArch == llvm::Triple::ppc64) {
1585
- static const char *const LibDirs[] = { " /usr/lib64/gcc" , " /usr/lib/gcc" };
1591
+ static const char *const LibDirs[] = {
1592
+ " /lib64/gcc" , " /lib/gcc" , " /lib64" , " /lib"
1593
+ };
1586
1594
static const char *const Triples[] = { " powerpc64-unknown-linux-gnu" };
1587
1595
CandidateLibDirs.append (LibDirs, LibDirs + llvm::array_lengthof (LibDirs));
1588
1596
CandidateTriples.append (Triples, Triples + llvm::array_lengthof (Triples));
1589
1597
}
1590
1598
1591
- // First finds the 'prefix' which exists beneath the system root. Second,
1592
- // finds the first triple which exists beneath that prefix.
1593
- StringRef DetectedGccPrefix, DetectedGccTriple;
1594
- for (unsigned i = 0 , ie = CandidateLibDirs.size (); i < ie; ++i) {
1595
- if (!PathExists (CandidateLibDirs[i]))
1596
- continue ;
1597
-
1598
- for (unsigned j = 0 , je = CandidateTriples.size (); j < je; ++j) {
1599
- if (PathExists (CandidateLibDirs[i].str () + " /" +
1600
- CandidateTriples[j].str ())) {
1601
- DetectedGccPrefix = CandidateLibDirs[i];
1602
- DetectedGccTriple = CandidateTriples[j];
1603
- }
1604
- }
1605
- }
1599
+ // Always include the default host triple as the final fallback if no
1600
+ // specific triple is detected.
1601
+ CandidateTriples.push_back (D.DefaultHostTriple );
1606
1602
1607
1603
static const char * GccVersions[] = {
1608
1604
" 4.6.1" , " 4.6.0" , " 4.6" ,
@@ -1611,40 +1607,64 @@ class GCCInstallationDetector {
1611
1607
" 4.3.4" , " 4.3.3" , " 4.3.2" , " 4.3" ,
1612
1608
" 4.2.4" , " 4.2.3" , " 4.2.2" , " 4.2.1" , " 4.2" ,
1613
1609
" 4.1.1" };
1614
- SmallVector<std::string, 8 > Paths (D.PrefixDirs .begin (),
1615
- D.PrefixDirs .end ());
1616
- Paths.push_back (D.SysRoot + " /usr/" );
1617
- const std::string Triples[] = {DetectedGccTriple.str (), D.DefaultHostTriple };
1618
- IsValid = true ; // In case we're able to find a GCC install.
1619
- for (SmallVector<std::string, 8 >::const_iterator I = Paths.begin (),
1620
- E = Paths.end ();
1621
- I != E; ++I) {
1622
- for (unsigned i = 0 ; i < sizeof (GccVersions)/sizeof (char *); ++i) {
1623
- for (unsigned j = 0 ; j < sizeof (Triples)/sizeof (Triples[0 ]); ++j) {
1624
- GccTriple = Triples[j];
1625
- std::string Suffix = Triples[j] + " /" + GccVersions[i];
1626
- GccInstallPath = *I + " lib/gcc/" + Suffix;
1627
- GccParentLibPath = GccInstallPath + " /../../.." ;
1628
- if (PathExists (GccInstallPath + " /crtbegin.o" ))
1629
- return ;
1630
- GccInstallPath = *I + " lib64/gcc/" + Suffix;
1631
- GccParentLibPath = GccInstallPath + " /../../.." ;
1632
- if (PathExists (GccInstallPath + " /crtbegin.o" ))
1633
- return ;
1634
- GccInstallPath = *I + " lib/" + GccTriple + " /gcc/" + Suffix;
1635
- GccParentLibPath = GccInstallPath + " /../../../.." ;
1636
- if (PathExists (GccInstallPath + " /crtbegin.o" ))
1637
- return ;
1638
-
1639
- if (GccTriple != " i386-linux-gnu" )
1610
+
1611
+ // Set this as valid so we can early exit from the loops if we find
1612
+ // a viable installation.
1613
+ IsValid = true ;
1614
+
1615
+ SmallVector<std::string, 8 > Prefixes (D.PrefixDirs .begin (),
1616
+ D.PrefixDirs .end ());
1617
+ Prefixes.push_back (D.SysRoot + " /usr" );
1618
+ // FIXME: This entire nested loop structure is broken. The structure is
1619
+ // well suited to quickly pruning impossible (non-existent) sub-trees, but
1620
+ // doesn't find all viable GCC installations and choose the best one. We
1621
+ // should invert this, and prune the impossible subtrees bottom-up, but
1622
+ // then select the best GCC installation top-down so that we prefer the
1623
+ // newest GCC, the most accurate triple, and only at the end select the lib
1624
+ // and prefix directories containing that installation.
1625
+ for (SmallVectorImpl<std::string>::const_iterator PI = Prefixes.begin (),
1626
+ PE = Prefixes.end ();
1627
+ PI != PE; ++PI) {
1628
+ if (!PathExists (*PI))
1629
+ continue ;
1630
+
1631
+ // First finds the 'prefix' which exists beneath the system root. Second,
1632
+ // finds the first triple which exists beneath that prefix.
1633
+ StringRef DetectedGccPrefix, DetectedGccTriple;
1634
+ for (unsigned i = 0 , ie = CandidateLibDirs.size (); i < ie; ++i) {
1635
+ const std::string LibDir = *PI + CandidateLibDirs[i].str ();
1636
+ if (!PathExists (LibDir))
1637
+ continue ;
1638
+
1639
+ for (unsigned j = 0 , je = CandidateTriples.size (); j < je; ++j) {
1640
+ GccTriple = CandidateTriples[j];
1641
+ const std::string TripleDir = LibDir + " /" + GccTriple;
1642
+ if (!PathExists (TripleDir))
1640
1643
continue ;
1641
1644
1642
- // Ubuntu 11.04 uses an unusual path.
1643
- GccInstallPath = *I + " lib/i386-linux-gnu/gcc/i686-linux-gnu/" +
1644
- GccVersions[i];
1645
- GccParentLibPath = GccInstallPath + " /../../../.." ;
1646
- if (PathExists (GccInstallPath + " /crtbegin.o" ))
1647
- return ;
1645
+ for (unsigned k = 0 ; k < llvm::array_lengthof (GccVersions); ++k) {
1646
+ GccInstallPath = TripleDir + " /" + GccVersions[k];
1647
+ GccParentLibPath = GccInstallPath + " /../../.." ;
1648
+ if (PathExists (GccInstallPath + " /crtbegin.o" ))
1649
+ return ;
1650
+
1651
+ // Try an install directory with an extra triple in it.
1652
+ GccInstallPath =
1653
+ TripleDir + " /gcc/" + GccTriple + " /" + GccVersions[k];
1654
+ GccParentLibPath = GccInstallPath + " /../../../.." ;
1655
+ if (PathExists (GccInstallPath + " /crtbegin.o" ))
1656
+ return ;
1657
+
1658
+ if (GccTriple != " i386-linux-gnu" )
1659
+ continue ;
1660
+
1661
+ // Ubuntu 11.04 uses an unusual path.
1662
+ GccInstallPath =
1663
+ TripleDir + " /gcc/i686-linux-gnu/" + GccVersions[k];
1664
+ GccParentLibPath = GccInstallPath + " /../../../.." ;
1665
+ if (PathExists (GccInstallPath + " /crtbegin.o" ))
1666
+ return ;
1667
+ }
1648
1668
}
1649
1669
}
1650
1670
}
0 commit comments