herumi / mcl

a portable and fast pairing-based cryptography library
BSD 3-Clause "New" or "Revised" License
450 stars 151 forks source link

Undefined symbols link with libmcl.a on Mac M1 #168

Closed levyfan closed 1 year ago

levyfan commented 1 year ago

Hi, I come with Undefined symbols error when including mcl static libs in my project.

Undefined symbols for architecture arm64:
  "_mcl_fpDbl_add3L", referenced from:
      mcl::fp::Op::init(mcl::VintT<mcl::vint::FixedBuffer> const&, unsigned long, int, mcl::fp::Mode, unsigned long) in libmcl.a(fp.cpp.o)
  "_mcl_fpDbl_add4L", referenced from:
      mcl::fp::Op::init(mcl::VintT<mcl::vint::FixedBuffer> const&, unsigned long, int, mcl::fp::Mode, unsigned long) in libmcl.a(fp.cpp.o)
  "_mcl_fpDbl_add6L", referenced from:
      mcl::fp::Op::init(mcl::VintT<mcl::vint::FixedBuffer> const&, unsigned long, int, mcl::fp::Mode, unsigned long) in libmcl.a(fp.cpp.o)
...

I find that these symbols is defined in libmcl.dylib but not in libmcl.a

Q4T9J22DT6:lib levyfan$ nm libmcl.a | grep mcl_fpDbl_add
                 U _mcl_fpDbl_add3L
                 U _mcl_fpDbl_add4L
                 U _mcl_fpDbl_add6L
                 U _mcl_fpDbl_add8L
Q4T9J22DT6:lib levyfan$ nm libmcl.dylib | grep mcl_fpDbl_add
0000000000022964 T _mcl_fpDbl_add3L
0000000000023498 T _mcl_fpDbl_add4L
0000000000024a10 T _mcl_fpDbl_add6L
000000000002706c T _mcl_fpDbl_add8L

I include mcl by cmake ExternalProject_Add just as:

ExternalProject_Add(mcl
        PREFIX mcl
        GIT_REPOSITORY https://github.com/herumi/mcl.git
        GIT_TAG v1.74
        GIT_SHALLOW 1
        DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
        BUILD_BYPRODUCTS ${mcl_STATIC_LIBRARIES}
        SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/mcl/src/mcl
        CMAKE_ARGS
        -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
        -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/mcl
        -DMCL_STATIC_LIB=ON
        )

I would like to only build with mcl static libs. Any ideas?

levyfan commented 1 year ago

I guess the cmake build might be broken. When I build mcl by makefile, the output libmcl.a is OK.

Q4T9J22DT6:lib levyfan$  nm libmcl.a | grep mcl_fpDbl_add
                 U _mcl_fpDbl_add3L
                 U _mcl_fpDbl_add4L
                 U _mcl_fpDbl_add6L
                 U _mcl_fpDbl_add8L
0000000000000c00 T _mcl_fpDbl_add3L
0000000000001740 T _mcl_fpDbl_add4L
0000000000002cc8 T _mcl_fpDbl_add6L
0000000000005338 T _mcl_fpDbl_add8L
herumi commented 1 year ago

Thank you for the report. I verified the results.

herumi commented 1 year ago

mcl_fpDbl* are in ${BASE_OBJ} and mclb_* are in ${BINT_OBJ}. I use target_link_libraries(mcl_st PUBLIC ${BINT_OBJ}) and target_link_libraries(mcl_st PUBLIC ${BASE_OBJ}) but they are not linked. If you know, could you please tell me what to do?

levyfan commented 1 year ago

I have checked 2 link.txt produced by cmake and mcl_st seems not be linked with bint64.o base64.o

$ cat CMakeFiles/mcl.dir/link.txt 
/Library/Developer/CommandLineTools/usr/bin/c++  -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.0.sdk -dynamiclib -Wl,-headerpad_max_install_names -compatibility_version 1.0.0 -current_version 1.74.0 -o lib/libmcl.1.74.dylib -install_name @rpath/libmcl.1.dylib CMakeFiles/mcl.dir/src/fp.cpp.o  bint64.o base64.o 
$ cat CMakeFiles/mcl_st.dir/link.txt 
/Library/Developer/CommandLineTools/usr/bin/ar qc lib/libmcl.a CMakeFiles/mcl_st.dir/src/fp.cpp.o
/Library/Developer/CommandLineTools/usr/bin/ranlib lib/libmcl.a

but no idea how to make it work.

herumi commented 1 year ago

Yes, I know that mcl.dir/link.txt links bint64.o and base64.o but mcl_st.dir/link.txt does not. I don't know why target_link_libraries works for a shared library but does not for a static library.

herumi commented 1 year ago

Using target_sources seems to be good. Could you try it? https://github.com/herumi/mcl/commit/ade06eac68ee3d8f897885e0c8c16d8a241d52b0

levyfan commented 1 year ago

Yes that is ok

herumi commented 1 year ago

Thank you for the quick response.