Skip to content

Commit

Permalink
compilers: Only insert -flto-jobs in clang's link arguments
Browse files Browse the repository at this point in the history
Clang has a hand `-Wunused-command-line-argument` switch, which when
turned to an error, gets very grump about `-flto-jobs=0` being set in
the compiler arguments (although `-flto=` belongs there). We'll refactor
a bit to put that only in the link arguments.

GCC doesn't have this probably because, a) it doesn't have an equivalent
warning, and b) it uses `-flto=<$numthreads.

Fixes: mesonbuild#8347
  • Loading branch information
dcbaker authored and tristan957 committed Mar 2, 2021
1 parent 8235bcb commit bb0e3dc
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 8 deletions.
6 changes: 4 additions & 2 deletions mesonbuild/compilers/compilers.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,9 @@ def get_base_link_args(options: 'KeyedOptionDictType', linker: 'Compiler',
args = [] # type: T.List[str]
try:
if options[OptionKey('b_lto')].value:
args.extend(linker.get_lto_link_args())
args.extend(linker.get_lto_link_args(
threads=get_option_value(options, OptionKey('b_lto_threads'), 0),
mode=get_option_value(options, OptionKey('b_lto_mode'), 'default')))
except KeyError:
pass
try:
Expand Down Expand Up @@ -950,7 +952,7 @@ def remove_linkerlike_args(self, args: T.List[str]) -> T.List[str]:
def get_lto_compile_args(self, *, threads: int = 0, mode: str = 'default') -> T.List[str]:
return []

def get_lto_link_args(self) -> T.List[str]:
def get_lto_link_args(self, *, threads: int = 0, mode: str = 'default') -> T.List[str]:
return self.linker.get_lto_args()

def sanitizer_compile_args(self, value: str) -> T.List[str]:
Expand Down
4 changes: 4 additions & 0 deletions mesonbuild/compilers/mixins/clang.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ def get_lto_compile_args(self, *, threads: int = 0, mode: str = 'default') -> T.
else:
assert mode == 'default', 'someone forgot to wire something up'
args.extend(super().get_lto_compile_args(threads=threads))
return args

def get_lto_link_args(self, *, threads: int = 0, mode: str = 'default') -> T.List[str]:
args = self.get_lto_compile_args(threads=threads, mode=mode)
# In clang -flto=0 means auto
if threads >= 0:
args.append(f'-flto-jobs={threads}')
Expand Down
2 changes: 1 addition & 1 deletion mesonbuild/compilers/mixins/islinker.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class BasicLinkerIsCompilerMixin(Compiler):
def sanitizer_link_args(self, value: str) -> T.List[str]:
return []

def get_lto_link_args(self) -> T.List[str]:
def get_lto_link_args(self, *, threads: int = 0, mode: str = 'default') -> T.List[str]:
return []

def can_linker_accept_rsp(self) -> bool:
Expand Down
14 changes: 9 additions & 5 deletions run_unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3062,10 +3062,14 @@ def test_lto_threads(self):

env = get_fake_env(testdir, self.builddir, self.prefix)
cc = env.detect_c_compiler(MachineChoice.HOST)
if cc.get_id() == 'clang' and is_windows():
raise unittest.SkipTest('LTO not (yet) supported by windows clang')
extra_args: T.List[str] = []
if cc.get_id() == 'clang':
if is_windows():
raise unittest.SkipTest('LTO not (yet) supported by windows clang')
else:
extra_args.append('-D_cargs=-Werror=unused-command-line-argument')

self.init(testdir, extra_args=['-Db_lto=true', '-Db_lto_threads=8'])
self.init(testdir, extra_args=['-Db_lto=true', '-Db_lto_threads=8'] + extra_args)
self.build()
self.run_tests()

Expand All @@ -3091,7 +3095,7 @@ def test_lto_mode(self):
elif is_windows():
raise unittest.SkipTest('LTO not (yet) supported by windows clang')

self.init(testdir, extra_args=['-Db_lto=true', '-Db_lto_mode=thin', '-Db_lto_threads=8'])
self.init(testdir, extra_args=['-Db_lto=true', '-Db_lto_mode=thin', '-Db_lto_threads=8', '-Dc_args=-Werror=unused-command-line-argument'])
self.build()
self.run_tests()

Expand All @@ -3100,7 +3104,7 @@ def test_lto_mode(self):
# This assumes all of the targets support lto
for t in targets:
for s in t['target_sources']:
assert expected.issubset(set(s['parameters'])), f'Incorrect values for {t["name"]}'
self.assertTrue(expected.issubset(set(s['parameters'])), f'Incorrect values for {t["name"]}')

def test_dist_git(self):
if not shutil.which('git'):
Expand Down

0 comments on commit bb0e3dc

Please sign in to comment.