Я потратил некоторое время, пытаясь решить эту проблему, и теперь rustc генерирует код, который может переводить emscripten, но скомпилированный javascript дает сбой, когда попадает в функцию времени выполнения. Следующим шагом является создание среды выполнения с использованием emcc
в качестве компилятора. Уберите все, что не работает, за EMSCRIPTEN
ifdefs.
Emscripten добавляет способ обработки встроенной сборки как javascript, поэтому все части среды выполнения, которые не создаются с помощью emscripten, могут быть реализованы встроенно с помощью javascript.
В качестве альтернативы мы могли бы повторно реализовать среду выполнения по частям в javascript и вообще не беспокоиться о ее компиляции из C ++. Такой подход не рекомендуется.
См. Также №3608.
Все равно было бы хорошо; не на каком-либо этапе зрелости.
Все равно было бы неплохо, но это не очень важно. Это должно стать проще, поскольку большая часть среды выполнения переписывается в ржавчине.
Теперь, когда среда выполнения написана на Rust, как это меняет перспективы для этой ошибки? Насколько сложно было бы запустить Hello World без времени выполнения через emscripten?
Теперь не должно быть особенно сложно добавить действительно хорошую поддержку для emscripten. Он уже в значительной степени работает с rust-core. В компиляторе нам нужно добавить поддержку правильной целевой тройки, правильно настроить различные целевые атрибуты, а затем отгородить несколько частей среды выполнения, которые в настоящее время не могут работать в js, потоковой передаче и переключении контекста.
Когда режим планирования 1: 1 станет немного более зрелым, мы сможем даже добавить поддержку задач через веб-воркеров, хотя в настоящее время для этого потребуется другое решение для передачи сообщений. В зависимости от того, какая поддержка параллелизма будет добавлена в js / emscripten, в конечном итоге мы сможем точно поддерживать семантику передачи сообщений rust.
@brson : Я думаю, что # 10780 будет самым большим блокировщиком на данный момент. Rust будет выводить посадочные площадки с вызовами для обновления размера, используемого для обеспечения безопасности стека, с помощью поддержки сегментированного стека LLVM.
Благодаря -Z no-landing-pads
теперь все работает нормально! Добавление явной поддержки этого в стандартную библиотеку возможно, но большинство из них все равно не будет работать (файлы, tcp, udp и т. Д.), Поэтому я не думаю, что это необходимо. Если и когда стандартная библиотека получит автономную поддержку, она начнет работать, и мы сможем открыть больше проблем в зависимости от функциональности, которую мы можем сопоставить с JavaScript.
Если все в порядке, я бы хотел пока оставить это открытым. Я думаю, что это будет хорошим шагом вперед к тому, чтобы стандартная библиотека была расширяемой и могла работать на любом количестве платформ.
Я согласен с тем, что большая часть работы, вероятно, уже сделана, и для этого, вероятно, потребуется libemscripten
для обеспечения ввода-вывода, специфичного для emscripten, но я думаю, что на этом пути может возникнуть достаточно проблем, поэтому от этого стоит отказаться вопрос открыт (это все еще интересный проект!)
@alexcrichton : невозможно обеспечить параллелизм и поддержку ввода-вывода стандартной библиотеки для emscripten. В лучшем случае он мог выводить на консоль для stdout / stderr. Я не могу придумать в стандартной библиотеке ничего, что было бы хорошей идеей для цели emscripten, но не автономной, помимо реализации распределителя по умолчанию.
Обновление статуса:
@alexcrichton Реорганизовал стандартную библиотеку в кучу меньших библиотек с более понятными зависимостями. Теперь должно быть почти тривиально скомпилировать библиотеки core, alloc, rand и collections в Интернет.
Вот как я бы посоветовал решить эту проблему:
Хорошее начало!
Хорошо, я попробовал с первых шагов, и, очевидно, сразу же возникли проблемы.
Я скомпилировал libcore
в битовый код с помощью --emit bc
, и при попытке скомпилировать его с помощью emcc -O0
я получаю:
/Users/arcnor/emscripten-fastcomp/build/bin/llvm-nm: /tmp/tmpfTkmfj/core_0.o: Invalid CMPXCHG record.
/Users/arcnor/emscripten-fastcomp/build/bin/opt: /tmp/tmpfTkmfj/core.bc: error: Invalid CMPXCHG record
Traceback (most recent call last):
File "/Users/arcnor/emscripten/emcc", line 1573, in <module>
shared.Building.llvm_opt(final, link_opts)
File "/Users/arcnor/emscripten/tools/shared.py", line 1335, in llvm_opt
assert os.path.exists(target), 'Failed to run llvm optimizations: ' + output
AssertionError: Failed to run llvm optimizations:
Не уверен, что могу что-нибудь с этим сделать, или это потому, что мы не можем использовать для этого вывод rustc --emit
.
Извините, если это не место, чтобы комментировать это ...
Я также пробовал с libnum
, более простым, и bc
генерируется правильно, но во время процесса emcc
я получаю предупреждение об использовании неправильной тройки и полученного результата. js не имеет никаких функций внутри libnum
, поэтому я думаю, что я здесь слишком наивен :)
@Arcnor Вы можете спросить некоторых из тех, кто ранее компилировал простые тесты с помощью emscripten, об их процессе. У меня есть только несколько идей.
Ошибка при попытке скомпилировать libcore
похоже, связана с этой проблемой emscripten. Компиляция libcore
в байт-код llvm генерирует атомарные инструкции llvm, но emscripten не поддерживает атомарные инструкции.
Возможно, есть способ обойти это со стороны ржавчины, но, основываясь на комментариях в проблеме emscripten, я думаю, что поддержка атомики в emscripten имеет наибольший смысл.
Если у emscripten есть своя собственная платформа, мы могли бы, возможно, исключить все атомики для их однопоточных вариантов, но я согласен, что было бы лучше иметь это в восходящем потоке emscripten!
Если я не ошибаюсь, новый backend emscripten "fastcomp" является форком LLVM (в то время как предыдущий backend был просто уровнем выше LLVM), поэтому LLVM-версию fastcomp, вероятно, сложно обновить, и она не будет обновлена. часто.
Это будет проблематично, если потребуется совместимость с выходными данными Rust. Например, сейчас версия fastcomp для LLVM - 3.3, а LLVM, используемая Rust, - 3.4.
Старый серверный модуль emscripten устарел и не должен использоваться в соответствии с официальной документацией, поэтому, вероятно, его нельзя использовать.
Кажется, на данный момент я единственный, кто пытается скомпилировать для emscripten.
Для справки, вот что я пробовал:
--llvm-root
на fastcomp от emscripten; это не сработало, потому что они удалили поддержку ARM / MIPS / и т. д. в их вилке (из-за этого я получаю ошибки из make-файлов и во время компоновки)--llvm-root
на предварительно скомпилированный LLVM 3.3 (взятый из официального репозитория ubuntu); получение подтверждения не удалось в конце компиляции stage1, и созданный двоичный файл rustc не работает.Если у кого-то нет идеи, я пришел к выводу, что нам нужно дождаться обновления emscripten.
ром вроде как работает; возможно это поможет
Незначительное обновление: emscripten-fastcomp обновлен до LLVM 3.4 и будет обновлен до LLVM 3.5 позже.
@tomaka вы пробовали что-нибудь делать с версией 3.4? Мне удалось получить пример рома, скомпилированного с ним, но что-то еще не удалось с непонятными ошибками.
@ibdknox 3.4 несовместим с 3.5
Даже простой привет мир дает ошибочное утверждение: LLVM ERROR: 0 && "some i64 thing we can't legalize yet"
Хм. Мне удалось взять вывод из rustc --emit ir foo.rust
и запустить его через emscripten-incoming. На LLVM 3.5 теперь есть ржавчина?
Rust давно использует LLVM 3.5. Вам может повезти, и вы не получите ничего несовместимого.
Например, это прекрасно компилируется:
#[start]
fn main(_: int, _: *const *const u8) -> int {}
Это не из-за несовместимого IR:
fn main() { println!("hello world"); }
@ibdknox http://www.reddit.com/r/rust_gamedev/comments/2n0x08/emscripten_experiments/
Похоже, несовместимости меньше, чем я думал.
В качестве обновления, когда я компилирую hello world с emscripten, который теперь обновлен до версии 3.5, я получаю следующее:
Value: %28 = call fastcc { i8, [0 x i8], [0 x i8] } @_ZN3fmt5write20h2c56fdda0b308d94DFAE({ i8*, void (i8*)** }* noalias nocapture dereferenceable(8) %arg.i, %"struct.core::fmt::Arguments[#3]"* noalias nocapture readonly dereferenceable(24) %__args31), !noalias !22
LLVM ERROR: Unrecognized struct value
Traceback (most recent call last):
File "/Users/chris/Downloads/emsdk_portable/emscripten/incoming/emcc", line 1259, in <module>
shared.Building.llvm_opt(final, link_opts)
File "/Users/chris/Downloads/emsdk_portable/emscripten/incoming/tools/shared.py", line 1401, in llvm_opt
assert os.path.exists(target), 'Failed to run llvm optimizations: ' + output
AssertionError: Failed to run llvm optimizations:
Вот как я компилирую:
rustc --target i686-apple-darwin -C lto --emit ir foo.rust
emcc -v foo.ll -o test.html
Вещи, которые, кажется, не приносят результатов, обычно работают.
На прошлой неделе я проводил свободное время, изучая это. Я читал книгу Руста где-то между летом и сейчас, и мне очень понравилась механика языка, но только недавно я начал что-то с ней реализовывать. Я осведомлен о компиляторе ржавчины ровно настолько, насколько я узнал на этой неделе, но надеюсь, что смогу внести свой вклад.
Итак, я думаю, первое, что нужно отметить из того, что я узнал (но на это у меня ушло несколько вечеров), это то, что Rust перешел на LLVM 3.6 в июле. Таким образом, текущие версии Rust и emscripten-fastcomp несовместимы.
Я попытался скомпилировать ржавчину с помощью --llvm-root
указывающего на emscripten-fastcomp 1.29.2, и получил эту ошибку:
rustc: x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libcore
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: http://doc.rust-lang.org/complement-bugreport.html
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'assertion failed: self.raw.hash != self.hashes_end', /Users/zen/Code/rust/src/libstd/collections/hash/table.rs:776
make: *** [x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/stamp.core] Error 101
Чтобы добраться до этой ошибки, я настроил и построил emscripten-fastcomp с
../configure --enable-optimized --disable-assertions --enable-targets=host,js,arm,aarch64,mips
Вместо рекомендованного руководства emscripten
../configure --enable-optimized --disable-assertions --enable-targets=host,js
Хотя Rust не нужно собирать для всех целей, в настоящее время он всегда связывается с LLVM с поддержкой ЦП, скомпилированной для всех целей. Это обходной путь для проблемы, которая может быть исправлена в будущем, поэтому нам, возможно, не нужно всегда компилировать emscripten-fastcomp с этой конфигурацией.
Как только я обнаружил, что Rust перешел на LLVM 3.6, я нашел последнюю ветку на rust-lang / llvm, которая была LLVM 3.5. https://github.com/rust-lang/llvm/tree/rust-llvm-2014-07-24 Я скомпилировал это вместо emscripten-fastcomp, любопытно посмотреть, что получится. Я получил ту же самую ошибку при компиляции против emscripton-fastcomp недавнего перехода на LLVM 3.5. Я считаю, что это означает, что Rust сейчас в некотором роде несовместим с LLVM 3.5, и я не ожидал бы иного.
Итак, теперь мы ждем или нам нужно получить emscripten-fastcomp для LLVM 3.6: wink:
Стоит упомянуть, что я загрузил заархивированную копию 0.11 и смог создать LLVM IR для hello world, который emcc
понял, но затем столкнулся с проблемой связывания. Было довольно интересно увидеть, как он ушел из понимания байтового кода, но для того, чтобы на самом деле связать его, потребуется доработать базу кода ржавчины.
Я взглянул на слияние rust-lang / llvm с emscripten-fastcomp. На тот момент насчитывалось 117 конфликтующих разделов над 43 файлами.
Я уже упоминал о получении Rust 0.11 и emcc 1.29.2, чтобы перейти на этап компоновки. Это конкретный результат:
$ emcc -v hello.ll -o hello.js
INFO root: (Emscripten: Running sanity checks)
WARNING: Linking two modules of different data layouts: '/Users/zen/.emscripten_cache/libc.bc' is 'e-p:32:32-i64:64-v128:32:128-n32-S128' whereas '/tmp/tmpv_yB8E/hello_0.o' is 'e-p:32:32-f64:32:64-f80:128-n8:16:32'
WARNING: Linking two modules of different target triples: /Users/zen/.emscripten_cache/libc.bc' is 'asmjs-unknown-emscripten' whereas '/tmp/tmpv_yB8E/hello_0.o' is 'i686-apple-darwin'
warning: incorrect target triple 'i686-apple-darwin' (did you use emcc/em++ on all source files and not clang directly?)
warning: unresolved symbol: _ZN2io5stdio12println_args20h0caae70b0e2eb347Iol7v0_11_0E
warning: unresolved symbol: _ZN10lang_start20h70f93b7d0a75f99atre7v0_11_0E
Кажется, что emcc / fastcomp заменяет точки в символах символами подчеркивания, в то время как Rust ожидает префикса с другим подчеркиванием, но я не уверен в этом. Первый неразрешенный символ отображается как __ZN2io5stdio12println_args20h0caae70b0e2eb347Iol7v0.11.0E
в libstd сборки i686-apple-darwin. Даже если бы я мог заставить emcc узнать, как найти этот символ во встроенных библиотеках, я предполагаю, что библиотеки содержат машинный код, а emcc потребуются байтовые коды LLVM. Я помню, как кто-то упоминал о необходимости скомпилировать стандартную библиотеку для emscripten. Это было бы частью потребности в этом.
Итак, вот следующие шаги, над которыми я хочу поработать, если кто-то захочет попробовать себя в этом. (Или можете сообщить, насколько я прав или нет.)
IO тоже. Возможно, другие части, о которых я не знаю.
"Слить rust-lang / llvm с emscripten-fastcomp"
Возможно, вы не захотите этого делать - Emscripten основан на pnacl-llvm / pnacl-clang, поэтому вы создаете вилку с патчами на патчах, что, вероятно, будет болезненным. Если вам интересно, вы можете увидеть некоторые детали ветвления в исследовании, которое я провел для слияния Emscripten с r33 -> r34 на https://github.com/kripken/emscripten-fastcomp/issues/51#issuecomment -62323164 .
Я слышал, что pnacl планирует отслеживать восходящий поток немного ближе, чем раньше, но я не вижу какой-либо соответствующей проблемы в системе отслеживания проблем pnacl для обновления до версии 3.6, так что это может занять некоторое время (особенно учитывая, что версия 3.6 была разветвлена всего 5 дней назад!). .. Думаю, вы могли создать проблему? Если вы решите не использовать собственный форк Emscripten, я вижу два варианта - дождаться pnacl или помочь Emscripten выйти из pnacl и перейти на апстрим.
Изменить: исправлено «сейчас» на «нет». Решающая разница.
Я прилагаю огромные усилия по сортировке, чтобы подготовить нас к версии 1.0. В рамках этого я перемещаю вещи, похожие на списки желаний, в репозиторий RFC, так как именно здесь следует обсуждать / расставлять приоритеты по основным новым вещам.
Этот вопрос был перемещен в репозиторий RFC: rust-lang / rfcs # 604.
Самый полезный комментарий
Я прилагаю огромные усилия по сортировке, чтобы подготовить нас к версии 1.0. В рамках этого я перемещаю вещи, похожие на списки желаний, в репозиторий RFC, так как именно здесь следует обсуждать / расставлять приоритеты по основным новым вещам.
Этот вопрос был перемещен в репозиторий RFC: rust-lang / rfcs # 604.