Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail mix firmware on Nerves RPi0 with Pelemay ** (Mix) Nerves encountered an error. %IO.Stream{device: :standard_io, line_or_bytes: :line, raw: true} #73

Closed
osako-ricc opened this issue Oct 2, 2019 · 21 comments
Labels
bug Something isn't working
Projects
Milestone

Comments

@osako-ricc
Copy link

osako-ricc commented Oct 2, 2019

Describe the bug

RaspberryPi Zero WH のNerves環境下にてmix firmwareに失敗する.

** (Mix) Nerves encountered an error. %IO.Stream{device: :standard_io, line_or_bytes: :line, raw: true}

To Reproduce
Steps to reproduce the behavior:

  1. Use Pelemay in the source code '...'

lib/pelemay_sample.ex:

defmodule PelemaySample do
  require Pelemay
  import Pelemay
  
  defpelemay do
    def enum_square list do
      list |> Enum.map(& &1 * &1)
    end
  end

  @doc """
    ## Examples
    iex> PelemaySample.do_test()
    [1, 4, 9, 16]
  """
  def do_test do
    1..4 |> Enum.to_list |> enum_square()
  end

  def hello do
    :world
  end
  
end
  1. Run in the command '....'
$ mix firmware
  1. See error
Nerves environment
  MIX_TARGET:   rpi0
  MIX_ENV:      dev

Compiling 1 file (.ex)
|nerves_bootstrap| Building OTP Release...

* skipping runtime configuration (config/releases.exs not found)
* creating _build/rpi0_dev/rel/pelemay_sample/releases/0.1.0/vm.args
Updating base firmware image with Erlang release...
scrub-otp-release.sh: ERROR: Unexpected executable format for '/Users/osako/Documents/nerves/pelemay_sample/_build/_nerves-tmp/rootfs-additions/srv/erlang/lib/pelemay-0.0.4/priv/libnifelixirpelemaysample.so'

Got:
 file:Mach-O 64-bit dynamically linked shared library x86_64

Expecting:
 readelf:ARM;0x5000200, Version5 EABI, soft-float ABI

This file was compiled for the host or a different target and probably
will not work.

Check the following:

1. Are you using a path dependency in your mix deps? If so, run
   'mix clean' in that directory to avoid pulling in any of its
   build products.

2. Did you recently upgrade to Elixir 1.9 or Nerves 1.5?
   Nerves 1.5 adds support for Elixir 1.9 Releases and requires
   you to either add an Elixir 1.9 Release configuration or add
   Distillery as a dependency. Without this, the OTP binaries
   for your build machine will get included incorrectly and cause
   this error. See
   https://hexdocs.pm/nerves/updating-projects.html#updating-from-v1-4-to-v1-5

3. Did you recently upgrade or change your Nerves system? If so,
   try cleaning and rebuilding this project and its deps.

4. Are you building outside of Nerves' mix integration? If so,
   make sure that you've sourced 'nerves-env.sh'.

If you're still having trouble, please file an issue on Github
at https://github.com/nerves-project/nerves_system_br/issues.

** (Mix) Nerves encountered an error. %IO.Stream{device: :standard_io, line_or_bytes: :line, raw: true}

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • Pelemay Version: 0.0.4
  • Elixir & Erlang/OTP versions (elixir --version): OTP22/Elixir 1.9.1
  • OS (OS name & version, and uname -a): macOS 10.14.6 / Darwin VLAN2-dhcp18.is.env.kitakyu-u.ac.jp 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64
  • Clang versions (clang -v): Apple LLVM version 10.0.1 (clang-1001.0.46.4)

Additional context

Pelemayをmix deps.getした状態のものをmix do firmware, firmware.burnして,iexでコードをテストすると,以下のような挙動を得た.

iex(hello_nerves@nerves.local)3> defpelemay do              
...(hello_nerves@nerves.local)3> def enum_square list do    
...(hello_nerves@nerves.local)3> list |> Enum.map(& &1 * &1)
...(hello_nerves@nerves.local)3> end                        
...(hello_nerves@nerves.local)3> end
** (ArgumentError) argument error
    (stdlib) :ets.new(:nif_func, [:set, :public, :named_table])
    (pelemay) lib/pelemay/db.ex:10: Pelemay.Db.init/0
    (pelemay) expanding macro: Pelemay.defpelemay/1
    iex:3: (file)

なお,Nervesを通さずにDocTestを通すことはできます.

@osako-ricc osako-ricc added the bug Something isn't working label Oct 2, 2019
@zacky1972
Copy link
Collaborator

Thank you for your contribution @osako-ricc

I guess this error message is essential:

Got:
 file:Mach-O 64-bit dynamically linked shared library x86_64

Expecting:
 readelf:ARM;0x5000200, Version5 EABI, soft-float ABI

That is, Nerves assumes not dlls but elf.

@zacky1972
Copy link
Collaborator

Would you run the following command? @osako-ricc

mix nerves.env --info

@zacky1972
Copy link
Collaborator

Thank you for your contribution @osako-ricc

I guess this error message is essential:

Got:
 file:Mach-O 64-bit dynamically linked shared library x86_64

Expecting:
 readelf:ARM;0x5000200, Version5 EABI, soft-float ABI

That is, Nerves assumes not dlls but elf.

No, the error shows it is compiled for x86_64, not ARM.

I guess it needs cross compilation.

@zacky1972
Copy link
Collaborator

zacky1972 commented Oct 2, 2019

@mobileoverlord @fhunleth @ConnorRigby
How can an elixir program incuding Pelemay get whether it is compiled by mix firmware, which requires cross compilation?

I'd like to modify Pelemay.Generator.Builder to compile the application into the target architecture like ARM.

@zacky1972 zacky1972 changed the title RPi0のNerves環境下にてmix firmwareに失敗する: ** (Mix) Nerves encountered an error. %IO.Stream{device: :standard_io, line_or_bytes: :line, raw: true} Fail mix firmware on Nerves RPi0 with Pelamy ** (Mix) Nerves encountered an error. %IO.Stream{device: :standard_io, line_or_bytes: :line, raw: true} Oct 2, 2019
@osako-ricc
Copy link
Author

osako-ricc commented Oct 2, 2019

Would you run the following command? @osako-ricc

mix nerves.env --info

Following the command: mix nerves.env --info

VLAN2-dhcp18% mix nerves.env --info
|nerves_bootstrap| Environment Package List

  Pkg:         nerves_system_br
  Vsn:         1.9.2
  Type:        system_platform
  BuildRunner: {nil, []}

  Pkg:         nerves_system_rpi0
  Vsn:         1.9.0
  Type:        system
  BuildRunner: {Nerves.Artifact.BuildRunners.Docker, []}

  Pkg:         nerves_toolchain_armv6_rpi_linux_gnueabi
  Vsn:         1.2.0
  Type:        toolchain
  BuildRunner: {Nerves.Artifact.BuildRunners.Local, []}

  Pkg:         nerves_toolchain_ctng
  Vsn:         1.6.0
  Type:        toolchain_platform
  BuildRunner: {nil, []}

|nerves_bootstrap| Loadpaths Start


Nerves environment
  MIX_TARGET:   rpi0
  MIX_ENV:      dev

|nerves_bootstrap| Environment Variable List
  target:     rpi0
  toolchain:  /Users/osako/.nerves/artifacts/nerves_toolchain_armv6_rpi_linux_gnueabi-darwin_x86_64-1.2.0
  system:     /Users/osako/.nerves/artifacts/nerves_system_rpi0-portable-1.9.0
  app:        /Users/osako/Documents/nerves/hello_nerves

|nerves_bootstrap| Loadpaths End

@zacky1972
Copy link
Collaborator

@fhunleth said:

I assume this is due to calling clang. Nerves provides gcc crosscompilers.

@zacky1972
Copy link
Collaborator

zacky1972 commented Oct 2, 2019

I'll try to use gcc instead of clang.

Does gcc support auto-vectorization...?

@zacky1972
Copy link
Collaborator

gcc may support auto-vectorization by default.
https://www.gnu.org/software/gcc/projects/tree-ssa/vectorization.html

@zacky1972
Copy link
Collaborator

@fhunleth said:

It might be ok to upgrade to gcc 9.2, but I’d have to check again. When I checked a 6 months ago, it wasn’t supported by crosstool-ng.

@zacky1972
Copy link
Collaborator

@osako-ricc Would you test it again, with modifying deps in mix.exs as follows?

      {:pelemay, git: "https://github.com/zeam-vm/pelemay.git", branch: "zacky1972_issue_73"},

@osako-ricc
Copy link
Author

osako-ricc commented Oct 2, 2019

@osako-ricc Would you test it again, with modifying deps in mix.exs as follows?

      {:pelemay, git: "https://github.com/zeam-vm/pelemay.git", branch: "zacky1972_issue_73"},

Following command: mix firmware

VLAN2-dhcp18% mix firmware

Nerves environment
  MIX_TARGET:   rpi0
  MIX_ENV:      dev

==> pelemay
Compiling 10 files (.ex)
Generated pelemay app
==> pelemay_sample
Compiling 2 files (.ex)
armv6-rpi-linux-gnueabi-gcc: error: dynamic_lookup: No such file or directory
armv6-rpi-linux-gnueabi-gcc: error: unrecognized command line option '-femit-all-decls'; did you mean '-fguiding-decls'?

== Compilation error in file lib/pelemay_sample.ex ==
** (MatchError) no match of right hand side value: {"", 1}
    lib/pelemay/generator/builder.ex:52: Pelemay.Generator.Builder.generate/1
    lib/pelemay.ex:51: Pelemay.pelemaystub/2
    expanding macro: Pelemay.defpelemay/1
    lib/pelemay_sample.ex:5: PelemaySample (module)

@zacky1972
Copy link
Collaborator

Thank you for your report.

I guess it occured due to the difference of the compiler options between gcc and clang.

Unfortunately, gcc can't be tested well on Mac.

I'll debug and test it tomorrow

@zacky1972
Copy link
Collaborator

@fhunleth said:

I don’t know if this is possible due to command line parameter differences, but you might be able to replace references to clang with $(CC) when building. Nerves sets CC to the proper crosscompiler when building.

@zacky1972
Copy link
Collaborator

@fhunleth is right.

Due to the difference of compiler option, it causes anothor error.

I'll debug and test on Linux, tomorrow.

@zacky1972
Copy link
Collaborator

zacky1972 commented Oct 3, 2019

@christianjgreen said:

Due to the pragma calls to clang?

@zacky1972
Copy link
Collaborator

I don't know it. Anyway, I found Pelemay must identify which compiler is used, so it can generate or not the pragma.

@zacky1972
Copy link
Collaborator

I guess solving this issue may be so complicated problem because Nerves and Pelemay rely on gcc and clang, respectively.

Thus, I'll try to fix this issue after refactoring of code generation, which is planed on version 0.0.5.

This version up needs so much time and efforts that I may regard this release as version 0.1.0.

@christianjgreen
Copy link
Contributor

Hey there!
I believe I have fixed this issue and would like to contribute my findings.
Here are the steps I took to get Pelemay to compile and run on Nerves.

  1. Remove the flag -femit-all-decls here
  2. Remove the flags defined here as they are more specific to building on macOS(Darwin)
  3. Move the string generation for the name of the NIF from compile time to runtime. This should also fix instances where a build is executed on another machine.

I have committed example changes to a fork: christianjgreen@8afb367

@zacky1972
Copy link
Collaborator

I'll check your patch, soon! Thank you! @christianjgreen

@zacky1972 zacky1972 added this to To do in 0.1.0_old Dec 4, 2019
@zacky1972 zacky1972 moved this from To do to In progress in 0.1.0_old Dec 6, 2019
@zacky1972
Copy link
Collaborator

zacky1972 commented Dec 7, 2019

@christianjgreen We've just tested your code at last!

I modified your code a little because it doesn't work when CC is not set.

We'll test again, on Linux and Nerves. Thank you.

@zacky1972 zacky1972 changed the title Fail mix firmware on Nerves RPi0 with Pelamy ** (Mix) Nerves encountered an error. %IO.Stream{device: :standard_io, line_or_bytes: :line, raw: true} Fail mix firmware on Nerves RPi0 with Pelemay ** (Mix) Nerves encountered an error. %IO.Stream{device: :standard_io, line_or_bytes: :line, raw: true} Dec 7, 2019
@christianjgreen
Copy link
Contributor

Thanks for the update! 🙇

@zacky1972 zacky1972 moved this from In progress to Done in 0.1.0_old Dec 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
No open projects
0.1.0_old
  
Done
Development

No branches or pull requests

3 participants