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

StdFill not defined in CxxWrap.StdLib #455

Open
peremato opened this issue Oct 7, 2024 · 9 comments
Open

StdFill not defined in CxxWrap.StdLib #455

peremato opened this issue Oct 7, 2024 · 9 comments

Comments

@peremato
Copy link

peremato commented Oct 7, 2024

I am trying to re-generate the wrappers for XRootD.jl with version v0.16.0 of CxxWrap and version v0.13.2 of libcxxwrap_julia_jll. I can build successfully the wrapper library, but when initialising I get the error:

julia> using XRootD
Precompiling XRootD...
Info Given XRootD was explicitly requested, output will be shown live 
ERROR: LoadError: UndefVarError: `StdFill` not defined in `CxxWrap.StdLib`
Stacktrace:
  [1] getproperty(x::Module, f::Symbol)
    @ Base ./Base.jl:42
  [2] top-level scope
    @ none:1
  [3] eval
    @ ./boot.jl:430 [inlined]
  [4] wrap_functions(functions::Vector{CxxWrap.CxxWrapCore.CppFunctionInfo}, julia_mod::Module)
    @ CxxWrap.CxxWrapCore ~/.julia/packages/CxxWrap/eWADG/src/CxxWrap.jl:773
  [5] wrapfunctions(jlmod::Module)
    @ CxxWrap.CxxWrapCore ~/.julia/packages/CxxWrap/eWADG/src/CxxWrap.jl:790
...

Any idea of what could be the problem? Thanks.

julia> versioninfo()
Julia Version 1.11.0-rc4
Commit b4b9add84db (2024-09-25 11:03 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: macOS (arm64-apple-darwin22.4.0)
  CPU: 8 × Apple M2
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, apple-m2)
Threads: 1 default, 0 interactive, 1 GC (on 4 virtual cores)
Environment:
  JULIA_PROJECT = @.
@barche
Copy link
Collaborator

barche commented Oct 7, 2024

This looks like a possible version mismatch, can you check with CxxWrap.libcxxwrapversion() that this is using the correct libcxxwrap? Maybe also verify with Libdl.dllist() that no wrong library gets pulled in.

@peremato
Copy link
Author

peremato commented Oct 8, 2024

Thanks for the reply. I do not see it. Everything looks fine for me (I reverted to julia 1.10 just to check):

julia> using CxxWrap
julia> CxxWrap.libcxxwrapversion()
v"0.13.2"

julia> using Libdl
julia> for l in Libdl.dllist();occursin("cxxwrap",lowercase(l)) && println(l);end
/Users/mato/.julia/compiled/v1.10/libcxxwrap_julia_jll/9VnAb_b2u6u.dylib
/Users/mato/.julia/artifacts/a733004dc3a6d098fcb468930d1084d8fea63e5e/lib/libcxxwrap_julia.0.13.2.dylib
/Users/mato/.julia/artifacts/a733004dc3a6d098fcb468930d1084d8fea63e5e/lib/libcxxwrap_julia_stl.dylib
/Users/mato/.julia/compiled/v1.10/CxxWrap/WGIJU_b2u6u.dylib

The only possibility I see is that JLCXX_HAS_RANGES is not defined for MacOS when building the libcxxwrap_julia_jll . See https://github.com/JuliaInterop/libcxxwrap-julia/blob/587f9feb6b64baa512856af2d508fec1f63583bc/include/jlcxx/stl.hpp#L175

@peremato
Copy link
Author

peremato commented Oct 8, 2024

The problem is that for MacOS the compiler used is clang++ and does not support <ranges> therefore the define JLCXX_HAS_RANGES is false.

# /opt/bin/aarch64-apple-darwin20-libgfortran5-cxx11-julia_version+1.10.0/aarch64-apple-darwin20-clang++ -std=c++20 a.cpp
a.cpp:2:10: fatal error: 'ranges' file not found
    2 | #include <ranges>
      |          ^~~~~~~~
1 error generated.

Perhaps @giordano has an idea on how this can be overcome.

@giordano
Copy link

giordano commented Oct 8, 2024

ranges may require a much newer SDK (13?): JuliaPackaging/Yggdrasil#8613 (comment)

@barche
Copy link
Collaborator

barche commented Oct 8, 2024

Ah yes, good catch, it is because of the #ifdef JLCXX_HAS_RANGES. Easiest solution I can think of is to expose a jlcxx_has_ranges function from libcxxwrap-julia and use that as a condition to use StdFill on the Julia side in CxxWrap. Upgrading the SDK on Yggdrasil is not enough I seem to remember, we need to upgrade the compiler itself.

@peremato
Copy link
Author

Any estimate when the easiest solution would be implemented?

@peremato
Copy link
Author

@barche I was trying to see whether I could provide a quick fix to avoid this problem, since I am stuck on it and cannot make problem on my side. In a very naive reasoning: If ranges are not supported we could do the loop explicitly. But this is not working. Indeed there are few things I do not understand:

  • The method StdfFill is defined in the wrapper library llibcxxwrap_julia_jll when C++ ranges are available. The only reference I found of StdFill is in StdLib.jl, which could be easily protected with:
function Base.fill!(v::T, x) where T <: Union{StdVector, StdValArray, StdDeque}
  if isdefined(StdLib, :HAS_RANGES) && StdLib.HAS_RANGES == 1
    StdFill(v, x)
  else
    for i in 1:length(v)
      v[i] = x
    end
  end
  return v
end
  • This is not sufficient. The problem happens when loading my wrapper library, which uses some std::vector types in some arguments of methods.
  • What I do not understand is where the reference to the method StdFill is in my wrapper library. I didn't see it explicitly mentioned. Sure I am using std::vectors and I guess is instantiated with the needed element type, but where is StdFill used?
    Can you please put some light on this? Thanks.

@barche
Copy link
Collaborator

barche commented Oct 30, 2024

Does simply commenting out the call to StdFill in StdLib.jl solve it? I'm currently reworking the way STL wrappers are defined on the C++ side, so hopefully I can include a fix for this too.

@peremato
Copy link
Author

Commenting the call in StdLib.jl does not help. Indeed, the problem is at loading time when the functions are being wrap.

But I know now what the problem is. When the llibcxxwrap_julia_jll was built with BinaryBuilder, ranges was not supported, but when I am building my wrapper library for my package locally before I added to Yggdrasil where I am using a newer compiler ranges are supported. Therefore my wrapped library expects to find the method StdFill defined and is not. The quick solution for me would be add the following lines in my wrapper code:

// BinaryBuilder uses old SDK which doesn't have ranges
#ifdef __APPLE__
    #undef JLCXX_HAS_RANGES
#endif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants