| 491 | #=== Begin Revised CXXFLAGS ========================================= |
---|
| 492 | def outputof(*cmd): |
---|
| 493 | """Run a command without running a shell, return cmd's stdout |
---|
| 494 | """ |
---|
| 495 | p = Popen(cmd, stdout=PIPE) |
---|
| 496 | return p.communicate()[0] |
---|
| 497 | |
---|
| 498 | def cpuinfo_kv(): |
---|
| 499 | """generator which reads lines from Linux /proc/cpuinfo and splits them |
---|
| 500 | into key:value tokens and yields (key, value) tuple. |
---|
| 501 | """ |
---|
| 502 | f = open('/proc/cpuinfo', 'r') |
---|
| 503 | for line in f: |
---|
| 504 | line = line.strip() |
---|
| 505 | if line: |
---|
| 506 | k,v = line.split(':') |
---|
| 507 | yield (k.strip(), v.strip()) |
---|
| 508 | f.close() |
---|
| 509 | |
---|
| 510 | |
---|
| 511 | class CpuInfo (object): |
---|
| 512 | """Collects information about the CPU, mainly from /proc/cpuinfo |
---|
| 513 | """ |
---|
| 514 | def __init__(self): |
---|
| 515 | self.sysname, self.hostname, self.release, self.version, self.machine = os.uname() |
---|
| 516 | # general CPU architecture |
---|
| 517 | self.is_x86 = self.machine in ('i686', 'x86_64') or \ |
---|
| 518 | re.match("i[3-5]86", self.machine) or False |
---|
| 519 | self.is_powerpc = self.machine in ('ppc64', 'ppc', 'powerpc', 'powerpc64') |
---|
| 520 | #!!! probably not comprehensive |
---|
| 521 | self.is_mips = self.machine == 'mips' |
---|
| 522 | #!!! not a comprehensive list. uname -m on one android phone reports 'armv71' |
---|
| 523 | # I have no other arm devices I can check |
---|
| 524 | self.is_arm = self.machine in ('armv71', ) |
---|
| 525 | |
---|
| 526 | self.cpu_count = 0 |
---|
| 527 | if self.is_x86: |
---|
| 528 | self.cpu_info_x86() |
---|
| 529 | elif self.is_powerpc: |
---|
| 530 | self.cpu_info_ppc() |
---|
| 531 | elif self.is_mips: |
---|
| 532 | self.cpu_info_mips() |
---|
| 533 | |
---|
| 534 | # 64-bit (x86_64/AMD64/Intel64) |
---|
| 535 | # Long Mode (x86-64: amd64, also known as Intel 64, i.e. 64-bit capable) |
---|
| 536 | self.is_64bit = (self.is_x86 and 'lm' in self.x86_flags) or \ |
---|
| 537 | (self.is_powerpc and '970' in self.ppc_type) |
---|
| 538 | |
---|
| 539 | # Hardware virtualization capable: vmx (Intel), svm (AMD) |
---|
| 540 | self.has_hwvirt = self.is_x86 and ( |
---|
| 541 | (self.is_amd and 'svm' in self.x86_flags) or |
---|
| 542 | (self.is_intel and 'vmx' in self.x86_flags)) |
---|
| 543 | |
---|
| 544 | # Physical Address Extensions (support for more than 4GB of RAM) |
---|
| 545 | self.has_pae = self.is_x86 and 'pae' in self.x86_flags |
---|
| 546 | |
---|
| 547 | |
---|
| 548 | def cpu_info_x86(self): |
---|
| 549 | "parse /proc/cpuinfo for x86 kernels" |
---|
| 550 | for k,v in cpuinfo_kv(): |
---|
| 551 | if k == 'processor': |
---|
| 552 | self.cpu_count += 1 |
---|
| 553 | if self.cpu_count > 1: |
---|
| 554 | # assume all CPUs are identical features, no need to |
---|
| 555 | # parse all of them |
---|
| 556 | continue |
---|
| 557 | elif k == 'vendor_id': # AuthenticAMD, GenuineIntel |
---|
| 558 | self.vendor_id = v |
---|
| 559 | self.is_amd = v == 'AuthenticAMD' |
---|
| 560 | self.is_intel = v == 'GenuineIntel' |
---|
| 561 | elif k == 'flags': |
---|
| 562 | self.x86_flags = v.split() |
---|
| 563 | elif k == 'model name': |
---|
| 564 | self.model_name = v |
---|
| 565 | elif k == 'cpu family': |
---|
| 566 | self.cpu_family = v |
---|
| 567 | elif k == 'model': |
---|
| 568 | self.model = v |
---|
| 569 | |
---|
| 570 | def cpu_info_ppc(self): |
---|
| 571 | "parse /proc/cpuinfo for PowerPC kernels" |
---|
| 572 | # http://en.wikipedia.org/wiki/List_of_PowerPC_processors |
---|
| 573 | # PowerPC 7xx family |
---|
| 574 | # PowerPC 740 and 750, 233-366 MHz |
---|
| 575 | # 745/755, 300–466 MHz |
---|
| 576 | |
---|
| 577 | # PowerPC G4 series |
---|
| 578 | # 7400/7410 350 - 550 MHz, uses AltiVec, a SIMD extension of the original PPC specs |
---|
| 579 | # 7450 micro-architecture family up to 1.5 GHz and 256 kB on-chip L2 cache and improved Altivec |
---|
| 580 | # 7447/7457 micro-architecture family up to 1.8 GHz with 512 kB on-chip L2 cache |
---|
| 581 | # 7448 micro-architecture family (1.5 GHz) in 90 nm with 1MB L2 cache and slightly |
---|
| 582 | # improved AltiVec (out of order instructions). |
---|
| 583 | # 8640/8641/8640D/8641D with one or two e600 (Formerly known as G4) cores, 1MB L2 cache |
---|
| 584 | |
---|
| 585 | # PowerPC G5 series |
---|
| 586 | # 970 (2003), 64-bit, derived from POWER4, enhanced with VMX, 512 kB L2 cache, 1.4 – 2 GHz |
---|
| 587 | # 970FX (2004), manufactured at 90 nm, 1.8 - 2.7 GHz |
---|
| 588 | # 970GX (2006), manufactured at 90 nm, 1MB L2 cache/core, 1.2 - 2.5 GHz |
---|
| 589 | # 970MP (2005), dual core, 1 MB L2 cache/core, 1.6 - 2.5 GHz |
---|
| 590 | for k,v in cpuinfo_kv(): |
---|
| 591 | if k == 'processor': |
---|
| 592 | self.cpu_count += 1 |
---|
| 593 | elif k == 'cpu': |
---|
| 594 | self.is_altivec_supported = 'altivec' in v |
---|
| 595 | ppc_type, x = v.split(',') |
---|
| 596 | self.ppc_type = ppc_type.strip() |
---|
| 597 | # older kernels might not have a 'processor' line |
---|
| 598 | if self.cpu_count == 0: |
---|
| 599 | self.cpu_count += 1 |
---|
| 600 | |
---|
| 601 | |
---|
| 602 | def cpu_info_mips(self): |
---|
| 603 | "parse /proc/cpuinfo for MIPS kernels" |
---|
| 604 | for k,v in cpuinfo_kv(): |
---|
| 605 | if k == 'processor': |
---|
| 606 | self.cpu_count += 1 |
---|
| 607 | elif k == 'cpu model': |
---|
| 608 | self.mips_cpu_model = v |
---|
| 609 | |
---|
| 610 | |
---|
| 611 | def is_userspace_32bit(cpuinfo): |
---|
| 612 | """Even if `uname -m` reports a 64-bit architecture, userspace could still |
---|
| 613 | be 32-bit, such as Debian on powerpc64. This function tries to figure out |
---|
| 614 | if userspace is 32-bit, i.e. we might need to pass '-m32' or '-m64' to gcc. |
---|
| 615 | """ |
---|
| 616 | if not cpuinfo.is_64bit: |
---|
| 617 | return True |
---|
| 618 | # note that having a 64-bit CPU means nothing for these purposes. You could |
---|
| 619 | # run a completely 32-bit system on a 64-bit capable CPU. |
---|
| 620 | answer = None |
---|
| 621 | # Debian ppc64 returns machine 'ppc64', but userspace might be 32-bit |
---|
| 622 | # We'll make an educated guess by examining a known executable |
---|
| 623 | exe = '/bin/mount' |
---|
| 624 | if os.path.isfile(exe): |
---|
| 625 | #print 'Found %s' % exe |
---|
| 626 | if os.path.islink(exe): |
---|
| 627 | real_exe = os.path.join(os.path.dirname(exe), os.readlink(exe)) |
---|
| 628 | #print '%s is a symlink to %s' % (exe, real_exe) |
---|
| 629 | else: |
---|
| 630 | real_exe = exe |
---|
| 631 | # presumably if a person is running this script, they should have |
---|
| 632 | # a gcc toolchain installed... |
---|
| 633 | x = outputof('objdump', '-Wi', real_exe) |
---|
| 634 | # should emit a line that looks like this: |
---|
| 635 | # /bin/mount: file format elf32-i386 |
---|
| 636 | # or like this: |
---|
| 637 | # /bin/mount: file format elf64-x86-64 |
---|
| 638 | # or like this: |
---|
| 639 | # /bin/mount: file format elf32-powerpc |
---|
| 640 | for line in x.split('\n'): |
---|
| 641 | line = line.strip() |
---|
| 642 | if line.startswith(real_exe) and 'file format' in line: |
---|
| 643 | x, fmt = line.rsplit(None, 1) |
---|
| 644 | answer = 'elf32' in fmt |
---|
| 645 | break |
---|
| 646 | else: |
---|
| 647 | print '!!! Not found %s' % exe |
---|
| 648 | return answer |
---|
| 649 | |
---|
| 650 | |
---|
| 651 | def cc_flags_x86(cpuinfo, enable_optimizations): |
---|
| 652 | """add certain gcc -m flags based on CPU features |
---|
| 653 | """ |
---|
| 654 | # See http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/i386-and-x86_002d64-Options.html |
---|
| 655 | cc_opts = [] |
---|
| 656 | if cpuinfo.machine == 'i586': |
---|
| 657 | cc_opts.append('-march=i586') |
---|
| 658 | elif cpuinfo.machine == 'i686': |
---|
| 659 | cc_opts.append('-march=i686') |
---|
| 660 | |
---|
| 661 | if 'mmx' in cpuinfo.x86_flags: |
---|
| 662 | cc_opts.append('-mmmx') |
---|
| 663 | |
---|
| 664 | # map from proc/cpuinfo flags to gcc options |
---|
| 665 | opt_flags = [ |
---|
| 666 | ('sse', ('-mfpmath=sse', '-msse')), |
---|
| 667 | ('sse2', '-msse2'), |
---|
| 668 | ('ssse3', '-mssse3'), |
---|
| 669 | ('sse4', '-msse4'), |
---|
| 670 | ('sse4_1', '-msse4.1'), |
---|
| 671 | ('sse4_2', '-msse4.2'), |
---|
| 672 | ('sse4a', '-msse4a'), |
---|
| 673 | ('3dnow', '-m3dnow'), |
---|
| 674 | ] |
---|
| 675 | if enable_optimizations: |
---|
| 676 | for flag, gccopt in opt_flags: |
---|
| 677 | if flag in cpuinfo.x86_flags: |
---|
| 678 | if isinstance(gccopt, (tuple, list)): |
---|
| 679 | cc_opts.extend(gccopt) |
---|
| 680 | else: |
---|
| 681 | cc_opts.append(gccopt) |
---|
| 682 | return cc_opts |
---|
| 683 | |
---|
| 684 | |
---|
| 685 | def cc_flags_powerpc(cpuinfo, enable_optimizations): |
---|
| 686 | """add certain gcc -m flags based on CPU model |
---|
| 687 | """ |
---|
| 688 | cc_opts = [] |
---|
| 689 | if cpuinfo.is_altivec_supported: |
---|
| 690 | cc_opts.append ('-maltivec') |
---|
| 691 | cc_opts.append ('-mabi=altivec') |
---|
| 692 | |
---|
| 693 | if re.match('74[0145][0578]A?', cpuinfo.ppc_type) is not None: |
---|
| 694 | cc_opts.append ('-mcpu=7400') |
---|
| 695 | cc_opts.append ('-mtune=7400') |
---|
| 696 | elif re.match('750', cpuinfo.ppc_type) is not None: |
---|
| 697 | cc_opts.append ('-mcpu=750') |
---|
| 698 | cc_opts.append ('-mtune=750') |
---|
| 699 | elif re.match('PPC970', cpuinfo.ppc_type) is not None: |
---|
| 700 | cc_opts.append ('-mcpu=970') |
---|
| 701 | cc_opts.append ('-mtune=970') |
---|
| 702 | elif re.match('Cell Broadband Engine', cpuinfo.ppc_type) is not None: |
---|
| 703 | cc_opts.append('-mcpu=cell') |
---|
| 704 | cc_opts.append('-mtune=cell') |
---|
| 705 | return cc_opts |
---|
| 706 | #=== End Revised CXXFLAGS ========================================= |
---|
| 707 | |
---|
507 | | if ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None) or (re.search ("powerpc", config[config_cpu]) != None)): |
---|
508 | | |
---|
509 | | build_host_supports_sse = 0 |
---|
510 | | build_host_supports_sse2 = 0 |
---|
511 | | build_host_supports_sse3 = 0 |
---|
512 | | |
---|
513 | | if config[config_kernel] == 'linux' : |
---|
514 | | |
---|
515 | | if (env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64'): |
---|
516 | | |
---|
517 | | flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1] |
---|
518 | | x86_flags = flag_line.split (": ")[1:][0].split () |
---|
519 | | |
---|
520 | | if "mmx" in x86_flags: |
---|
521 | | opt_flags.append ("-mmmx") |
---|
522 | | if "sse" in x86_flags: |
---|
523 | | build_host_supports_sse = 1 |
---|
524 | | if "sse2" in x86_flags: |
---|
525 | | build_host_supports_sse2 = 1 |
---|
526 | | #if "sse3" in x86_flags: |
---|
527 | | #build_host_supports_sse3 = 1 |
---|
528 | | if "3dnow" in x86_flags: |
---|
529 | | opt_flags.append ("-m3dnow") |
---|
530 | | |
---|
531 | | if config[config_cpu] == "i586": |
---|
532 | | opt_flags.append ("-march=i586") |
---|
533 | | elif config[config_cpu] == "i686": |
---|
534 | | opt_flags.append ("-march=i686") |
---|
535 | | |
---|
536 | | elif (env['DIST_TARGET'] == 'powerpc') or (env['DIST_TARGET'] == 'powerpc64'): |
---|
537 | | |
---|
538 | | cpu_line = os.popen ("cat /proc/cpuinfo | grep '^cpu'").read()[:-1] |
---|
539 | | |
---|
540 | | ppc_type = cpu_line.split (": ")[1] |
---|
541 | | if re.search ("altivec", ppc_type) != None: |
---|
542 | | opt_flags.append ("-maltivec") |
---|
543 | | opt_flags.append ("-mabi=altivec") |
---|
544 | | |
---|
545 | | ppc_type = ppc_type.split (", ")[0] |
---|
546 | | if re.match ("74[0145][0578]A?", ppc_type) != None: |
---|
547 | | opt_flags.append ("-mcpu=7400") |
---|
548 | | opt_flags.append ("-mtune=7400") |
---|
549 | | elif re.match ("750", ppc_type) != None: |
---|
550 | | opt_flags.append ("-mcpu=750") |
---|
551 | | opt_flags.append ("-mtune=750") |
---|
552 | | elif re.match ("PPC970", ppc_type) != None: |
---|
553 | | opt_flags.append ("-mcpu=970") |
---|
554 | | opt_flags.append ("-mtune=970") |
---|
555 | | elif re.match ("Cell Broadband Engine", ppc_type) != None: |
---|
556 | | opt_flags.append ("-mcpu=cell") |
---|
557 | | opt_flags.append ("-mtune=cell") |
---|
558 | | |
---|
559 | | if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \ |
---|
560 | | and build_host_supports_sse and env['ENABLE_OPTIMIZATIONS']: |
---|
561 | | opt_flags.extend (["-msse", "-mfpmath=sse"]) |
---|
562 | | env['USE_SSE'] = 1 |
---|
563 | | |
---|
564 | | if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \ |
---|
565 | | and build_host_supports_sse2 and env['ENABLE_OPTIMIZATIONS']: |
---|
566 | | opt_flags.extend (["-msse2"]) |
---|
567 | | env['USE_SSE2'] = 1 |
---|
568 | | |
---|
569 | | #if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \ |
---|
570 | | #and build_host_supports_sse2 and env['ENABLE_OPTIMIZATIONS']: |
---|
571 | | #opt_flags.extend (["-msse3"]) |
---|
572 | | #env['USE_SSE3'] = 1 |
---|
573 | | |
---|
574 | | # build for 64-bit userland? |
---|
575 | | if env['DIST_TARGET'] == "powerpc64": |
---|
576 | | print "Doing a 64-bit PowerPC build" |
---|
| 724 | #=== Begin Revised CXXFLAGS ========================================= |
---|
| 725 | # comment on DIST_TARGET up top implies it can be used for cross-compiling |
---|
| 726 | # but that's not true because even if it is not 'auto' the original |
---|
| 727 | # script still reads /proc/cpuinfo to determine gcc arch flags. |
---|
| 728 | # This script does the same as the original. Needs to be fixed someday. |
---|
| 729 | cpuinfo = CpuInfo() |
---|
| 730 | if cpuinfo.is_x86: |
---|
| 731 | opt_flags.extend(cc_flags_x86(cpuinfo, env['ENABLE_OPTIMIZATIONS'])) |
---|
| 732 | if cpuinfo.is_powerpc: |
---|
| 733 | opt_flags.extend(cc_flags_powerpc(cpuinfo, env['ENABLE_OPTIMIZATIONS'])) |
---|
| 734 | if '-msse' in opt_flags: |
---|
| 735 | env['USE_SSE'] = 1 |
---|
| 736 | if '-msse2' in opt_flags: |
---|
| 737 | env['USE_SSE2'] = 1 |
---|
| 738 | |
---|
| 739 | m32 = is_userspace_32bit(cpuinfo) |
---|
| 740 | print 'User space is %s' % (m32 and '32-bit' or '64-bit') |
---|
| 741 | if cpuinfo.is_powerpc: |
---|
| 742 | if m32: |
---|
| 743 | print "Doing a 32-bit PowerPC build for %s CPU" % cpuinfo.ppc_type |
---|
| 744 | machineflags = { 'CXXFLAGS' : ['-m32'] } |
---|
| 745 | else: |
---|
| 746 | print "Doing a 64-bit PowerPC build for %s CPU" % cpuinfo.ppc_type |
---|