bug 1248020 - add USE_YASM to moz.build. r?mshal draft
authorTed Mielczarek <ted@mielczarek.org>
Tue, 01 Mar 2016 21:12:36 -0500
changeset 336547 09e174884822554810d6a049d09d5f30529d80ab
parent 336544 d7eddb71b050e0576e783c6ce8c67f66cfd88e13
child 336548 9bfc0633bdbdd2c1076f05fd6959604a16e8c63a
push id12114
push usertmielczarek@mozilla.com
push dateThu, 03 Mar 2016 17:49:00 +0000
reviewersmshal
bugs1248020
milestone47.0a1
bug 1248020 - add USE_YASM to moz.build. r?mshal MozReview-Commit-ID: Liw4RGOXiVf
old-configure.in
python/mozbuild/mozbuild/frontend/context.py
python/mozbuild/mozbuild/frontend/emitter.py
python/mozbuild/mozbuild/test/frontend/data/use-yasm/moz.build
python/mozbuild/mozbuild/test/frontend/test_emitter.py
--- a/old-configure.in
+++ b/old-configure.in
@@ -3391,17 +3391,48 @@ if test -n "$YASM"; then
   AC_MSG_CHECKING([yasm version])
   dnl Pull out yasm's version string
   YASM_VERSION=`yasm --version | $AWK '/^yasm/ { print $2 }'`
   _YASM_MAJOR_VERSION=`echo ${YASM_VERSION} | $AWK -F\. '{ print $1 }'`
   _YASM_MINOR_VERSION=`echo ${YASM_VERSION} | $AWK -F\. '{ print $2 }'`
   _YASM_RELEASE=`      echo ${YASM_VERSION} | $AWK -F\. '{ print $3 }'`
   _YASM_BUILD=`        echo ${YASM_VERSION} | $AWK -F\. '{ print $4 }'`
   AC_MSG_RESULT([$_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION.$_YASM_RELEASE ($YASM_VERSION)])
-fi
+
+  # Determine proper yasm arguments.
+  YASM_ASFLAGS=
+  case "$OS_ARCH:$CPU_ARCH" in
+    Darwin:x86)
+      YASM_ASFLAGS="-f macho32 -rnasm -pnasm"
+    ;;
+    Darwin:x86_64)
+      YASM_ASFLAGS="-f macho64 -rnasm -pnasm"
+    ;;
+    WINNT:x86_64)
+      YASM_ASFLAGS="-f x64 -rnasm -pnasm"
+    ;;
+    WINNT:x86)
+      YASM_ASFLAGS="-f win32 -rnasm -pnasm"
+    ;;
+    *:x86)
+      if $CC -E -dM -</dev/null | grep -q __ELF__; then
+        YASM_ASFLAGS="-f elf32 -rnasm -pnasm"
+      fi
+    ;;
+    *:x86_64)
+      if $CC -E -dM -</dev/null | grep -q __ELF__; then
+        YASM_ASFLAGS="-f elf64 -rnasm -pnasm"
+      fi
+    ;;
+    *)
+      # yasm doesn't support other architectures, so just disable it.
+      YASM=
+  esac
+fi
+AC_SUBST(YASM_ASFLAGS)
 
 if test -z "$SKIP_LIBRARY_CHECKS"; then
 dnl system JPEG support
 dnl ========================================================
 MOZ_ARG_WITH_STRING(system-jpeg,
 [  --with-system-jpeg[=PFX]
                           Use system libjpeg [installed at prefix PFX]],
     JPEG_DIR=$withval)
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -1713,16 +1713,27 @@ VARIABLES = {
         """Forces to build a real static library, and no corresponding fake
            library.
         """),
 
     'NO_COMPONENTS_MANIFEST': (bool, bool,
         """Do not create a binary-component manifest entry for the
         corresponding XPCOMBinaryComponent.
         """),
+
+    'USE_YASM': (bool, bool,
+        """Use the yasm assembler to assemble assembly files from SOURCES.
+
+        By default, the build will use the toolchain assembler, $(AS), to
+        assemble source files in assembly language (.s or .asm files). Setting
+        this value to ``True`` will cause it to use yasm instead.
+
+        If yasm is not available on this system, or does not support the
+        current target architecture, an error will be raised.
+        """),
 }
 
 # Sanity check: we don't want any variable above to have a list as storage type.
 for name, (storage_type, input_types, docs) in VARIABLES.items():
     if storage_type == list:
         raise RuntimeError('%s has a "list" storage type. Use "List" instead.'
             % name)
 
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -908,16 +908,24 @@ class TreeMetadataEmitter(LoggingMixin):
             yield obj
 
         for name, jar in context.get('JAVA_JAR_TARGETS', {}).items():
             yield ContextWrapped(context, jar)
 
         for name, data in context.get('ANDROID_ECLIPSE_PROJECT_TARGETS', {}).items():
             yield ContextWrapped(context, data)
 
+        if context.get('USE_YASM') is True:
+            yasm = context.config.substs.get('YASM')
+            if not yasm:
+                raise SandboxValidationError('yasm is not available', context)
+            passthru.variables['AS'] = yasm
+            passthru.variables['ASFLAGS'] = context.config.substs.get('YASM_ASFLAGS')
+            passthru.variables['AS_DASH_C_FLAG'] = ''
+
         for (symbol, cls) in [
                 ('ANDROID_RES_DIRS', AndroidResDirs),
                 ('ANDROID_EXTRA_RES_DIRS', AndroidExtraResDirs),
                 ('ANDROID_ASSETS_DIRS', AndroidAssetsDirs)]:
             paths = context.get(symbol)
             if not paths:
                 continue
             for p in paths:
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/use-yasm/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+USE_YASM = True
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -60,22 +60,25 @@ class TestEmitterBasic(unittest.TestCase
     def setUp(self):
         self._old_env = dict(os.environ)
         os.environ.pop('MOZ_OBJDIR', None)
 
     def tearDown(self):
         os.environ.clear()
         os.environ.update(self._old_env)
 
-    def reader(self, name, enable_tests=False):
-        config = MockConfig(mozpath.join(data_path, name), extra_substs=dict(
+    def reader(self, name, enable_tests=False, extra_substs=None):
+        substs = dict(
             ENABLE_TESTS='1' if enable_tests else '',
             BIN_SUFFIX='.prog',
             OS_TARGET='WINNT',
-        ))
+        )
+        if extra_substs:
+            substs.update(extra_substs)
+        config = MockConfig(mozpath.join(data_path, name), extra_substs=substs)
 
         return BuildReader(config)
 
     def read_topsrcdir(self, reader, filter_common=True):
         emitter = TreeMetadataEmitter(reader.config)
         objs = list(emitter.emit(reader.read_topsrcdir()))
         self.assertGreater(len(objs), 0)
 
@@ -189,16 +192,42 @@ class TestEmitterBasic(unittest.TestCase
         }
 
         variables = objs[0].variables
         maxDiff = self.maxDiff
         self.maxDiff = None
         self.assertEqual(wanted, variables)
         self.maxDiff = maxDiff
 
+    def test_use_yasm(self):
+        # When yasm is not available, this should raise.
+        reader = self.reader('use-yasm')
+        with self.assertRaisesRegexp(SandboxValidationError,
+            'yasm is not available'):
+            objs = self.read_topsrcdir(reader)
+
+        # When yasm is available, this should work.
+        reader = self.reader('use-yasm',
+                             extra_substs=dict(
+                                 YASM='yasm',
+                                 YASM_ASFLAGS='-foo',
+                             ))
+        objs = self.read_topsrcdir(reader)
+
+        self.assertEqual(len(objs), 1)
+        self.assertIsInstance(objs[0], VariablePassthru)
+        maxDiff = self.maxDiff
+        self.maxDiff = None
+        self.assertEqual(objs[0].variables,
+                         {'AS': 'yasm',
+                          'ASFLAGS': '-foo',
+                          'AS_DASH_C_FLAG': ''})
+        self.maxDiff = maxDiff
+
+
     def test_generated_files(self):
         reader = self.reader('generated-files')
         objs = self.read_topsrcdir(reader)
 
         self.assertEqual(len(objs), 2)
         for o in objs:
             self.assertIsInstance(o, GeneratedFile)