From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan Tojnar <jtojnar@gmail.com>
Date: Tue, 12 Jul 2022 15:22:30 +0200
Subject: [PATCH] compilers: Add optimization=plain option
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

https://github.com/mesonbuild/meson/pull/9287 changed the `optimization=0`
to pass `-O0` to the compiler. This change is reasonable by itself
but unfortunately, it breaks `buildtype=plain`, which promises
that “no extra build flags are used”.

`buildtype=plain` is important for distros like NixOS,
which manage compiler flags for optimization and hardening
themselves.

Let’s introduce a new optimization level that does nothing
and set it as the default for `buildtype=plain`.

(cherry picked from commit 70663f652863443b427e6711ec5ce6c07b85ff84)
---
 mesonbuild/backend/xcodebackend.py               | 7 +++++--
 mesonbuild/compilers/compilers.py                | 6 ++++--
 mesonbuild/compilers/cs.py                       | 4 +++-
 mesonbuild/compilers/d.py                        | 6 ++++--
 mesonbuild/compilers/mixins/arm.py               | 2 ++
 mesonbuild/compilers/mixins/clang.py             | 1 +
 mesonbuild/compilers/mixins/compcert.py          | 1 +
 mesonbuild/compilers/mixins/gnu.py               | 1 +
 mesonbuild/compilers/mixins/intel.py             | 6 ++++--
 mesonbuild/compilers/mixins/ti.py                | 1 +
 mesonbuild/compilers/mixins/visualstudio.py      | 1 +
 mesonbuild/compilers/mixins/xc16.py              | 1 +
 mesonbuild/compilers/rust.py                     | 1 +
 mesonbuild/compilers/swift.py                    | 1 +
 mesonbuild/coredata.py                           | 6 +++---
 test cases/failing/101 number in combo/test.json | 2 +-
 16 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index 0d8bafb4b745..9e101ce63aa4 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -52,7 +52,8 @@ LANGNAMEMAP = {'c': 'C',
                'objcpp': 'OBJCPLUSPLUS',
                'swift': 'SWIFT_'
                }
-OPT2XCODEOPT = {'0': '0',
+OPT2XCODEOPT = {'plain': None,
+                '0': '0',
                 'g': '0',
                 '1': '1',
                 '2': '2',
@@ -1561,7 +1562,9 @@ class XCodeBackend(backends.Backend):
                 settings_dict.add_item('EXECUTABLE_SUFFIX', suffix)
             settings_dict.add_item('GCC_GENERATE_DEBUGGING_SYMBOLS', BOOL2XCODEBOOL[target.get_option(OptionKey('debug'))])
             settings_dict.add_item('GCC_INLINES_ARE_PRIVATE_EXTERN', 'NO')
-            settings_dict.add_item('GCC_OPTIMIZATION_LEVEL', OPT2XCODEOPT[target.get_option(OptionKey('optimization'))])
+            opt_flag = OPT2XCODEOPT[target.get_option(OptionKey('optimization'))]
+            if opt_flag is not None:
+                settings_dict.add_item('GCC_OPTIMIZATION_LEVEL', opt_flag)
             if target.has_pch:
                 # Xcode uses GCC_PREFIX_HEADER which only allows one file per target/executable. Precompiling various header files and
                 # applying a particular pch to each source file will require custom scripts (as a build phase) and build flags per each
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 20e35ee6b1bc..4f18af7f3e5e 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -247,15 +247,17 @@ msvc_winlibs = ['kernel32.lib', 'user32.lib', 'gdi32.lib',
                 'winspool.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib',
                 'uuid.lib', 'comdlg32.lib', 'advapi32.lib']  # type: T.List[str]
 
-clike_optimization_args = {'0': [],
+clike_optimization_args = {'plain': [],
+                           '0': [],
                            'g': [],
                            '1': ['-O1'],
                            '2': ['-O2'],
                            '3': ['-O3'],
                            's': ['-Os'],
                            }  # type: T.Dict[str, T.List[str]]
 
-cuda_optimization_args = {'0': [],
+cuda_optimization_args = {'plain': [],
+                          '0': [],
                           'g': ['-O0'],
                           '1': ['-O1'],
                           '2': ['-O2'],
diff --git a/mesonbuild/compilers/cs.py b/mesonbuild/compilers/cs.py
index b38f626a820f..3f020e2cfd00 100644
--- a/mesonbuild/compilers/cs.py
+++ b/mesonbuild/compilers/cs.py
@@ -26,7 +26,9 @@ if T.TYPE_CHECKING:
     from ..envconfig import MachineInfo
     from ..environment import Environment
 
-cs_optimization_args = {'0': [],
+cs_optimization_args = {
+                        'plain': [],
+                        '0': [],
                         'g': [],
                         '1': ['-optimize+'],
                         '2': ['-optimize+'],
diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py
index 8e331ec359a1..ab42099ae74b 100644
--- a/mesonbuild/compilers/d.py
+++ b/mesonbuild/compilers/d.py
@@ -64,15 +64,17 @@ d_feature_args = {'gcc':  {'unittest': '-funittest',
                            }
                   }  # type: T.Dict[str, T.Dict[str, str]]
 
-ldc_optimization_args = {'0': [],
+ldc_optimization_args = {'plain': [],
+                         '0': [],
                          'g': [],
                          '1': ['-O1'],
                          '2': ['-O2'],
                          '3': ['-O3'],
                          's': ['-Oz'],
                          }  # type: T.Dict[str, T.List[str]]
 
-dmd_optimization_args = {'0': [],
+dmd_optimization_args = {'plain': [],
+                         '0': [],
                          'g': [],
                          '1': ['-O'],
                          '2': ['-O'],
diff --git a/mesonbuild/compilers/mixins/arm.py b/mesonbuild/compilers/mixins/arm.py
index 5bf862ddf197..b3abd70d6936 100644
--- a/mesonbuild/compilers/mixins/arm.py
+++ b/mesonbuild/compilers/mixins/arm.py
@@ -43,24 +43,26 @@ arm_buildtype_args = {
 }  # type: T.Dict[str, T.List[str]]
 
 arm_optimization_args = {
+    'plain': [],
     '0': ['-O0'],
     'g': ['-g'],
     '1': ['-O1'],
     '2': [], # Compiler defaults to -O2
     '3': ['-O3', '-Otime'],
     's': ['-O3'], # Compiler defaults to -Ospace
 }  # type: T.Dict[str, T.List[str]]
 
 armclang_buildtype_args = {
     'plain': [],
     'debug': [],
     'debugoptimized': [],
     'release': [],
     'minsize': [],
     'custom': [],
 }  # type: T.Dict[str, T.List[str]]
 
 armclang_optimization_args = {
+    'plain': [],
     '0': [], # Compiler defaults to -O0
     'g': ['-g'],
     '1': ['-O1'],
diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py
index 5083ace7c72b..4ac9b92c60c2 100644
--- a/mesonbuild/compilers/mixins/clang.py
+++ b/mesonbuild/compilers/mixins/clang.py
@@ -35,6 +35,7 @@ clang_color_args = {
 }  # type: T.Dict[str, T.List[str]]
 
 clang_optimization_args = {
+    'plain': [],
     '0': ['-O0'],
     'g': ['-Og'],
     '1': ['-O1'],
diff --git a/mesonbuild/compilers/mixins/compcert.py b/mesonbuild/compilers/mixins/compcert.py
index ce872002c341..78f4f9f13574 100644
--- a/mesonbuild/compilers/mixins/compcert.py
+++ b/mesonbuild/compilers/mixins/compcert.py
@@ -40,6 +40,7 @@ ccomp_buildtype_args = {
 }  # type: T.Dict[str, T.List[str]]
 
 ccomp_optimization_args = {
+    'plain': [],
     '0': ['-O0'],
     'g': ['-O0'],
     '1': ['-O1'],
diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py
index 1b1e8a1c1332..11efcc9fe2dc 100644
--- a/mesonbuild/compilers/mixins/gnu.py
+++ b/mesonbuild/compilers/mixins/gnu.py
@@ -55,6 +55,7 @@ gnulike_buildtype_args = {
 }  # type: T.Dict[str, T.List[str]]
 
 gnu_optimization_args = {
+    'plain': [],
     '0': ['-O0'],
     'g': ['-Og'],
     '1': ['-O1'],
diff --git a/mesonbuild/compilers/mixins/intel.py b/mesonbuild/compilers/mixins/intel.py
index 2698b393096a..9877a54ff4c8 100644
--- a/mesonbuild/compilers/mixins/intel.py
+++ b/mesonbuild/compilers/mixins/intel.py
@@ -58,7 +58,8 @@ class IntelGnuLikeCompiler(GnuLikeCompiler):
         'custom': [],
     }  # type: T.Dict[str, T.List[str]]
 
-    OPTIM_ARGS = {
+    OPTIM_ARGS: T.Dict[str, T.List[str]] = {
+        'plain': [],
         '0': ['-O0'],
         'g': ['-O0'],
         '1': ['-O1'],
@@ -136,7 +137,8 @@ class IntelVisualStudioLikeCompiler(VisualStudioLikeCompiler):
         'custom': [],
     }  # type: T.Dict[str, T.List[str]]
 
-    OPTIM_ARGS = {
+    OPTIM_ARGS: T.Dict[str, T.List[str]] = {
+        'plain': [],
         '0': ['/Od'],
         'g': ['/Od'],
         '1': ['/O1'],
diff --git a/mesonbuild/compilers/mixins/ti.py b/mesonbuild/compilers/mixins/ti.py
index 9ee6f272f410..d2d7f3b55fdc 100644
--- a/mesonbuild/compilers/mixins/ti.py
+++ b/mesonbuild/compilers/mixins/ti.py
@@ -41,6 +41,7 @@ ti_buildtype_args = {
 }  # type: T.Dict[str, T.List[str]]
 
 ti_optimization_args = {
+    'plain': [],
     '0': ['-O0'],
     'g': ['-Ooff'],
     '1': ['-O1'],
diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py
index f4f2f1e1d0c7..d3b01108192e 100644
--- a/mesonbuild/compilers/mixins/visualstudio.py
+++ b/mesonbuild/compilers/mixins/visualstudio.py
@@ -62,6 +62,7 @@ vs64_instruction_set_args = {
 }  # T.Dicst[str, T.Optional[T.List[str]]]
 
 msvc_optimization_args = {
+    'plain': [],
     '0': ['/Od'],
     'g': [], # No specific flag to optimize debugging, /Zi or /ZI will create debug information
     '1': ['/O1'],
diff --git a/mesonbuild/compilers/mixins/xc16.py b/mesonbuild/compilers/mixins/xc16.py
index 3c8b68b3258a..27c4fbc05664 100644
--- a/mesonbuild/compilers/mixins/xc16.py
+++ b/mesonbuild/compilers/mixins/xc16.py
@@ -41,6 +41,7 @@ xc16_buildtype_args = {
 }  # type: T.Dict[str, T.List[str]]
 
 xc16_optimization_args = {
+    'plain': [],
     '0': ['-O0'],
     'g': ['-O0'],
     '1': ['-O1'],
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index 296c53906ae4..168448f5be8c 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -31,6 +31,7 @@ if T.TYPE_CHECKING:
 
 
 rust_optimization_args = {
+    'plain': [],
     '0': [],
     'g': ['-C', 'opt-level=0'],
     '1': ['-C', 'opt-level=1'],
diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py
index a2b57b872f4a..6515387d1639 100644
--- a/mesonbuild/compilers/swift.py
+++ b/mesonbuild/compilers/swift.py
@@ -25,6 +25,7 @@ if T.TYPE_CHECKING:
     from ..linkers import DynamicLinker
 
 swift_optimization_args = {
+    'plain': [],
     '0': [],
     'g': [],
     '1': ['-O'],
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 916212aacf2d..90c212d5a3ed 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -693,34 +693,34 @@ class CoreData:
         result = []
         value = self.options[OptionKey('buildtype')].value
         if value == 'plain':
-            opt = '0'
+            opt = 'plain'
             debug = False
         elif value == 'debug':
             opt = '0'
             debug = True
         elif value == 'debugoptimized':
             opt = '2'
             debug = True
         elif value == 'release':
             opt = '3'
             debug = False
         elif value == 'minsize':
             opt = 's'
             debug = True
         else:
             assert value == 'custom'
             return []
         actual_opt = self.options[OptionKey('optimization')].value
         actual_debug = self.options[OptionKey('debug')].value
         if actual_opt != opt:
             result.append(('optimization', actual_opt, opt))
         if actual_debug != debug:
             result.append(('debug', actual_debug, debug))
         return result
 
     def _set_others_from_buildtype(self, value: str) -> None:
         if value == 'plain':
-            opt = '0'
+            opt = 'plain'
             debug = False
         elif value == 'debug':
             opt = '0'
@@ -1217,7 +1217,7 @@ BUILTIN_CORE_OPTIONS: 'MutableKeyedOptionDictType' = OrderedDict([
     (OptionKey('errorlogs'),       BuiltinOption(UserBooleanOption, "Whether to print the logs from failing tests", True)),
     (OptionKey('install_umask'),   BuiltinOption(UserUmaskOption, 'Default umask to apply on permissions of installed files', '022')),
     (OptionKey('layout'),          BuiltinOption(UserComboOption, 'Build directory layout', 'mirror', choices=['mirror', 'flat'])),
-    (OptionKey('optimization'),    BuiltinOption(UserComboOption, 'Optimization level', '0', choices=['0', 'g', '1', '2', '3', 's'])),
+    (OptionKey('optimization'),    BuiltinOption(UserComboOption, 'Optimization level', '0', choices=['plain', '0', 'g', '1', '2', '3', 's'])),
     (OptionKey('prefer_static'),   BuiltinOption(UserBooleanOption, 'Whether to try static linking before shared linking', False)),
     (OptionKey('stdsplit'),        BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True)),
     (OptionKey('strip'),           BuiltinOption(UserBooleanOption, 'Strip targets on install', False)),
diff --git a/test cases/failing/101 number in combo/test.json b/test cases/failing/101 number in combo/test.json
index 5d37df109f3a..4c30f98002ed 100644
--- a/test cases/failing/101 number in combo/test.json	
+++ b/test cases/failing/101 number in combo/test.json	
@@ -1,5 +1,5 @@
 {
   "stdout": [
-    { "line": "test cases/failing/101 number in combo/meson.build:1:0: ERROR: Value \"1\" (of type \"number\") for combo option \"Optimization level\" is not one of the choices. Possible choices are (as string): \"0\", \"g\", \"1\", \"2\", \"3\", \"s\"." }
+    { "line": "test cases/failing/101 number in combo/meson.build:1:0: ERROR: Value \"1\" (of type \"number\") for combo option \"Optimization level\" is not one of the choices. Possible choices are (as string): \"plain\", \"0\", \"g\", \"1\", \"2\", \"3\", \"s\"." }
   ]
 }
