Repository: mesonbuild/meson

Issue:
AttributeError with Emscripten since Meson 0.56.0
**Describe the bug**
Meson raises this `AttributeError` when cross-building glib with Emscripten.

```
Checking if "atomic ops define" compiles: NO 
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/mesonmain.py", line 140, in run
    return options.run_func(options)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/msetup.py", line 253, in run
    app.generate()
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/msetup.py", line 161, in generate
    self._generate(env)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/msetup.py", line 200, in _generate
    intr.run()
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreter.py", line 4703, in run
    super().run()
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 519, in run
    self.evaluate_codeblock(self.ast, start=1)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 544, in evaluate_codeblock
    raise e
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 537, in evaluate_codeblock
    self.evaluate_statement(cur)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 560, in evaluate_statement
    return self.evaluate_if(cur)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 647, in evaluate_if
    self.evaluate_codeblock(node.elseblock)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 544, in evaluate_codeblock
    raise e
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 537, in evaluate_codeblock
    self.evaluate_statement(cur)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 552, in evaluate_statement
    self.assignment(cur)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 1219, in assignment
    value = self.evaluate_statement(node.value)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 550, in evaluate_statement
    return self.function_call(cur)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 909, in function_call
    return func(node, func_args, kwargs)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 393, in wrapped
    return f(*wrapped_args, **wrapped_kwargs)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 393, in wrapped
    return f(*wrapped_args, **wrapped_kwargs)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 393, in wrapped
    return f(*wrapped_args, **wrapped_kwargs)
  [Previous line repeated 3 more times]
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 209, in wrapped
    ret = f(*wrapped_args, **wrapped_kwargs)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreterbase.py", line 228, in wrapped
    return f(*wrapped_args, **wrapped_kwargs)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreter.py", line 3719, in func_dependency
    d = self.dependency_impl(name, display_name, kwargs)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/interpreter.py", line 3813, in dependency_impl
    dep = dependencies.find_external_dependency(name, self.environment, kwargs)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/dependencies/base.py", line 2392, in find_external_dependency
    d = c()
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/dependencies/misc.py", line 118, in __init__
    self.link_args = self.clib_compiler.thread_link_flags(environment)
  File "/usr/local/lib/python3.7/dist-packages/mesonbuild/compilers/mixins/emscripten.py", line 53, in thread_link_flags
    count = env.coredata.compiler_options[self.for_machine]['{}_thread_count'.format(self.language)].value  # type: int
AttributeError: 'dict' object has no attribute 'value'
```

Reverting to Meson 0.55.3 or applying this patch seems to fix it:
```diff
diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py
index 1111111..2222222 100644
--- a/mesonbuild/compilers/mixins/emscripten.py
+++ b/mesonbuild/compilers/mixins/emscripten.py
@@ -50,7 +50,7 @@ class EmscriptenMixin(Compiler):
 
     def thread_link_flags(self, env: 'Environment') -> T.List[str]:
         args = ['-s', 'USE_PTHREADS=1']
-        count = env.coredata.compiler_options[self.for_machine]['{}_thread_count'.format(self.language)].value  # type: int
+        count = env.coredata.compiler_options[self.for_machine][self.language]['thread_count'].value  # type: int
         if count:
             args.extend(['-s', 'PTHREAD_POOL_SIZE={}'.format(count)])
         return args
@@ -58,7 +58,7 @@ class EmscriptenMixin(Compiler):
     def get_options(self) -> 'coredata.OptionDictType':
         opts = super().get_options()
         opts.update({
-            '{}_thread_count'.format(self.language): coredata.UserIntegerOption(
+            'thread_count': coredata.UserIntegerOption(
                 'Number of threads to use in web assembly, set to 0 to disable',
                 (0, None, 4),  # Default was picked at random
             ),
```

**To Reproduce**
```bash
git clone https://github.com/kleisauke/wasm-vips.git
cd wasm-vips
docker build -t wasm-vips .
docker run --rm -v $(pwd):/src wasm-vips ./build.sh -e node --enable-simd
```
(If you want, I could make a minimal reproduction)

**Expected behavior**
Successful build (like Meson 0.55.3).

**system parameters**
* Docker cross build (emscripten)
* Debian 10.6 (buster)
* Python 3.7.3
* meson 0.56.0 (https://github.com/mesonbuild/meson/commit/f16d31607eb3cd0f281758bd0944e206ef6be387)
* Ninja 1.8.2


Discussion:
Here's a simplified minimal reproduction:
```bash
# Download and install the latest tagged Emscripten release
# See https://emscripten.org/docs/getting_started/downloads.html#installation-instructions
cd ~
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh

# Reproduce the above AttributeError
cd ~
git clone https://github.com/mesonbuild/meson
cd "meson/test cases/wasm/2 threads"
curl -LO https://github.com/kleisauke/wasm-vips/raw/master/build/emscripten-crossfile.meson
meson setup _build --cross-file=emscripten-crossfile.meson --default-library=static --buildtype=release
emmake ninja -C _build
```

Resolving patch:
diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py
--- a/mesonbuild/compilers/mixins/emscripten.py
+++ b/mesonbuild/compilers/mixins/emscripten.py
@@ -50,7 +50,7 @@ def thread_flags(self, env: 'Environment') -> T.List[str]:
 
     def thread_link_flags(self, env: 'Environment') -> T.List[str]:
         args = ['-s', 'USE_PTHREADS=1']
-        count = env.coredata.compiler_options[self.for_machine]['{}_thread_count'.format(self.language)].value  # type: int
+        count = env.coredata.compiler_options[self.for_machine][self.language]['thread_count'].value  # type: int
         if count:
             args.extend(['-s', 'PTHREAD_POOL_SIZE={}'.format(count)])
         return args
@@ -58,7 +58,7 @@ def thread_link_flags(self, env: 'Environment') -> T.List[str]:
     def get_options(self) -> 'coredata.OptionDictType':
         opts = super().get_options()
         opts.update({
-            '{}_thread_count'.format(self.language): coredata.UserIntegerOption(
+            'thread_count': coredata.UserIntegerOption(
                 'Number of threads to use in web assembly, set to 0 to disable',
                 (0, None, 4),  # Default was picked at random
             ),


Test patch: