support precompiled headers; fixes #2045
This commit is contained in:
Родитель
a7c5795f32
Коммит
a5243b4365
34
emcc
34
emcc
|
@ -61,6 +61,7 @@ BITCODE_ENDINGS = ('.bc', '.o', '.obj')
|
|||
DYNAMICLIB_ENDINGS = ('.dylib', '.so', '.dll')
|
||||
STATICLIB_ENDINGS = ('.a',)
|
||||
ASSEMBLY_ENDINGS = ('.ll',)
|
||||
HEADER_ENDINGS = ('.h', '.hxx', '.hpp', '.hh', '.H', '.HXX', '.HPP', '.HH')
|
||||
|
||||
LIB_PREFIXES = ('', 'lib')
|
||||
|
||||
|
@ -695,15 +696,12 @@ if len(sys.argv) == 1 or sys.argv[1] in ['x', 't']:
|
|||
sys.exit(0)
|
||||
|
||||
use_cxx = True
|
||||
header = False # pre-compiled headers. We fake that by just copying the file
|
||||
|
||||
for i in range(1, len(sys.argv)):
|
||||
arg = sys.argv[i]
|
||||
if not arg.startswith('-'):
|
||||
if arg.endswith(('.c','.m')):
|
||||
use_cxx = False
|
||||
if arg.endswith('.h') and sys.argv[i-1] != '-include':
|
||||
header = True
|
||||
|
||||
if '-M' in sys.argv or '-MM' in sys.argv:
|
||||
# Just output dependencies, do not compile. Warning: clang and gcc behave differently with -MF! (clang seems to not recognize it)
|
||||
|
@ -737,15 +735,6 @@ if '.' in target:
|
|||
else:
|
||||
final_suffix = ''
|
||||
|
||||
if header: # header or such
|
||||
if len(sys.argv) >= 3: # if there is a source and a target, then copy, otherwise do nothing
|
||||
sys.argv = filter(lambda arg: not arg.startswith('-I'), sys.argv)
|
||||
logging.debug('Just copy:' + sys.argv[-1] + target)
|
||||
shutil.copy(sys.argv[-1], target)
|
||||
else:
|
||||
logging.debug('No-op.')
|
||||
exit(0)
|
||||
|
||||
if TEMP_DIR:
|
||||
temp_dir = TEMP_DIR
|
||||
if os.path.exists(temp_dir):
|
||||
|
@ -1062,6 +1051,7 @@ try:
|
|||
|
||||
input_files = []
|
||||
has_source_inputs = False
|
||||
has_header_inputs = False
|
||||
lib_dirs = [shared.path_from_root('system', 'local', 'lib'),
|
||||
shared.path_from_root('system', 'lib')]
|
||||
libs = []
|
||||
|
@ -1073,7 +1063,7 @@ try:
|
|||
prev = newargs[i-1]
|
||||
if prev in ['-MT', '-MF', '-MQ', '-D', '-U', '-o', '-x', '-Xpreprocessor', '-include', '-imacros', '-idirafter', '-iprefix', '-iwithprefix', '-iwithprefixbefore', '-isysroot', '-imultilib', '-A', '-isystem', '-iquote', '-install_name', '-compatibility_version', '-current_version', '-I', '-L']: continue # ignore this gcc-style argument
|
||||
|
||||
if (os.path.islink(arg) and os.path.realpath(arg).endswith(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS)):
|
||||
if (os.path.islink(arg) and os.path.realpath(arg).endswith(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS)):
|
||||
arg = os.path.realpath(arg)
|
||||
|
||||
if not arg.startswith('-'):
|
||||
|
@ -1082,11 +1072,14 @@ try:
|
|||
exit(1)
|
||||
|
||||
arg_ending = filename_type_ending(arg)
|
||||
if arg_ending.endswith(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS) or shared.Building.is_ar(arg): # we already removed -o <target>, so all these should be inputs
|
||||
if arg_ending.endswith(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS) or shared.Building.is_ar(arg): # we already removed -o <target>, so all these should be inputs
|
||||
newargs[i] = ''
|
||||
if arg_ending.endswith(SOURCE_ENDINGS):
|
||||
input_files.append(arg)
|
||||
has_source_inputs = True
|
||||
elif arg_ending.endswith(HEADER_ENDINGS):
|
||||
input_files.append(arg)
|
||||
has_header_inputs = True
|
||||
elif arg_ending.endswith(ASSEMBLY_ENDINGS) or shared.Building.is_bitcode(arg): # this should be bitcode, make sure it is valid
|
||||
input_files.append(arg)
|
||||
elif arg_ending.endswith(STATICLIB_ENDINGS + DYNAMICLIB_ENDINGS):
|
||||
|
@ -1125,7 +1118,7 @@ try:
|
|||
# -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
|
||||
has_dash_c = '-c' in newargs
|
||||
if has_dash_c:
|
||||
assert has_source_inputs, 'Must have source code inputs to use -c'
|
||||
assert has_source_inputs or has_header_inputs, 'Must have source code or header inputs to use -c'
|
||||
target = target_basename + '.o'
|
||||
final_suffix = 'o'
|
||||
|
||||
|
@ -1159,7 +1152,7 @@ try:
|
|||
input_files = filter(lambda input_file: check(input_file), input_files)
|
||||
|
||||
if len(input_files) == 0:
|
||||
logging.error('no input files\nnote that input files without a known suffix are ignored, make sure your input files end with one of: ' + str(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + STATICLIB_ENDINGS + ASSEMBLY_ENDINGS))
|
||||
logging.error('no input files\nnote that input files without a known suffix are ignored, make sure your input files end with one of: ' + str(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + STATICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS))
|
||||
exit(0)
|
||||
|
||||
newargs = CC_ADDITIONAL_ARGS + newargs
|
||||
|
@ -1299,6 +1292,15 @@ try:
|
|||
|
||||
log_time('parse arguments and setup')
|
||||
|
||||
# Precompiled headers support
|
||||
if has_header_inputs:
|
||||
for header in input_files:
|
||||
assert header.endswith(HEADER_ENDINGS), 'if you have one header input, we assume you want to precompile headers, and cannot have source files or other inputs as well: ' + str(input_files) + ' : ' + header
|
||||
args = newargs + shared.EMSDK_CXX_OPTS + input_files
|
||||
logging.debug("running (for precompiled headers: " + call + ' ' + ' '.join(args))
|
||||
execute([call] + args) # let compiler frontend print directly, so colors are saved (PIPE kills that)
|
||||
sys.exit(1)
|
||||
|
||||
# First, generate LLVM bitcode. For each input file, we get base.o with bitcode
|
||||
for input_file in input_files:
|
||||
file_ending = filename_type_ending(input_file)
|
||||
|
|
|
@ -2324,3 +2324,22 @@ var Module = { print: function(x) { throw '<{(' + x + ')}>' } };
|
|||
output = run_js(os.path.join(self.get_dir(), 'a.out.js'), stderr=PIPE, full_output=True, engine=NODE_JS)
|
||||
assert r'<{(123456789)}>' in output, output
|
||||
|
||||
def test_precompiled_headers(self):
|
||||
self.clear()
|
||||
|
||||
open('header.h', 'w').write('#define X 5\n')
|
||||
Popen([PYTHON, EMCC, '-xc++-header', 'header.h', '-c']).communicate()
|
||||
assert os.path.exists('header.h.gch')
|
||||
|
||||
open('src.cpp', 'w').write(r'''
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
printf("|%d|\n", X);
|
||||
return 0;
|
||||
}
|
||||
''')
|
||||
Popen([PYTHON, EMCC, 'src.cpp', '-include', 'header.h']).communicate()
|
||||
|
||||
output = run_js(self.in_dir('a.out.js'), stderr=PIPE, full_output=True, engine=NODE_JS)
|
||||
assert '|5|' in output, output
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче