shibatch / sleef

SIMD Library for Evaluating Elementary Functions, vectorized libm and DFT
https://sleef.org
Boost Software License 1.0
628 stars 126 forks source link

Weird linker errors that don't make sense #551

Closed ethindp closed 2 months ago

ethindp commented 2 months ago

I'm trying to use this library in a project and I'm getting linker errors like:

error LNK2019: unresolved external symbol __imp_Sleef_sin_u10

When I was originally directly dispatching to functions like Sleef_sind1_u10purecfma or Sleef_sind1_u10purec the errors were similar. I'm not sure what I'm doing wrong; though I built it with vcpkg it doesn't appear to do anything special that would break the library like this. I'm including the library in the linker arguments too:

Linker command line:

link /nologo /NOEXP /NOIMPLIB /OPT:REF /OPT:ICF /ignore:4099 ... sleef.lib Kernel32.lib User32.lib imm32.lib OneCoreUAP.lib dinput8.lib dxguid.lib gdi32.lib ...

Am I doing something wrong?

joanaxcruz commented 2 months ago

Hello. Thanks for reporting this. In order to properly access this issue, could you provide some more information on the conditions where this issue is being generated, namely:

Thanks!

ethindp commented 2 months ago

@joanaxcruz Hi there,

The platform is, as you guessed, Windows. The compiler is MSVC. Architecture is x86-64, and environment is MSVC.

joanaxcruz commented 2 months ago

Thank you for the information above. Our experience is limited for debugging Windows on x86. Could you share the code that is causing this, or provide a small reproducer so we can have a deeper look in this?

ethindp commented 2 months ago

I'm uncertain if any code will work or not. Basically, I'm attempting to use sleef in a game engine. I modified the game engines build file to link to sleef.lib, included sleef.h, then went about exposing these functions to the engines scripting interface. The bug arose whenever I would call any Sleef function. If I tried to call, say, Sleef_sin_u10, I'd get the error. Or if I tried to use run-time CPU detection to dispatch to the Sleef_sind1_u10_purecfma/Sleef_sind1_u10_purec (variants since I'm using v. 3.5.1 until vcpkg can update it to 3.6), I'd get the error that it couldn't find __imp_Sleef_sin_u10/__imp_Sleef_sind1_u10_purecfma/... etc. The project I'm trying to incorporate this into doesn't use CMake, so maybe I screwed something up when linking it, but I don't think I did.

joanaxcruz commented 2 months ago

Hey, In order to understand the root of the issue you're seeing, we will need a bit more information. Can you try isolating the issue on a small example so we can try on our side?

If you could send us the log of running SLEEF config within your project (the lines that follows from running dir build && cmake -S . -B build within sleef repository directory which run Configure.cmake).

Also, could you confirm that:

Thanks and keen to get to the bottom of this.

ethindp commented 2 months ago

@joanaxcruz So, I've tried with version 3.6.1, and I think I've nailed it down. When suing a small CMake project that I threw together today, using cpm.cmake, I use the following configuration:

file(
  DOWNLOAD
  https://github.com/cpm-cmake/CPM.cmake/releases/download/v0.38.3/CPM.cmake
  ${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake
  EXPECTED_HASH SHA256=cc155ce02e7945e7b8967ddfaff0b050e958a723ef7aad3766d368940cb15494
)
include(${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake)
CPMAddPackage(
    NAME sleef
    VERSION 3.6.1
    GITHUB_REPOSITORY "shibatch/sleef"
    GIT_TAG 3.6.1
    OPTIONS
        "SLEEF_BUILD_SHARED_LIBS OFF"
        "SLEEF_BUILD_STATIC_TEST_BINS OFF"
        "SLEEF_ENABLE_LTO ON"
        "SLEEF_BUILD_LIBM ON"
        "SLEEF_BUILD_DFT ON"
        "SLEEF_BUILD_QUAD ON"
        "SLEEF_BUILD_GNUABI_LIBS ON"
        "SLEEF_BUILD_SCALAR_LIB ON"
        "SLEEF_BUILD_TESTS OFF"
        "SLEEF_ENABLE_CXX ON"
)
target_include_directories(${PROJECT_NAME} PRIVATE ${sleef_BINARY_DIR}/include)
target_link_libraries(${PROJECT_NAME} PRIVATE sleef sleefdft sleefquad)

Something very interesting happens. When I do the following:

file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp")

# ---- Create library ----
add_library(${PROJECT_NAME} SHARED ${headers} ${sources})
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 20)

# being a cross-platform target, we enforce standards conformance on MSVC
target_compile_options(${PROJECT_NAME} PUBLIC "$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/permissive->")

I get the same linker errors:

[ 95%] Linking CXX shared library fast.dll
LINK Pass 1: command "C:\PROGRA~1\MICROS~1\2022\ENTERP~1\VC\Tools\MSVC\1439~1.335\bin\HostX64\x64\link.exe /nologo @CMakeFiles\fast.dir\objects1.rsp /out:fast.dll /implib:fast.lib /pdb:C:\Users\Ethin\source\plugins\fast\build\fast.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL vcpkg_installed\x64-windows-static\debug\lib\scn.lib vcpkg_installed\x64-windows-static\debug\lib\llfio_sl-2.0-Windows-AMD64-Debug.lib vcpkg_installed\x64-windows-static\debug\lib\af.lib vcpkg_installed\x64-windows-static\debug\lib\afcpu.lib vcpkg_installed\x64-windows-static\debug\lib\afopencl.lib vcpkg_installed\x64-windows-static\debug\lib\PocoFoundationmtd.lib _deps\sleef-build\lib\sleef.lib _deps\sleef-build\lib\sleefdft.lib _deps\sleef-build\lib\sleefquad.lib vcpkg_installed\x64-windows-static\debug\lib\simdutf.lib ws2_32.lib vcpkg_installed\x64-windows-static\debug\lib\pcre2-8d.lib vcpkg_installed\x64-windows-static\debug\lib\zlibd.lib iphlpapi.lib _deps\sleef-build\lib\sleef.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\fast.dir/intermediate.manifest CMakeFiles\fast.dir/manifest.res" failed (exit code 1120) with the following output:
   Creating library fast.lib and object fast.exp
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_sin_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_cos_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_tan_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_asin_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_acos_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_atan_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_atan2_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_log_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_cbrt_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_exp_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_pow_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_sinh_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_cosh_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_tanh_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
simd.cpp.obj : error LNK2019: unresolved external symbol __imp_Sleef_asinh_u10 referenced in function "void __cdecl register_simd_elementary_functions(class asIScriptEngine *)" (?register_simd_elementary_functions@@YAXPEAVasIScriptEngine@@@Z)
...

However, when I remove SHARED from add_library, it links fine (but commenting out the line for shared libraries for Sleef doesn't fix the problem). I'm extremely confused.

I am using a 64-bit windows environment. The library is being linked statically, and BUILD_SHARED_LIBS for sleef is off. The configure log (at least, for tryign to build sleef as shared, but static should be very similar) is (linking against vcpkg libraries):

-- CPM: Adding package sleef@3.6.1 (3.6.1)
-- The C compiler identification is MSVC 19.39.33523.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/MSVC/14.39.33519/bin/HostX64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY OPENSSL_INCLUDE_DIR)
-- Looking for sys/types.h
-- Looking for sys/types.h - found
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Looking for stddef.h
-- Looking for stddef.h - found
-- Check size of long double
-- Check size of long double - done
-- Performing Test COMPILER_SUPPORTS_FLOAT128
-- Performing Test COMPILER_SUPPORTS_FLOAT128 - Failed
-- Performing Test COMPILER_SUPPORTS_SSE2
-- Performing Test COMPILER_SUPPORTS_SSE2 - Success
-- Performing Test COMPILER_SUPPORTS_SSE4
-- Performing Test COMPILER_SUPPORTS_SSE4 - Success
-- Performing Test COMPILER_SUPPORTS_AVX
-- Performing Test COMPILER_SUPPORTS_AVX - Success
-- Performing Test COMPILER_SUPPORTS_FMA4
-- Performing Test COMPILER_SUPPORTS_FMA4 - Success
-- Performing Test COMPILER_SUPPORTS_AVX2
-- Performing Test COMPILER_SUPPORTS_AVX2 - Success
-- Performing Test COMPILER_SUPPORTS_AVX512F
-- Performing Test COMPILER_SUPPORTS_AVX512F - Success
-- Found OpenMP_C: -openmp (found version "2.0")
-- Found OpenMP_CXX: -openmp (found version "2.0")
-- Found OpenMP: TRUE (found version "2.0")
-- Performing Test COMPILER_SUPPORTS_OPENMP
-- Performing Test COMPILER_SUPPORTS_OPENMP - Success
-- Performing Test COMPILER_SUPPORTS_OMP_SIMD
-- Performing Test COMPILER_SUPPORTS_OMP_SIMD - Failed
-- Performing Test COMPILER_SUPPORTS_WEAK_ALIASES
-- Performing Test COMPILER_SUPPORTS_WEAK_ALIASES - Failed
-- Performing Test COMPILER_SUPPORTS_BUILTIN_MATH
-- Performing Test COMPILER_SUPPORTS_BUILTIN_MATH - Failed
-- Performing Test COMPILER_SUPPORTS_SYS_GETRANDOM
-- Performing Test COMPILER_SUPPORTS_SYS_GETRANDOM - Failed
CMake Warning (dev) at build/_deps/sleef-src/src/libm/CMakeLists.txt:1004 (install):
  Target sleefscalar has PUBLIC_HEADER files but no PUBLIC_HEADER
  DESTINATION.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Unroll target for DP : unroll_0_purecdp.c;unroll_2_purecdp.c;unroll_0_sse2dp.c;unroll_2_sse2dp.c;unroll_0_avxdp.c;unroll_2_avxdp.c;unroll_0_avx2dp.c;unroll_2_avx2dp.c;unroll_0_avx512fdp.c;unroll_2_avx512fdp.c
-- Unroll target for SP : unroll_0_purecsp.c;unroll_2_purecsp.c;unroll_0_sse2sp.c;unroll_2_sse2sp.c;unroll_0_avxsp.c;unroll_2_avxsp.c;unroll_0_avx2sp.c;unroll_2_avx2sp.c;unroll_0_avx512fsp.c;unroll_2_avx512fsp.c
-- Configuring build for SLEEF-v3.6.1
   Target system: Windows-10.0.19044
   Target processor: AMD64
   Host system: Windows-10.0.19044
   Host processor: AMD64
   Detected C compiler: MSVC @ C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/MSVC/14.39.33519/bin/HostX64/x64/cl.exe
   CMake: 3.28.3-msvc11
   Make program: nmake
-- Using option `/D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_DEPRECATE  ` to compile libsleef
-- Building shared libs : OFF
-- Building static test bins: OFF
-- MPFR : LIB_MPFR-NOTFOUND
-- GMP : LIBGMP-NOTFOUND
-- RT :
-- FFTW3 : LIBFFTW3-NOTFOUND
-- OPENSSL :
-- SDE : SDE_COMMAND-NOTFOUND
-- COMPILER_SUPPORTS_OPENMP : FALSE
-- Configuring done (75.9s)
-- Generating done (1.0s)
-- Build files have been written to: C:/Users/Ethin/source/plugins/fast/build
ethindp commented 2 months ago

Uh, okay... I think I figured out the problem.... Apparently I need to define SLEEF_STATIC_LIBS. After I did that it works perfefctly.