Skip to content

Commit 0439ebf

Browse files
committed
Simplify clang vs clang++ selection process when compiling sources
Base the choice solely on whether `emcc` or `em++` was used on the command line. This means that the handling C vs C++ input files will now simply match that of the underlying compiler. When running `clang` there is automatic language selection at the lower level such that that `clang -c file.cc` will run with `-x c++` internally and `clang -c file.c` will run with `-x c` internally. The situation with `clang++` (and now `em++`) is a bit different in that running `clang++` on `.c` input file not automatically use C mode and will generate a warning: ``` clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated] ``` Previously we were hiding the warning but using `clang` internally even if the user ran with `emc++`.
1 parent 75aefcd commit 0439ebf

File tree

5 files changed

+27
-57
lines changed

5 files changed

+27
-57
lines changed

ChangeLog.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ See docs/process.md for more on how version tagging works.
2020

2121
3.1.50 (in development)
2222
-----------------------
23+
- When compiling, Emscripten will now invoke `clang` or `clang++` depending only
24+
on whether `emcc` or `em++` was run. Previously it would determine which to
25+
run based on individual file extensions. One side effect of this is that you
26+
may now see a clang warning when building `.c` source files using `em++`:
27+
`warning: treating 'c' input as 'c++' when in C++ mode`. This also means that
28+
the `DEFAULT_TO_CXX` setting now only applies when linking and not when
29+
compiling. (#20712)
2330

2431
3.1.49 - 11/14/23
2532
-----------------

emcc.py

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,9 +1494,6 @@ def phase_setup(options, state, newargs):
14941494
diagnostics.warning('deprecated', 'RUNTIME_LINKED_LIBS is deprecated; you can simply list the libraries directly on the commandline now')
14951495
newargs += settings.RUNTIME_LINKED_LIBS
14961496

1497-
if settings.STRICT:
1498-
default_setting('DEFAULT_TO_CXX', 0)
1499-
15001497
# Find input files
15011498

15021499
# These three arrays are used to store arguments of different types for
@@ -2067,6 +2064,7 @@ def phase_linker_setup(options, state, newargs):
20672064
if settings.STRICT:
20682065
if not settings.MODULARIZE and not settings.EXPORT_ES6:
20692066
default_setting('STRICT_JS', 1)
2067+
default_setting('DEFAULT_TO_CXX', 0)
20702068
default_setting('AUTO_JS_LIBRARIES', 0)
20712069
default_setting('AUTO_NATIVE_LIBRARIES', 0)
20722070
default_setting('AUTO_ARCHIVE_INDEXES', 0)
@@ -3039,12 +3037,14 @@ def is_link_flag(flag):
30393037
return True
30403038
return flag.startswith(('-l', '-L', '-Wl,'))
30413039

3042-
CXX = [shared.CLANG_CXX]
3043-
CC = [shared.CLANG_CC]
3040+
if run_via_emxx:
3041+
compiler = [shared.CLANG_CXX]
3042+
else:
3043+
compiler = [shared.CLANG_CC]
3044+
30443045
if config.COMPILER_WRAPPER:
30453046
logger.debug('using compiler wrapper: %s', config.COMPILER_WRAPPER)
3046-
CXX.insert(0, config.COMPILER_WRAPPER)
3047-
CC.insert(0, config.COMPILER_WRAPPER)
3047+
compiler.insert(0, config.COMPILER_WRAPPER)
30483048

30493049
compile_args = [a for a in newargs if a and not is_link_flag(a)]
30503050
system_libs.ensure_sysroot()
@@ -3062,39 +3062,16 @@ def get_language_mode(args):
30623062
return ''
30633063

30643064
language_mode = get_language_mode(newargs)
3065-
3066-
def use_cxx(src):
3067-
if 'c++' in language_mode or run_via_emxx:
3068-
return True
3069-
suffix = shared.suffix(src)
3070-
# Next consider the filename
3071-
if suffix in C_ENDINGS + OBJC_ENDINGS:
3072-
return False
3073-
if suffix in CXX_ENDINGS:
3074-
return True
3075-
# Finally fall back to the default
3076-
if settings.DEFAULT_TO_CXX:
3077-
# Default to using C++ even when run as `emcc`.
3078-
# This means that emcc will act as a C++ linker when no source files are
3079-
# specified.
3080-
# This differs to clang and gcc where the default is always C unless run as
3081-
# clang++/g++.
3082-
return True
3083-
return False
3084-
3085-
def get_compiler(src_file):
3086-
if use_cxx(src_file):
3087-
return CXX
3088-
return CC
3065+
use_cxx = 'c++' in language_mode or run_via_emxx
30893066

30903067
def get_clang_command(src_file):
3091-
return get_compiler(src_file) + get_cflags(state.orig_args, use_cxx(src_file)) + compile_args + [src_file]
3068+
return compiler + get_cflags(state.orig_args, use_cxx) + compile_args + [src_file]
30923069

30933070
def get_clang_command_preprocessed(src_file):
3094-
return get_compiler(src_file) + get_clang_flags(state.orig_args) + compile_args + [src_file]
3071+
return compiler + get_clang_flags(state.orig_args) + compile_args + [src_file]
30953072

30963073
def get_clang_command_asm(src_file):
3097-
return get_compiler(src_file) + get_target_flags() + compile_args + [src_file]
3074+
return compiler + get_target_flags() + compile_args + [src_file]
30983075

30993076
# preprocessor-only (-E) support
31003077
if state.mode == Mode.PREPROCESS_ONLY:

src/settings.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,9 +1944,9 @@ var USE_OFFSET_CONVERTER = false;
19441944
var LOAD_SOURCE_MAP = false;
19451945

19461946
// Default to c++ mode even when run as `emcc` rather then `emc++`.
1947-
// When this is disabled `em++` is required when compiling and linking C++
1948-
// programs. This which matches the behaviour of gcc/g++ and clang/clang++.
1949-
// [compile+link]
1947+
// When this is disabled `em++` is required linking C++ programs. Disabling
1948+
// this will match the behaviour of gcc/g++ and clang/clang++.
1949+
// [link]
19501950
var DEFAULT_TO_CXX = true;
19511951

19521952
// While LLVM's wasm32 has long double = float128, we don't support printing

test/test_other.py

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11720,29 +11720,16 @@ def test_default_to_cxx(self):
1172011720
create_file('foo.h', '#include <string.h>')
1172111721
create_file('cxxfoo.h', '#include <string>')
1172211722

11723-
# The default bahviour is to default to C++, which means the C++ header can be compiled even
11724-
# with emcc.
11725-
self.run_process([EMCC, '-c', 'cxxfoo.h'])
11723+
# Compiling a C++ header using `emcc` works.
11724+
self.run_process([EMXX, '-c', 'cxxfoo.h'])
1172611725

11727-
# But this means that C flags can't be passed (since we are assuming C++)
11728-
err = self.expect_fail([EMCC, '-std=gnu11', '-c', 'foo.h'])
11729-
self.assertContained("'-std=gnu11' not allowed with 'C++'", err)
11730-
11731-
# If we disable DEFAULT_TO_CXX the emcc can be used with C-only flags (e.g. -std=gnu11),
11732-
self.run_process([EMCC, '-std=gnu11', '-c', 'foo.h', '-sDEFAULT_TO_CXX=0'])
11733-
11734-
# But can't be used to build C++ headers
11735-
err = self.expect_fail([EMCC, '-c', 'cxxfoo.h', '-sDEFAULT_TO_CXX=0'])
11736-
self.assertContained("'string' file not found", err)
11737-
11738-
# Check that STRICT also disables DEFAULT_TO_CXX
11726+
# Compiling the same header `emcc` fails, just like `clang`
1173911727
err = self.expect_fail([EMCC, '-c', 'cxxfoo.h', '-sSTRICT'])
1174011728
self.assertContained("'string' file not found", err)
1174111729

11742-
# Using em++ should alwasy work for C++ headers
11743-
self.run_process([EMXX, '-c', 'cxxfoo.h', '-sDEFAULT_TO_CXX=0'])
11744-
# Or using emcc with `-x c++`
11745-
self.run_process([EMCC, '-c', 'cxxfoo.h', '-sDEFAULT_TO_CXX=0', '-x', 'c++-header'])
11730+
# But it works if we pass and explicit language mode.
11731+
self.run_process([EMCC, '-c', 'cxxfoo.h', '-x', 'c++-header'])
11732+
self.run_process([EMCC, '-c', 'cxxfoo.h', '-x', 'c++'])
1174611733

1174711734
@parameterized({
1174811735
'': ([],),

tools/settings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@
7070
'USE_PTHREADS', # legacy name of PTHREADS setting
7171
'SHARED_MEMORY',
7272
'SUPPORT_LONGJMP',
73-
'DEFAULT_TO_CXX',
7473
'WASM_OBJECT_FILES',
7574
'WASM_WORKERS',
7675
'BULK_MEMORY',

0 commit comments

Comments
 (0)