iden3 / circom

zkSnark circuit compiler
GNU General Public License v3.0
1.28k stars 244 forks source link

Fresh M2 (Apple Silicon) Mac Tutorial Issue regarding: Computing Witness w/ C++ #201

Open adrianmcli opened 1 year ago

adrianmcli commented 1 year ago

When running make at the "Computing the witness with C++" part of the tutorial, I got the following error:

➜  multiplier2_cpp git:(master) ✗ make
g++ -c main.cpp -std=c++11 -O3 -I.
main.cpp:9:10: fatal error: 'nlohmann/json.hpp' file not found
#include <nlohmann/json.hpp>
         ^~~~~~~~~~~~~~~~~~~
1 error generated.
make: *** [main.o] Error 1

I tried to install the noted dependencies (nlohmann-json3-dev, libgmp-dev and nasm) with Brew, but actually had to install the Brew versions instead, which are named a little differently:

brew install nlohmann-json gmp nasm

However, I still ran into the same error as above. I tried a whole bunch of stuff until I found the solution.

It turns out the fix is that I need to do this to add Brew-installed binaries to the path:

export CPLUS_INCLUDE_PATH="$CPLUS_INCLUDE_PATH:/opt/homebrew/include/"

Source of fix: https://stackoverflow.com/questions/43967007/mac-c-include-cannot-find-file-installed-by-homebrew

Hope this saves someone some time and frustration 🥺.

Recommendation

Might be a good idea to update the docs to mention this. I can make a PR if the maintainers agree.

adrianmcli commented 1 year ago

Actually, I encountered more errors. I had to add an extra line to my ~/.zshrc:

export LIBRARY_PATH=$LIBRARY_PATH:$(brew --prefix)/lib
export CPLUS_INCLUDE_PATH="$CPLUS_INCLUDE_PATH:/opt/homebrew/include/"

It progressed further, but I eventually got stuck again. And here is where I am stumped:

1 warning generated.
nasm -fmacho64 --prefix _ fr.asm -o fr_asm.o
g++ -c multiplier2.cpp -std=c++11 -O3 -I.
g++ -o multiplier2 *.o -lgmp
ld: warning: ignoring file fr_asm.o, building for macOS-arm64 but attempting to link with file built for unknown-x86_64
Undefined symbols for architecture arm64:
  "_Fr_copy", referenced from:
      writeBinWitness(Circom_CalcWit*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>) in main.o
      Multiplier2_0_run(unsigned int, Circom_CalcWit*) in multiplier2.o
  "_Fr_mul", referenced from:
      Fr_div(FrElement*, FrElement*, FrElement*) in fr.o
      Multiplier2_0_run(unsigned int, Circom_CalcWit*) in multiplier2.o
  "_Fr_q", referenced from:
      Fr_init() in fr.o
      writeBinWitness(Circom_CalcWit*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>) in main.o
  "_Fr_rawCopy", referenced from:
      RawFr::exp(RawFr::Element&, RawFr::Element const&, unsigned char*, unsigned int) in fr.o
  "_Fr_rawFromMontgomery", referenced from:
      RawFr::toString(RawFr::Element const&, unsigned int) in fr.o
      RawFr::toMpz(__mpz_struct*, RawFr::Element const&) in fr.o
      RawFr::toRprBE(RawFr::Element const&, unsigned char*, int) in fr.o
  "_Fr_rawMMul", referenced from:
      RawFr::inv(RawFr::Element&, RawFr::Element const&) in fr.o
      RawFr::div(RawFr::Element&, RawFr::Element const&, RawFr::Element const&) in fr.o
      RawFr::exp(RawFr::Element&, RawFr::Element const&, unsigned char*, unsigned int) in fr.o
  "_Fr_rawMSquare", referenced from:
      RawFr::exp(RawFr::Element&, RawFr::Element const&, unsigned char*, unsigned int) in fr.o
  "_Fr_rawNeg", referenced from:
      RawFr::RawFr() in fr.o
  "_Fr_rawR3", referenced from:
      RawFr::inv(RawFr::Element&, RawFr::Element const&) in fr.o
      RawFr::div(RawFr::Element&, RawFr::Element const&, RawFr::Element const&) in fr.o
  "_Fr_rawToMontgomery", referenced from:
      RawFr::RawFr() in fr.o
      RawFr::set(RawFr::Element&, int) in fr.o
      RawFr::fromString(RawFr::Element&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, unsigned int) in fr.o
      RawFr::fromUI(RawFr::Element&, unsigned long) in fr.o
      RawFr::fromMpz(RawFr::Element&, __mpz_struct const*) in fr.o
      RawFr::fromRprBE(RawFr::Element&, unsigned char const*, int) in fr.o
  "_Fr_toLongNormal", referenced from:
      writeBinWitness(Circom_CalcWit*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>) in main.o
  "_Fr_toNormal", referenced from:
      Fr_toMpz(__mpz_struct*, FrElement*) in fr.o
      Fr_element2str(FrElement*) in fr.o
      Fr_idiv(FrElement*, FrElement*, FrElement*) in fr.o
      Fr_mod(FrElement*, FrElement*, FrElement*) in fr.o
      Fr_pow(FrElement*, FrElement*, FrElement*) in fr.o
      Fr_inv(FrElement*, FrElement*) in fr.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [multiplier2] Error 1
tarassh commented 1 year ago

@adrianmcli did you overcome this issue?

OBrezhniev commented 1 year ago

@adrianmcli @tarassh Current implementation of c++ witnesscalc uses x86_64 assembly to optimize performance. We have ported assembly parts to arm64 here: https://github.com/0xPolygonID/witnesscalc Plan is to merge this port into mainline and it's WIP, but so far no dates set.

adrianmcli commented 1 year ago

@OBrezhniev thanks for the update! I had skipped that part of the tutorial thus far.

I look forward to closing this issue when the ported code is merged in!

xana-rahmani commented 6 months ago

I noticed that there has been some progress on the porting of the assembly parts to arm64 architecture in the witnesscalc project, as mentioned in the issue. I'm encountering a similar problem and I'm eager to know if the ported code has been merged into the mainline repository since then.

Could you provide an update on the status of this porting effort? Any information on when we can expect the merged code to be available would be greatly appreciated.

Thank you.