Compare commits

...

26 Commits

Author SHA1 Message Date
Danny McClanahan
0af9331015 fix zlib and bzip2 2022-04-28 00:42:33 -04:00
Danny McClanahan
da423cdbac fix npm docstring 2022-04-24 16:58:33 -04:00
Danny McClanahan
fe0323f7a3 default -Wl,--allow-multiple-definition to on 2022-04-23 15:32:40 -04:00
Danny McClanahan
0c3d3afb01 subjective change -- prefer ninja over unix makefiles in cmake 2022-04-23 14:44:46 -04:00
Danny McClanahan
f4b094834a make ffmpeg build with emscripten!!!!!! 2022-04-23 14:44:45 -04:00
Danny McClanahan
2170120f40 fix emscripten and llvm to be able to produce runnable binaries
fix binaryen for emscripten
2022-04-23 14:44:45 -04:00
Danny McClanahan
58a71a5307 yasm bootstrap is no longer necessary 2022-04-23 14:44:45 -04:00
Danny McClanahan
203cebb081 make zlib and other makefile packages able to use emscripten
- also, bzip2 fix
2022-04-23 14:44:37 -04:00
Danny McClanahan
13362f6c86 make emscripten test work 2022-04-23 03:56:14 -04:00
Danny McClanahan
29dbae0c20 add emscripten package 2022-04-23 03:29:54 -04:00
Danny McClanahan
4f2b9ca6dc add several new variants to llvm to make it build on alpine 2022-04-23 03:29:54 -04:00
Danny McClanahan
bf50833d58 add note about python version necessary to install node-js 2022-04-23 03:29:54 -04:00
Danny McClanahan
5adf17f8a3 add binaryen package 2022-04-23 03:29:54 -04:00
Danny McClanahan
856dee5b0a add very hacky compatibility layer for npm on alpine 2022-04-23 03:29:53 -04:00
Danny McClanahan
9baf586a2e fix python2 build dep for node-js 2022-04-23 03:29:53 -04:00
Danny McClanahan
d38310fa02 not working -- look at nix emscripten support first before further work 2022-04-23 03:29:53 -04:00
Danny McClanahan
cc87de83cd make emconfigure and emcmake work, kinda 2022-04-23 03:29:53 -04:00
Danny McClanahan
187c0f1d04 fix doc issue with executables regex 2022-04-23 03:29:53 -04:00
Danny McClanahan
1a0b11ca43 random unrelated change 2022-04-23 03:29:53 -04:00
Danny McClanahan
982f883bcc rename emcc to emscripten 2022-04-23 03:29:52 -04:00
Danny McClanahan
2487a75422 implement spack external find for node-js 2022-04-23 03:29:52 -04:00
Danny McClanahan
b9bedba68c make emsdk use spack's node and llvm instead of downloading its own 2022-04-23 03:29:52 -04:00
Danny McClanahan
620575f505 add emscripten compiler emcc, which can't compile executables (yet!) 2022-04-23 03:29:52 -04:00
Danny McClanahan
43eaa713a3 add emsdk package 2022-04-23 03:29:52 -04:00
Danny McClanahan
e4f602632c add gnu plotutils 2022-04-23 03:27:53 -04:00
Danny McClanahan
5fe1a036a0 fix gsl build with openblas 2022-04-23 03:27:53 -04:00
36 changed files with 3140 additions and 35 deletions

View File

@@ -5323,7 +5323,7 @@ would be quite complicated to do using regex only. Employing the
.. code-block:: python
class Gcc(Package):
executables = ['g++']
executables = [r'g\+\+']
def filter_detected_exes(cls, prefix, exes_in_prefix):
return [x for x in exes_in_prefix if 'clang' not in x]

4
lib/spack/env/cc vendored
View File

@@ -241,14 +241,14 @@ case "$command" in
mode=cpp
debug_flags="-g"
;;
cc|c89|c99|gcc|clang|armclang|icc|icx|pgcc|nvc|xlc|xlc_r|fcc|amdclang|cl.exe)
cc|c89|c99|gcc|clang|armclang|icc|icx|pgcc|nvc|xlc|xlc_r|fcc|amdclang|cl.exe|emcc)
command="$SPACK_CC"
language="C"
comp="CC"
lang_flags=C
debug_flags="-g"
;;
c++|CC|g++|clang++|armclang++|icpc|icpx|dpcpp|pgc++|nvc++|xlc++|xlc++_r|FCC|amdclang++)
c++|CC|g++|clang++|armclang++|icpc|icpx|dpcpp|pgc++|nvc++|xlc++|xlc++_r|FCC|amdclang++|em++)
command="$SPACK_CXX"
language="C++"
comp="CXX"

1
lib/spack/env/emscripten/em++ vendored Symbolic link
View File

@@ -0,0 +1 @@
../cc

1
lib/spack/env/emscripten/emcc vendored Symbolic link
View File

@@ -0,0 +1 @@
../cc

View File

@@ -512,7 +512,14 @@ def _set_variables_for_single_module(pkg, module):
m.make_jobs = jobs
# TODO: make these build deps that can be installed if not found.
# FIXME: !!!!!
m.make = MakeExecutable('make', jobs)
m.emmake = MakeExecutable('emmake', jobs)
m.emmake.add_default_arg('make')
m.emmake.add_default_arg('AR=emar')
m.emmake.add_default_arg('RANLIB=emranlib')
m.emmake.add_default_arg('NM=emnm')
m.gmake = MakeExecutable('gmake', jobs)
m.scons = MakeExecutable('scons', jobs)
m.ninja = MakeExecutable('ninja', jobs)
@@ -523,9 +530,15 @@ def _set_variables_for_single_module(pkg, module):
# Find the configure script in the archive path
# Don't use which for this; we want to find it in the current dir.
m.configure = Executable('./configure')
m.emconfigure = Executable('emconfigure')
m.emconfigure.add_default_arg('./configure')
m.meson = Executable('meson')
m.cmake = Executable('cmake')
m.emcmake = Executable('emcmake')
m.emcmake.add_default_arg('cmake')
m.ctest = MakeExecutable('ctest', jobs)
if sys.platform == 'win32':

View File

@@ -419,7 +419,10 @@ def configure(self, spec, prefix):
options += self.configure_args()
with working_dir(self.build_directory, create=True):
inspect.getmodule(self).configure(*options)
if self.spec.satisfies('%emscripten'):
inspect.getmodule(self).emconfigure(*options)
else:
inspect.getmodule(self).configure(*options)
def setup_build_environment(self, env):
if (self.spec.platform == 'darwin'

View File

@@ -94,11 +94,13 @@ class CMakePackage(PackageBase):
#: See https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html
#: for more information.
generator = "Unix Makefiles"
# generator = "Unix Makefiles"
generator = "Ninja"
depends_on('ninja', type='build')
if sys.platform == 'win32':
generator = "Ninja"
depends_on('ninja')
depends_on('ninja', type='build')
# https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html
variant('build_type', default='RelWithDebInfo',
@@ -374,7 +376,10 @@ def cmake(self, spec, prefix):
options += self.cmake_args()
options.append(os.path.abspath(self.root_cmakelists_dir))
with working_dir(self.build_directory, create=True):
inspect.getmodule(self).cmake(*options)
if self.spec.satisfies('%emscripten'):
inspect.getmodule(self).emcmake(*options)
else:
inspect.getmodule(self).cmake(*options)
def build(self, spec, prefix):
"""Make the build targets"""

View File

@@ -82,14 +82,20 @@ def build(self, spec, prefix):
as targets.
"""
with working_dir(self.build_directory):
inspect.getmodule(self).make(*self.build_targets)
if self.spec.satisfies('%emscripten'):
inspect.getmodule(self).emmake(*self.build_targets)
else:
inspect.getmodule(self).make(*self.build_targets)
def install(self, spec, prefix):
"""Calls make, passing :py:attr:`~.MakefilePackage.install_targets`
as targets.
"""
with working_dir(self.build_directory):
inspect.getmodule(self).make(*self.install_targets)
if self.spec.satisfies('%emscripten'):
inspect.getmodule(self).emmake(*self.install_targets)
else:
inspect.getmodule(self).make(*self.install_targets)
run_after('build')(PackageBase._run_default_build_time_test_callbacks)

View File

@@ -0,0 +1,37 @@
# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import re
from spack.compiler import Compiler
from spack.version import ver
class Emscripten(Compiler):
cc_names = ['emcc']
cxx_names = ['em++']
# Named wrapper links within build_env_path
link_paths = {'cc': os.path.join('emscripten', 'emcc'),
'cxx': os.path.join('emscripten', 'em++'),
'f77': '',
'fc': ''}
@property
def verbose_flag(self):
return "-v"
@property
def debug_flags(self):
return ['-g', '-gsource-map', '-gseparate-dwarf', '-g0', '-g1', '-g2', '-g3']
@property
def opt_flags(self):
return ['-O0', '-O1', '-O2', '-O3', '-Os', '-Oz']
@property
def disable_new_dtags(self):
return ''

View File

@@ -247,6 +247,12 @@ def by_executable(packages_to_check, path_hints=None):
continue
for prefix, exes_in_prefix in sorted(_group_by_prefix(exes)):
pkg_prefix = executable_prefix(prefix)
if not pkg_prefix:
msg = "no bin/ dir found in {0}. Cannot add it as a Spack package"
llnl.util.tty.debug(msg.format(prefix))
continue
# TODO: multiple instances of a package can live in the same
# prefix, and a package implementation can return multiple specs
# for one prefix, but without additional details (e.g. about the
@@ -270,13 +276,6 @@ def by_executable(packages_to_check, path_hints=None):
)
for spec in specs:
pkg_prefix = executable_prefix(prefix)
if not pkg_prefix:
msg = "no bin/ dir found in {0}. Cannot add it as a Spack package"
llnl.util.tty.debug(msg.format(prefix))
continue
if spec in resolved_specs:
prior_prefix = ', '.join(
_convert_to_iterable(resolved_specs[spec]))

View File

@@ -1775,7 +1775,10 @@ def _if_make_target_execute(self, target, *args, **kwargs):
"""
if self._has_make_target(target):
# Execute target
inspect.getmodule(self).make(target, *args, **kwargs)
if self.spec.satisfies('%emscripten'):
inspect.getmodule(self).emmake(target, *args, **kwargs)
else:
inspect.getmodule(self).make(target, *args, **kwargs)
def _has_ninja_target(self, target):
"""Checks to see if 'target' is a valid target in a Ninja build script.

View File

@@ -21,6 +21,8 @@ class AlsaLib(AutotoolsPackage):
variant('python', default=False, description='enable python')
patch('python.patch', when='@1.1.4:1.1.5 +python')
# Remove a type that only exists in the kernel.
patch('s64.patch')
depends_on('python', type=('link', 'run'), when='+python')

View File

@@ -0,0 +1,12 @@
diff --git a/include/alsa/sound/uapi/asound.h b/include/alsa/sound/uapi/asound.h
index ec610c2..5f9724b 100644
--- a/include/alsa/sound/uapi/asound.h
+++ b/include/alsa/sound/uapi/asound.h2
@@ -30,6 +30,7 @@
#else
#include <endian.h>
#include <sys/ioctl.h>
#endif
+typedef int64_t __s64;
#include <stdlib.h>

View File

@@ -0,0 +1,48 @@
# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import re
import sys
from spack import *
class Binaryen(CMakePackage):
"""Compiler infrastructure and toolchain library for WebAssembly"""
homepage = "https://github.com/WebAssembly/binaryen"
git = "https://github.com/WebAssembly/binaryen.git"
url = "https://github.com/WebAssembly/binaryen/archive/refs/tags/version_101.tar.gz"
version('101', sha256='5d7cdec89957549f01b7c93f080d08827c87bbd4789a34694c740d15d077c041')
executables = ('^{}$'.format(re.escape(exe)) for exe in [
'wasm-opt',
'wasm-as',
'wasm-dis',
'wasm2js',
'wasm-reduce',
'wasm-shell',
'wasm-emscripten-finalize',
'wasm-ctor-eval',
'binaryen.js',
])
@classmethod
def determine_version(cls, exe_path):
try:
exe = Executable(exe_path)
output = exe('--version', output=str, error=str)
pattern = r'^{} version ([0-9]+)$'.format(re.escape(os.path.basename(exe_path)))
m = re.match(pattern, output)
if m is None:
return None
(v,) = m.groups()
return Version(v)
except spack.util.executable.ProcessError:
pass
return None

View File

@@ -0,0 +1,67 @@
diff --git a/bzip2.c b/bzip2.c
index d95d280..30429ea 100644
--- a/bzip2.c
+++ b/bzip2.c
@@ -1227,30 +1227,11 @@ void compress ( Char *name )
case SM_I2O:
inStr = stdin;
outStr = stdout;
- if ( isatty ( fileno ( stdout ) ) ) {
- fprintf ( stderr,
- "%s: I won't write compressed data to a terminal.\n",
- progName );
- fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
- progName, progName );
- setExit(1);
- return;
- };
break;
case SM_F2O:
inStr = fopen ( inName, "rb" );
outStr = stdout;
- if ( isatty ( fileno ( stdout ) ) ) {
- fprintf ( stderr,
- "%s: I won't write compressed data to a terminal.\n",
- progName );
- fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
- progName, progName );
- if ( inStr != NULL ) fclose ( inStr );
- setExit(1);
- return;
- };
if ( inStr == NULL ) {
fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
progName, inName, strerror(errno) );
@@ -1413,15 +1394,6 @@ void uncompress ( Char *name )
case SM_I2O:
inStr = stdin;
outStr = stdout;
- if ( isatty ( fileno ( stdin ) ) ) {
- fprintf ( stderr,
- "%s: I won't read compressed data from a terminal.\n",
- progName );
- fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
- progName, progName );
- setExit(1);
- return;
- };
break;
case SM_F2O:
@@ -1554,15 +1526,6 @@ void testf ( Char *name )
switch ( srcMode ) {
case SM_I2O:
- if ( isatty ( fileno ( stdin ) ) ) {
- fprintf ( stderr,
- "%s: I won't read compressed data from a terminal.\n",
- progName );
- fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
- progName, progName );
- setExit(1);
- return;
- };
inStr = stdin;
break;

View File

@@ -28,6 +28,8 @@ class Bzip2(Package, SourcewarePackage):
variant('pic', default=False, description='Build static libraries with PIC')
variant('debug', default=False, description='Enable debug symbols and disable optimization')
patch('no-tty-checking.patch', when='%emscripten')
depends_on('diffutils', type='build')
@classmethod
@@ -99,13 +101,28 @@ def patch(self):
**kwargs)
def install(self, spec, prefix):
def do_make(*args):
if self.spec.satisfies('%emscripten'):
emmake(*args)
else:
make(*args)
# Build the dynamic library first
if '+shared' in spec:
make('-f', 'Makefile-libbz2_so')
do_make('-f', 'Makefile-libbz2_so')
# Build the static library and everything else
make()
make('install', 'PREFIX={0}'.format(prefix))
do_make()
do_make('install', 'PREFIX={0}'.format(prefix))
if self.spec.satisfies('%emscripten'):
install('bzip2.wasm',
join_path(prefix.bin, 'bzip2.wasm'))
install('bzip2recover.wasm',
join_path(prefix.bin, 'bzip2recover.wasm'))
if '+shared' in spec:
install('bzip2-shared.wasm',
join_path(prefix.bin, 'bzip2-shared.wasm'))
if '+shared' in spec:
install('bzip2-shared', join_path(prefix.bin, 'bzip2'))

View File

@@ -0,0 +1,13 @@
diff --git a/emcc.py b/emcc.py
index d378fcca8..53286d9fb 100755
--- a/emcc.py
+++ b/emcc.py
@@ -2787,6 +2787,8 @@ def phase_final_emitting(options, state, target, wasm_target, memfile):
for f in generated_text_files_with_native_eols:
tools.line_endings.convert_line_endings_in_file(f, os.linesep, options.output_eol)
+ if shared.suffix(target) not in ['.js', '.wasm', '.o']:
+ options.executable = True
if options.executable:
make_js_executable(js_target)

View File

@@ -0,0 +1,22 @@
diff --git a/src/settings.js b/src/settings.js
index 265c13a47..94cf2e744 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -876,7 +876,7 @@ var FILESYSTEM = 1;
// it is not used. For example, if your C code uses no files, but you include
// some JS that does, you might need this.
// [link]
-var FORCE_FILESYSTEM = 0;
+var FORCE_FILESYSTEM = 1;
// Enables support for the NODERAWFS filesystem backend. This is a special
// backend as it replaces all normal filesystem access with direct Node.js
@@ -889,7 +889,7 @@ var FORCE_FILESYSTEM = 0;
// handles permissions and errors and so forth may be noticeable. This has
// mostly been tested on Linux so far.
// [link]
-var NODERAWFS = 0;
+var NODERAWFS = 1;
// This saves the compiled wasm module in a file with name
// $WASM_BINARY_NAME.$V8_VERSION.cached

View File

@@ -0,0 +1,22 @@
diff --git a/src/settings.js b/src/settings.js
index 94cf2e744..0495c3bf1 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -167,7 +167,7 @@ var ABORTING_MALLOC = 1;
//
// (This option was formerly called TOTAL_MEMORY.)
// [link]
-var INITIAL_MEMORY = 16777216;
+var INITIAL_MEMORY = 19988480;
// Set the maximum size of memory in the wasm module (in bytes). This is only
// relevant when ALLOW_MEMORY_GROWTH is set, as without growth, the size of
@@ -204,7 +204,7 @@ var MAXIMUM_MEMORY = 2147483648;
// returning 0 when it fails, and also of being able to allocate more
// memory from the system as necessary.
// [link]
-var ALLOW_MEMORY_GROWTH = 0;
+var ALLOW_MEMORY_GROWTH = 1;
// If ALLOW_MEMORY_GROWTH is true, this variable specifies the geometric
// overgrowth rate of the heap at resize. Specify MEMORY_GROWTH_GEOMETRIC_STEP=0

View File

@@ -0,0 +1,130 @@
# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import re
import sys
from textwrap import dedent
from spack import *
class Emscripten(Package):
"""An LLVM-to-WebAssembly Compiler"""
homepage = "https://emscripten.org"
git = "https://github.com/emscripten-core/emscripten.git"
url = "https://github.com/emscripten-core/emscripten/archive/refs/tags/3.0.0.tar.gz"
version('3.0.0', sha256='c5524755b785d8f4b83eb3214fdd3ac4b2e1b1a4644df4c63f06e5968f48f90e')
variant('create-standard-executables', default=True,
description='Apply some patches to executable-type output files in order to make them executable by default.')
# Need f-strings to run emcc, so 3.7+.
depends_on('python@3.7:')
depends_on('npm', type='build')
depends_on('llvm@14:+lld+clang+multiple-definitions targets=webassembly')
depends_on('openjdk')
# Each version of emscripten has an single specific binaryen version they are
# compatible with.
depends_on('binaryen')
depends_on('binaryen@101', when='@3.0.0')
with when('+create-standard-executables'):
# Ensure the output has a hashbang and is marked executable with chmod.
patch('executable-result.patch')
# Ensure the output has access to node raw fs APIs.
patch('force-fs.patch')
# Ensure that executables have sufficient initial memory, and can grow the
# memory at runtime.
patch('initial-memory.patch')
executables = ('^{}$'.format(re.escape(exe)) for exe in [
'emscons',
'embuilder',
'emprofile',
'emconfigure',
'em++',
'emcc',
'emnm',
'emrun',
'em-config',
'emcmake',
'emdump',
'emranlib',
'emar',
'emsize',
'emdwp',
'emmake',
])
_description = 'Emscripten gcc/clang-like replacement + linker emulating GNU ld'
_version_pattern = re.compile(
r'^emcc \({}\) ([0-9]+\.[0-9]+\.[0-9]+(?:\-git)?)$'.format(
re.escape(_description)),
flags=re.MULTILINE,
)
@classmethod
def determine_version(cls, exe_path):
try:
exe = Executable(exe_path)
output = exe('--version', output=str, error=str)
m = cls._version_pattern.search(output)
if m is None:
return None
(v,) = m.groups()
return Version(v)
except spack.util.executable.ProcessError:
pass
return None
def install(self, spec, prefix):
npm = which('npm')
npm('install')
with open('.emscripten', 'w') as f:
f.write(dedent("""\
NODE_JS = '{node_js}'
LLVM_ROOT = '{llvm}'
BINARYEN_ROOT = '{binaryen}'
EMSCRIPTEN_ROOT = '{emscripten}'
JAVA = '{java}'
COMPILER_ENGINE = NODE_JS
JS_ENGINES = [NODE_JS]
""".format(
node_js=str(which('node')),
llvm=os.path.dirname(str(which('wasm-ld'))),
binaryen=str(self.spec['binaryen'].prefix),
emscripten=str(prefix),
java=str(which('java')),
)))
install_tree('.', str(prefix))
def setup_run_environment(self, env):
# Tools like emcc are at the prefix root instead of /bin, and they don't seem to
# like being symlinked into /bin.
env.prepend_path('PATH', self.prefix)
_check_description = 'shared:INFO: (Emscripten: Running sanity checks)'
_check_line = re.compile(
r'^{}$'.format(re.escape(_check_description)),
flags=re.MULTILINE,
)
def test(self):
self.run_test(
'emcc',
options=['--check'],
expected=[self._version_pattern, self._check_line],
installed=True,
purpose='test: validating emscripten installation',
skip_missing=False,
)

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
#include <stdio.h>
int main() {
printf("hello, world!\n");
return 0;
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,113 @@
# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import re
import sys
from spack import *
class Emsdk(Package):
"""Emscripten SDK"""
homepage = "https://emscripten.org"
git = "https://github.com/emscripten-core/emsdk.git"
version('latest', branch='main')
version('3.1.8', tag='3.1.8')
version('2.0.34', tag='2.0.34')
version('1.40.1', tag='1.40.1')
# TODO: see https://emscripten.org/docs/building_from_source/index.html#installing-from-source and https://emscripten.org/docs/building_from_source/configuring_emscripten_settings.html.
# variant('from-source', default=False, description='Build emscripten from source.')
depends_on('python@3')
depends_on('node-js')
depends_on('llvm@main+lld+clang targets=webassembly')
depends_on('cmake', type='test')
provides('wasm')
phases = ['install']
executables = ['emcc', r'em\+\+']
def _patch_line_regex(self, varname):
return re.compile(r'^{} = (.*)$'.format(varname),
flags=re.MULTILINE)
def _patch_line_replacement(self, varname, path):
return "{} = '{}'".format(varname, path)
def _patch_emscripten_config_line(self, varname, path, file_contents):
regex = self._patch_line_regex(varname)
replacement = self._patch_line_replacement(varname, path)
return regex.sub(replacement, file_contents)
def _patch_emscripten_config_contents(self, file_contents):
# Use the path to the actual `node` executable.
node_path = str(which('node'))
file_contents = self._patch_emscripten_config_line(
'NODE_JS', node_path, file_contents,
)
# Use the directory containing the `lld` binary.
lld_path = os.path.dirname(str(which('lld')))
file_contents = self._patch_emscripten_config_line(
'LLVM_ROOT', lld_path, file_contents,
)
return file_contents
def _patch_emscripten_config_file(self, path):
"""Use our own llvm and node by overriding NODE_JS and LLVM_ROOT in the
generated .emscripten file."""
assert os.path.isfile(path), path
with open(path, 'r') as f:
config_contents = f.read()
config_contents = self._patch_emscripten_config_contents(config_contents)
with open(path, 'w') as f:
f.write(config_contents)
def install(self, spec, prefix):
# See https://emscripten.org/docs/getting_started/downloads.html#emsdk-install-targets.
if str(self.version) == 'main':
version_arg = 'latest'
else:
version_arg = str(self.version)
emsdk_script = Executable('./emsdk')
emsdk_script('update')
emsdk_script('install', version_arg)
emsdk_script('activate', version_arg)
# Patch .emscripten to point to our versions of node and llvm.
self._patch_emscripten_config_file('.emscripten')
install_tree('.', prefix)
_set_env_var_line = re.compile(r'^([A-Z_]+) = (.*)$', flags=re.MULTILINE)
_clear_env_var_line = re.compile(r'^Clearing existing environment variable: (.*)$',
flags=re.MULTILINE)
def setup_run_environment(self, env):
"""Parse the output of the environment setup script from the emscripten SDK."""
# setup_script = self.prefix.join('emsdk_env.sh')
# env.extend(EnvironmentModifications.from_sourcing_file(setup_script))
# import pdb; pdb.set_trace()
sh = which('sh')
with working_dir(self.prefix):
sh_output = sh('./emsdk_env.sh', output=str, error=str)
for m in self._set_env_var_line.finditer(sh_output):
(env_var, env_value) = m.groups()
if env_var != 'PATH':
env.set(env_var, env_value)
for m in self._clear_env_var_line.finditer(sh_output):
(var_to_unset,) = m.groups()
env.unset(var_to_unset)
env.append_path('PATH', self.prefix.upstream.emscripten)
env.prepend_path('PATH', self.prefix.upstream.bin)

View File

@@ -0,0 +1,13 @@
diff --git a/./configure b/./configure
index 4ba72bf..43c1a0e 100755
--- a/./configure
+++ b/./configure
@@ -4652,7 +4652,7 @@ probe_cc(){
_depflags='-MMD'
_cflags_speed='-O3'
_cflags_size='-Os'
- elif $_cc -v 2>&1 | grep -q clang && ! $_cc -? > /dev/null 2>&1; then
+ elif $_cc -v 2>&1 | grep -q clang && $_cc -? > /dev/null 2>&1; then
_type=clang
_ident=$($_cc --version 2>/dev/null | head -n1)
_depflags='-MMD -MF $(@:.o=.d) -MT $@'

View File

@@ -61,13 +61,20 @@ class Ffmpeg(AutotoolsPackage):
# description='XML parsing, needed for dash demuxing support')
variant('libzmq', default=False, description='message passing via libzmq')
variant('lzma', default=False, description='lzma support')
variant('avresample', default=False, description='AV reasmpling component')
variant('avresample', default=False, description='AV resampling component (deprecated)')
variant('openssl', default=False, description='needed for https support')
variant('sdl2', default=False, description='sdl2 support')
variant('shared', default=True, description='build shared libraries')
variant('static', default=True, description='build static libraries')
variant('libx264', default=False, description='H.264 encoding')
variant('alsa', default=True, when='platform=linux', description='Build ALSA support')
variant('doc', default=True, description='Build documentation')
variant('swscale', default=True, description='Build libswscale')
variant('swresample', default=True, description='Build libswresample')
variant('postproc', default=True, description='Build libpostproc')
variant('stripping', default=True, description='Build stripped binaries')
depends_on('alsa-lib', when='platform=linux')
depends_on('alsa-lib', when='+alsa')
depends_on('libiconv')
depends_on('yasm@1.2.0:')
depends_on('zlib')
@@ -125,6 +132,8 @@ def enable_or_disable_meta(self, variant, options):
switch = 'enable' if '+{0}'.format(variant) in self.spec else 'disable'
return ['--{0}-{1}'.format(switch, option) for option in options]
patch('disable-asm.patch', when='%emscripten')
def configure_args(self):
spec = self.spec
config_args = [
@@ -132,6 +141,12 @@ def configure_args(self):
'--cc={0}'.format(spack_cc),
'--cxx={0}'.format(spack_cxx)
]
if self.spec.satisfies('%emscripten'):
config_args.extend([
'--disable-asm',
'--arch=wasm32',
'--disable-programs',
])
# '+X' meta variant #
@@ -176,6 +191,13 @@ def configure_args(self):
'nonfree',
'openssl',
'shared',
'static',
'alsa',
'doc',
'swscale',
'swresample',
'postproc',
'stripping',
'version3',
]

View File

@@ -38,7 +38,8 @@ class Gsl(AutotoolsPackage, GNUMirrorPackage):
depends_on('m4', type='build', when='+external-cblas')
depends_on('autoconf', type='build', when='+external-cblas')
depends_on('automake', type='build', when='+external-cblas')
depends_on('libtool', type='build', when='+external-cblas')
# Pinning libtool@2.4.6 appears necessary to be compatible with openblas@0.3.20.
depends_on('libtool@2.4.6', type='build', when='+external-cblas')
depends_on('blas', when='+external-cblas')
@property

View File

@@ -0,0 +1,65 @@
diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h
index 8eaa4acc6..abaf1c9a2 100644
--- a/lld/wasm/Config.h
+++ b/lld/wasm/Config.h
@@ -27,6 +27,7 @@ enum class UnresolvedPolicy { ReportError, Warn, Ignore, ImportDynamic };
struct Configuration {
bool bsymbolic;
bool checkFeatures;
+ bool allowMultipleDefinition;
bool compressRelocations;
bool demangle;
bool disableVerify;
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 1dc6b9dd6..68826b567 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -350,6 +350,9 @@ static void readConfigs(opt::InputArgList &args) {
config->bsymbolic = args.hasArg(OPT_Bsymbolic);
config->checkFeatures =
args.hasFlag(OPT_check_features, OPT_no_check_features, true);
+ config->allowMultipleDefinition =
+ args.hasFlag(OPT_allow_multiple_definition,
+ OPT_no_allow_multiple_definition, true);
config->compressRelocations = args.hasArg(OPT_compress_relocations);
config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
config->disableVerify = args.hasArg(OPT_disable_verify);
diff --git a/lld/wasm/Options.td b/lld/wasm/Options.td
index a5395bbda..10a0b84de 100644
--- a/lld/wasm/Options.td
+++ b/lld/wasm/Options.td
@@ -138,6 +138,12 @@ defm wrap: Eq<"wrap", "Use wrapper functions for symbol">,
def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">,
HelpText<"Linker option extensions">;
+// This is stolen from the ELF linker
+
+defm allow_multiple_definition: B<"allow-multiple-definition",
+ "Allow multiple definitions",
+ "Do not allow multiple definitions (default)">;
+
// The follow flags are unique to wasm
def allow_undefined: F<"allow-undefined">,
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index ef1402248..113ebb20e 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -294,10 +294,13 @@ static bool shouldReplace(const Symbol *existing, InputFile *newFile,
return true;
}
- // Neither symbol is week. They conflict.
- error("duplicate symbol: " + toString(*existing) + "\n>>> defined in " +
- toString(existing->getFile()) + "\n>>> defined in " +
- toString(newFile));
+ if (!config->allowMultipleDefinition) {
+ // Neither symbol is week. They conflict.
+ error("duplicate symbol: " + toString(*existing) + "\n>>> defined in " +
+ toString(existing->getFile()) + "\n>>> defined in " +
+ toString(newFile));
+ }
+
return true;
}

View File

@@ -77,6 +77,12 @@ class Llvm(CMakePackage, CudaPackage):
default=True,
description="Build the LLVM C/C++/Objective-C compiler frontend",
)
variant(
"tools-extra-clang",
default=True,
description="Build extra tools like clang-tidy on top of clang",
when='+clang',
)
variant(
"flang",
default=False,
@@ -165,6 +171,11 @@ class Llvm(CMakePackage, CudaPackage):
default=True,
description="Build OpenMP runtime via ENABLE_RUNTIME by just-built Clang",
)
variant(
"openmp",
default=True,
description="Build OpenMP support",
)
variant('code_signing', default=False,
description="Enable code-signing on macOS")
variant("python", default=False, description="Install python bindings")
@@ -172,6 +183,9 @@ class Llvm(CMakePackage, CudaPackage):
variant('version_suffix', default='none', description="Add a symbol suffix")
variant('z3', default=False, description='Use Z3 for the clang static analyzer')
variant('multiple-definitions', default=False,
when='targets=webassembly', description='Allow multiple definitions in wasm linking')
provides('libllvm@14', when='@14.0.0:14')
provides('libllvm@13', when='@13.0.0:13')
provides('libllvm@12', when='@12.0.0:12')
@@ -361,6 +375,11 @@ class Llvm(CMakePackage, CudaPackage):
# patch for missing hwloc.h include for libompd
patch('llvm14-hwloc-ompd.patch', when='@14')
# Allow wasm-ld to have a --allow-multiple-definition flag, turned on by
# default. This mirrors the behavior of gcc when producing and consuming
# shared libraries.
patch('multiple-definitions-wasm.patch', when='+multiple-definitions')
# The functions and attributes below implement external package
# detection for LLVM. See:
#
@@ -620,11 +639,13 @@ def cmake_args(self):
if "+clang" in spec:
projects.append("clang")
projects.append("clang-tools-extra")
if "+omp_as_runtime" in spec:
runtimes.append("openmp")
else:
projects.append("openmp")
if '+tools-extra-clang' in spec:
projects.append("clang-tools-extra")
if '+openmp' in spec:
if "+omp_as_runtime" in spec:
runtimes.append("openmp")
else:
projects.append("openmp")
if self.spec.satisfies("@8"):
cmake_args.append(define('CLANG_ANALYZER_ENABLE_Z3_SOLVER',

View File

@@ -52,6 +52,9 @@ class NodeJs(Package):
depends_on('gmake@3.81:', type='build')
depends_on('libtool', type='build', when=sys.platform != 'darwin')
depends_on('pkgconfig', type='build')
# FIXME: this actually can *only* be python 3.5 for python versions >= 3, but it's
# impossible to later install emscripten if we do that, since that requires at least
# python 3.7.
depends_on('python@2.7:2.8,3.5:', when='@12:', type='build')
depends_on('python@2.7:2.8', when='@:11', type='build')
# depends_on('bash-completion', when="+bash-completion")
@@ -60,6 +63,8 @@ class NodeJs(Package):
depends_on('openssl@1.1:', when='@10:+openssl')
depends_on('zlib', when='+zlib')
executables = ['node']
phases = ['configure', 'build', 'install']
# https://github.com/spack/spack/issues/19310
@@ -67,6 +72,19 @@ class NodeJs(Package):
msg="fails to build with gcc 4.8 "
"(see https://github.com/spack/spack/issues/19310")
@classmethod
def determine_version(cls, exe_path):
try:
exe = Executable(exe_path)
output = exe('--version', output=str, error=str)
if not output.startswith('v'):
return None
return Version(output[1:])
except spack.util.executable.ProcessError:
pass
return None
def setup_build_environment(self, env):
# Force use of experimental Python 3 support
env.set('PYTHON', self.spec['python'].command.path)

View File

@@ -17,6 +17,8 @@ class Npm(Package):
# base https://www.npmjs.com/
url = "https://registry.npmjs.org/npm/-/npm-6.13.4.tgz"
executables = ['npm', 'npx']
version('6.14.9', sha256='1e0e880ce0d5adf0120fb3f92fc8e5ea5bac73681d37282615d074ff670f7703')
version('6.14.8', sha256='fe8e873cb606c06f67f666b4725eb9122c8927f677c8c0baf1477f0ff81f5a2c')
version('6.13.7', sha256='6adf71c198d61a5790cf0e057f4ab72c6ef6c345d72bed8bb7212cb9db969494')
@@ -45,14 +47,40 @@ def patch(self):
'package.json')
install_tree('env-paths/package', 'node_modules/env-paths')
@property
def _is_alpine(self):
"""Determine whether the current spec is being built for alpine linux.
If so, we avoid building any documentation and simply copy over javascript
sources. Alpine's use of musl libc causes a segmentation fault when executing
`make` (when executing `gatsby build`)."""
return self.spec.architecture.os.startswith('alpine')
def configure(self, spec, prefix):
configure('--prefix={0}'.format(prefix))
if not self._is_alpine:
configure('--prefix={0}'.format(prefix))
def build(self, spec, prefix):
make()
if self._is_alpine:
# Link npm.
os.unlink(os.path.join('bin', 'npm'))
symlink('npm-cli.js',
os.path.join('bin', 'npm'))
# Link npx.
os.unlink(os.path.join('bin', 'npx'))
symlink('npx-cli.js',
os.path.join('bin', 'npx'))
else:
make()
def install(self, spec, prefix):
make('install')
if self._is_alpine:
install_tree('.', prefix)
else:
make('install')
def setup_run_environment(self, env):
env.prepend_path('PATH', self.prefix.bin)
def setup_dependent_build_environment(self, env, dependent_spec):
npm_config_cache_dir = "%s/npm-cache" % dependent_spec.prefix

View File

@@ -0,0 +1,36 @@
# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack import *
class Plotutils(AutotoolsPackage, GNUMirrorPackage):
"""The GNU plotutils package contains software for both programmers and technical
users. Its centerpiece is libplot, a powerful C/C++ function library for exporting
2-D vector graphics in many file formats, both vector and bitmap. On the X Window
System, it can also do 2-D vector graphics animations."""
homepage = "https://www.gnu.org/software/plotutils"
gnu_mirror_path = "plotutils/plotutils-2.6.tar.gz"
version('2.6', sha256='4f4222820f97ca08c7ea707e4c53e5a3556af4d8f1ab51e0da6ff1627ff433ab')
depends_on('libxt')
depends_on('libxaw')
# libpng@1.5: introduces an error relating to the incomplete type png_struct which
# appears to be a result of this codebase using types that later become opaque in
# 1.5.0 onwards; see discussion at https://github.com/glennrp/libpng/issues/191.
depends_on('libpng@:1.4')
depends_on('zlib')
def configure_args(self):
xt = self.spec['libxt']
xaw = self.spec['libxaw']
configure_args = [
'--x-includes={}:{}'.format(xt.prefix.include, xaw.prefix.include),
'--x-libraries={}:{}'.format(xt.prefix.lib, xaw.prefix.lib),
]
return configure_args

View File

@@ -3,6 +3,11 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import stat
from llnl.util.filesystem import chmod_x
from spack import *

View File

@@ -75,12 +75,23 @@ def install(self, spec, prefix):
nmake('-f' 'win32\\Makefile.msc')
self.win_install()
else:
def do_configure(*args):
if self.spec.satisfies('%emscripten'):
emconfigure(*args)
else:
configure(*args)
def do_make(*args):
if self.spec.satisfies('%emscripten'):
emmake(*args)
else:
make(*args)
config_args = []
if '~shared' in spec:
config_args.append('--static')
configure('--prefix={0}'.format(prefix), *config_args)
do_configure('--prefix={0}'.format(prefix), *config_args)
make()
do_make()
if self.run_tests:
make('check')
make('install')
do_make('check')
do_make('install')