Skip to content

Commit 7f85c83

Browse files
committed
Add --force-output-type option
1 parent 2a43ed5 commit 7f85c83

File tree

2 files changed

+70
-10
lines changed

2 files changed

+70
-10
lines changed

emcc.py

+29-10
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@
5858
JS_CONTAINING_SUFFIXES = ('js', 'html')
5959
EXECUTABLE_SUFFIXES = JS_CONTAINING_SUFFIXES + ('wasm',)
6060

61+
EXPLICIT_OUTPUT_TYPES = ('js', 'html', 'bc')
62+
6163
DEFERRED_REPONSE_FILES = ('EMTERPRETIFY_BLACKLIST', 'EMTERPRETIFY_WHITELIST')
6264

6365
# Mapping of emcc opt levels to llvm opt levels. We use llvm opt level 3 in emcc opt
@@ -165,6 +167,7 @@ def __init__(self):
165167
# Specifies the line ending format to use for all generated text files.
166168
# Defaults to using the native EOL on each platform (\r\n on Windows, \n on Linux&OSX)
167169
self.output_eol = os.linesep
170+
self.force_output_type = None
168171

169172

170173
class JSOptimizer(object):
@@ -542,11 +545,6 @@ def uniquename(name):
542545
target = specified_target if specified_target is not None else 'a.out.js' # specified_target is the user-specified one, target is what we will generate
543546
target_basename = unsuffixed_basename(target)
544547

545-
if '.' in target:
546-
final_suffix = target.split('.')[-1]
547-
else:
548-
final_suffix = ''
549-
550548
if TEMP_DIR:
551549
temp_dir = TEMP_DIR
552550
if os.path.exists(temp_dir):
@@ -777,24 +775,37 @@ def detect_fixed_language_mode(args):
777775

778776
newargs = [arg for arg in newargs if arg is not '']
779777

778+
final_suffix = None
780779
# -c means do not link in gcc, and for us, the parallel is to not go all the way to JS, but stop at bitcode
781780
has_dash_c = '-c' in newargs
782781
if has_dash_c:
783782
assert has_source_inputs or has_header_inputs, 'Must have source code or header inputs to use -c'
784-
target = target_basename + '.o'
783+
if specified_target == None:
784+
target = target_basename + '.o'
785785
final_suffix = 'o'
786786
if '-E' in newargs:
787787
final_suffix = 'eout' # not bitcode, not js; but just result from preprocessing stage of the input file
788788
if '-M' in newargs or '-MM' in newargs:
789789
final_suffix = 'mout' # not bitcode, not js; but just dependency rule of the input file
790+
791+
if final_suffix == None:
792+
if options.force_output_type != None:
793+
final_suffix = options.force_output_type
794+
else:
795+
final_suffix = suffix(target)
796+
if final_suffix == None:
797+
final_suffix = '' # generate bitcode by default
798+
790799
final_ending = ('.' + final_suffix) if len(final_suffix) > 0 else ''
791800

801+
target_unsuffixed = unsuffixed(target)
802+
792803
# target is now finalized, can finalize other _target s
793-
js_target = unsuffixed(target) + '.js'
804+
js_target = target if options.force_output_type == 'js' else target_unsuffixed + '.js'
794805

795-
asm_target = unsuffixed(js_target) + '.asm.js' # might not be used, but if it is, this is the name
796-
wasm_text_target = asm_target.replace('.asm.js', '.wast') # ditto, might not be used
797-
wasm_binary_target = asm_target.replace('.asm.js', '.wasm') # ditto, might not be used
806+
asm_target = target_unsuffixed + '.asm.js' # might not be used, but if it is, this is the name
807+
wasm_text_target = target_unsuffixed + '.wast' # ditto, might not be used
808+
wasm_binary_target = target_unsuffixed + '.wasm' # ditto, might not be used
798809

799810
if final_suffix == 'html' and not options.separate_asm and ('PRECISE_F32=2' in settings_changes or 'USE_PTHREADS=2' in settings_changes):
800811
options.separate_asm = True
@@ -2102,6 +2113,14 @@ def parse_args(newargs):
21022113
exit(1)
21032114
newargs[i] = ''
21042115
newargs[i+1] = ''
2116+
elif newargs[i] == '--force-output-type':
2117+
if newargs[i+1] in EXPLICIT_OUTPUT_TYPES:
2118+
options.force_output_type = newargs[i+1]
2119+
else:
2120+
logging.error('Invalid value "' + newargs[i+1] + '" to --force-output-type')
2121+
exit(1)
2122+
newargs[i] = ''
2123+
newargs[i+1] = ''
21052124

21062125
if should_exit:
21072126
sys.exit(0)

tests/test_other.py

+41
Original file line numberDiff line numberDiff line change
@@ -7890,3 +7890,44 @@ def test_include_system_header_in_c(self):
78907890
print inc
78917891
open('a.c', 'w').write(inc)
78927892
subprocess.check_call([PYTHON, EMCC, 'a.c'])
7893+
7894+
def test_force_output_type(self):
7895+
test_file = os.path.join(self.get_dir(), 'test.cpp')
7896+
fout = open(test_file, 'w')
7897+
fout.write('int main() { return 0; }')
7898+
fout.close()
7899+
7900+
def assert_is_bc(filepath):
7901+
fin = open(filepath, 'rb')
7902+
try:
7903+
magic = fin.read(2)
7904+
finally:
7905+
fin.close()
7906+
assert magic[0] == 'B' and magic[1] == 'C'
7907+
7908+
def assert_is_js(filepath):
7909+
fin = open(filepath, 'r')
7910+
try:
7911+
content = fin.read()
7912+
finally:
7913+
fin.close()
7914+
self.assertContained('function', content)
7915+
7916+
def assert_is_html(filepath):
7917+
fin = open(filepath, 'r')
7918+
try:
7919+
content = fin.read()
7920+
finally:
7921+
fin.close()
7922+
assert content.lstrip().lower().startswith('<!doctype')
7923+
7924+
output_types = [ ('bc', assert_is_bc),
7925+
('js', assert_is_js),
7926+
('html', assert_is_html),
7927+
]
7928+
7929+
for output_type, verifier in output_types:
7930+
for output_suffix in ['', '.o', '.js', '.html', '.somesuffix']:
7931+
output_path = os.path.join(self.get_dir(), 'output' + output_suffix)
7932+
subprocess.check_call([PYTHON, EMCC, '--force-output-type', output_type, test_file, '-o', output_path])
7933+
verifier(output_path)

0 commit comments

Comments
 (0)