Merge pull request #1605 from juj/mingw32make_nmake_cmake
Mingw32make nmake cmake
This commit is contained in:
Коммит
ea729bea8c
|
@ -275,71 +275,77 @@ f.close()
|
|||
# TODO: deprecate llvm optimizations, dlmalloc, etc. in emscripten.py.
|
||||
|
||||
def test_cmake(self):
|
||||
# On Windows, we want to build cmake-generated Makefiles with mingw32-make instead of e.g. cygwin make, since mingw32-make
|
||||
# understands Windows paths, and cygwin make additionally produces a cryptic 'not valid bitcode file' errors on files that
|
||||
# *are* valid bitcode files.
|
||||
# Test all supported generators.
|
||||
if WINDOWS:
|
||||
generators = ['MinGW Makefiles', 'NMake Makefiles']
|
||||
else:
|
||||
generators = ['Unix Makefiles']
|
||||
|
||||
make_commands = { 'MinGW Makefiles': ['mingw32-make'], 'NMake Makefiles': ['nmake', '/NOLOGO'], 'Unix Makefiles': ['make'] }
|
||||
|
||||
if os.name == 'nt':
|
||||
make_command = 'mingw32-make'
|
||||
generator = 'MinGW Makefiles'
|
||||
emconfigure = path_from_root('emconfigure.bat')
|
||||
else:
|
||||
make_command = 'make'
|
||||
generator = 'Unix Makefiles'
|
||||
emconfigure = path_from_root('emconfigure')
|
||||
|
||||
cmake_cases = ['target_js', 'target_html']
|
||||
cmake_outputs = ['hello_world.js', 'hello_world_gles.html']
|
||||
for i in range(0, 2): # Test both JS and HTML build outputs from CMake.
|
||||
for configuration in ['Debug', 'Release']:
|
||||
# CMake can be invoked in two ways, using 'emconfigure cmake', or by directly running 'cmake'.
|
||||
# Test both methods.
|
||||
for invoke_method in ['cmake', 'emconfigure']:
|
||||
for generator in generators:
|
||||
if generator == 'NMake Makefiles' and not Building.which('nmake'):
|
||||
print >> sys.stderr, 'Skipping NMake test for CMake support, since nmake was not found in PATH. Run this test in Visual Studio command prompt to easily access nmake.'
|
||||
continue
|
||||
|
||||
# Create a temp workspace folder
|
||||
cmakelistsdir = path_from_root('tests', 'cmake', cmake_cases[i])
|
||||
tempdirname = tempfile.mkdtemp(prefix='emscripten_test_' + self.__class__.__name__ + '_', dir=TEMP_DIR)
|
||||
try:
|
||||
os.chdir(tempdirname)
|
||||
make = make_commands[generator]
|
||||
cmake_cases = ['target_js', 'target_html']
|
||||
cmake_outputs = ['hello_world.js', 'hello_world_gles.html']
|
||||
for i in range(0, 2):
|
||||
for configuration in ['Debug', 'Release']:
|
||||
# CMake can be invoked in two ways, using 'emconfigure cmake', or by directly running 'cmake'.
|
||||
# Test both methods.
|
||||
for invoke_method in ['cmake', 'emconfigure']:
|
||||
|
||||
verbose_level = int(os.getenv('EM_BUILD_VERBOSE')) if os.getenv('EM_BUILD_VERBOSE') != None else 0
|
||||
|
||||
# Run Cmake
|
||||
if invoke_method == 'cmake':
|
||||
# Test invoking cmake directly.
|
||||
cmd = ['cmake', '-DCMAKE_TOOLCHAIN_FILE='+path_from_root('cmake', 'Platform', 'Emscripten.cmake'),
|
||||
'-DCMAKE_BUILD_TYPE=' + configuration, '-G', generator, cmakelistsdir]
|
||||
else:
|
||||
# Test invoking via 'emconfigure cmake'
|
||||
cmd = [emconfigure, 'cmake', '-DCMAKE_BUILD_TYPE=' + configuration, '-G', generator, cmakelistsdir]
|
||||
# Create a temp workspace folder
|
||||
cmakelistsdir = path_from_root('tests', 'cmake', cmake_cases[i])
|
||||
tempdirname = tempfile.mkdtemp(prefix='emscripten_test_' + self.__class__.__name__ + '_', dir=TEMP_DIR)
|
||||
try:
|
||||
os.chdir(tempdirname)
|
||||
|
||||
ret = Popen(cmd, stdout=None if verbose_level >= 2 else PIPE, stderr=None if verbose_level >= 1 else PIPE).communicate()
|
||||
if len(ret) > 1 and ret[1] != None and len(ret[1].strip()) > 0:
|
||||
logging.error(ret[1]) # If there were any errors, print them directly to console for diagnostics.
|
||||
if len(ret) > 1 and ret[1] != None and 'error' in ret[1].lower():
|
||||
logging.error('Failed command: ' + ' '.join(cmd))
|
||||
logging.error('Result:\n' + ret[1])
|
||||
raise Exception('cmake call failed!')
|
||||
assert os.path.exists(tempdirname + '/Makefile'), 'CMake call did not produce a Makefile!'
|
||||
verbose_level = int(os.getenv('EM_BUILD_VERBOSE')) if os.getenv('EM_BUILD_VERBOSE') != None else 0
|
||||
|
||||
# Run Cmake
|
||||
if invoke_method == 'cmake':
|
||||
# Test invoking cmake directly.
|
||||
cmd = ['cmake', '-DCMAKE_TOOLCHAIN_FILE='+path_from_root('cmake', 'Platform', 'Emscripten.cmake'),
|
||||
'-DCMAKE_BUILD_TYPE=' + configuration, '-G', generator, cmakelistsdir]
|
||||
else:
|
||||
# Test invoking via 'emconfigure cmake'
|
||||
cmd = [emconfigure, 'cmake', '-DCMAKE_BUILD_TYPE=' + configuration, '-G', generator, cmakelistsdir]
|
||||
|
||||
# Build
|
||||
cmd = [make_command] + (['VERBOSE=1'] if verbose_level >= 3 else [])
|
||||
ret = Popen(cmd, stdout=None if verbose_level >= 2 else PIPE).communicate()
|
||||
if len(ret) > 1 and ret[1] != None and len(ret[1].strip()) > 0:
|
||||
logging.error(ret[1]) # If there were any errors, print them directly to console for diagnostics.
|
||||
if len(ret) > 0 and ret[0] != None and 'error' in ret[0].lower() and not '0 error(s)' in ret[0].lower():
|
||||
logging.error('Failed command: ' + ' '.join(cmd))
|
||||
logging.error('Result:\n' + ret[0])
|
||||
raise Exception('make failed!')
|
||||
assert os.path.exists(tempdirname + '/' + cmake_outputs[i]), 'Building a cmake-generated Makefile failed to produce an output file %s!' % tempdirname + '/' + cmake_outputs[i]
|
||||
ret = Popen(cmd, stdout=None if verbose_level >= 2 else PIPE, stderr=None if verbose_level >= 1 else PIPE).communicate()
|
||||
if len(ret) > 1 and ret[1] != None and len(ret[1].strip()) > 0:
|
||||
logging.error(ret[1]) # If there were any errors, print them directly to console for diagnostics.
|
||||
if len(ret) > 1 and ret[1] != None and 'error' in ret[1].lower():
|
||||
logging.error('Failed command: ' + ' '.join(cmd))
|
||||
logging.error('Result:\n' + ret[1])
|
||||
raise Exception('cmake call failed!')
|
||||
assert os.path.exists(tempdirname + '/Makefile'), 'CMake call did not produce a Makefile!'
|
||||
|
||||
# Run through node, if CMake produced a .js file.
|
||||
if cmake_outputs[i].endswith('.js'):
|
||||
ret = Popen(listify(NODE_JS) + [tempdirname + '/' + cmake_outputs[i]], stdout=PIPE).communicate()[0]
|
||||
assert 'hello, world!' in ret, 'Running cmake-based .js application failed!'
|
||||
finally:
|
||||
os.chdir(path_from_root('tests')) # Move away from the directory we are about to remove.
|
||||
shutil.rmtree(tempdirname)
|
||||
# Build
|
||||
cmd = make + (['VERBOSE=1'] if verbose_level >= 3 else [])
|
||||
ret = Popen(cmd, stdout=None if verbose_level >= 2 else PIPE).communicate()
|
||||
if len(ret) > 1 and ret[1] != None and len(ret[1].strip()) > 0:
|
||||
logging.error(ret[1]) # If there were any errors, print them directly to console for diagnostics.
|
||||
if len(ret) > 0 and ret[0] != None and 'error' in ret[0].lower() and not '0 error(s)' in ret[0].lower():
|
||||
logging.error('Failed command: ' + ' '.join(cmd))
|
||||
logging.error('Result:\n' + ret[0])
|
||||
raise Exception('make failed!')
|
||||
assert os.path.exists(tempdirname + '/' + cmake_outputs[i]), 'Building a cmake-generated Makefile failed to produce an output file %s!' % tempdirname + '/' + cmake_outputs[i]
|
||||
|
||||
# Run through node, if CMake produced a .js file.
|
||||
if cmake_outputs[i].endswith('.js'):
|
||||
ret = Popen(listify(NODE_JS) + [tempdirname + '/' + cmake_outputs[i]], stdout=PIPE).communicate()[0]
|
||||
assert 'hello, world!' in ret, 'Running cmake-based .js application failed!'
|
||||
finally:
|
||||
os.chdir(path_from_root('tests')) # Move away from the directory we are about to remove.
|
||||
shutil.rmtree(tempdirname)
|
||||
|
||||
def test_failure_error_code(self):
|
||||
for compiler in [EMCC, EMXX]:
|
||||
|
|
|
@ -820,14 +820,52 @@ class Building:
|
|||
env['EMSCRIPTEN'] = path_from_root()
|
||||
return env
|
||||
|
||||
# Finds the given executable 'program' in PATH. Operates like the Unix tool 'which'.
|
||||
@staticmethod
|
||||
def which(program):
|
||||
import os
|
||||
def is_exe(fpath):
|
||||
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
|
||||
|
||||
fpath, fname = os.path.split(program)
|
||||
if fpath:
|
||||
if is_exe(program):
|
||||
return program
|
||||
else:
|
||||
for path in os.environ["PATH"].split(os.pathsep):
|
||||
path = path.strip('"')
|
||||
exe_file = os.path.join(path, program)
|
||||
if is_exe(exe_file):
|
||||
return exe_file
|
||||
|
||||
if WINDOWS and not '.' in fname:
|
||||
if is_exe(exe_file + '.exe'):
|
||||
return exe_file + '.exe'
|
||||
if is_exe(exe_file + '.cmd'):
|
||||
return exe_file + '.cmd'
|
||||
if is_exe(exe_file + '.bat'):
|
||||
return exe_file + '.bat'
|
||||
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def handle_CMake_toolchain(args, env):
|
||||
# Don't append a toolchain file if the user specified one already.
|
||||
for arg in args:
|
||||
if '-DCMAKE_TOOLCHAIN_FILE' in arg:
|
||||
return args
|
||||
|
||||
args.append('-DCMAKE_TOOLCHAIN_FILE=' + path_from_root('cmake', 'Platform', 'Emscripten.cmake'))
|
||||
def has_substr(array, substr):
|
||||
for arg in array:
|
||||
if substr in arg:
|
||||
return True
|
||||
return False
|
||||
|
||||
# Append the Emscripten toolchain file if the user didn't specify one.
|
||||
if not has_substr(args, '-DCMAKE_TOOLCHAIN_FILE'):
|
||||
args.append('-DCMAKE_TOOLCHAIN_FILE=' + path_from_root('cmake', 'Platform', 'Emscripten.cmake'))
|
||||
|
||||
# On Windows specify MinGW Makefiles if we have MinGW and no other toolchain was specified, to avoid CMake
|
||||
# pulling in a native Visual Studio, or Unix Makefiles.
|
||||
if WINDOWS and not '-G' in args and Building.which('mingw32-make'):
|
||||
args += ['-G', 'MinGW Makefiles']
|
||||
|
||||
return args
|
||||
|
||||
@staticmethod
|
||||
|
@ -858,6 +896,13 @@ class Building:
|
|||
logging.error('Executable to run not specified.')
|
||||
sys.exit(1)
|
||||
#args += ['VERBOSE=1']
|
||||
|
||||
# On Windows prefer building with mingw32-make instead of make, if it exists.
|
||||
if WINDOWS and args[0] == 'make':
|
||||
mingw32_make = Building.which('mingw32-make')
|
||||
if mingw32_make:
|
||||
args[0] = mingw32_make
|
||||
|
||||
try:
|
||||
process = Popen(args, stdout=stdout, stderr=stderr, env=env)
|
||||
process.communicate()
|
||||
|
|
Загрузка…
Ссылка в новой задаче