Closed PieroV closed 2 months ago
Please also note https://github.com/corrosion-rs/corrosion/pull/546 and my comments there. Specifically I'm interested in
gnullvm
?*-gnu
and linking a Rust library compiled for gnullvm
sound?IMPLIB
? How does CMake handle that?If I understand correctly, this command is run in corrosion/required_libs, but it fails for me:
The command corrosion runs has an additional --
before the --print
. The cargo flag is unstable, but the rustc
flag is stable, and those are separated by a --
.
> cargo rustc --verbose --color never --target=<triple> -- --print=native-static-libs
Could you rerun this command with the --
and report the output? Please also note that configuring CMake in debug mode will also provide additional helpful output (cmake -S<source_dir> -B<build_dir> --log-level=DEBUG <your_other_options>
)
ws2_32;ntoskrnl;userenv
Are these libraries also required for a minimal hello world example? If not, then it's likely that these libraries are added by dependencies (which probably report that they need to link to a library via a build-script). Such libraries missing is a known limitation of Corrosion, that needs upstream CMake additions to fix reliably.
Thanks for the prompt answer! I tried to look for issues but I missed a PR was already existing, sorry!
Please also note #546 and my comments there. Specifically I'm interested in
- What are the Clang / CMake compiler targets, which corresponds to Rusts
gnullvm
?
Clang and CMake use x86_64-pc-windows-gnu
also for this target.
Clang manages to find the correct runtime libraries by itself when they are in their appropriate directory.
The reference for creating an all-LLVM mingw pipeline is this repository.
- Is using gcc to compile for
*-gnu
and linking a Rust library compiled forgnullvm
sound?
I have never tried. The main problems might be with unwinding, but I believe it's sort of expected not to work over FFI boundaries. Usually LLVM runtimes are made to be ABI compatible with GNU. FWIW, Firefox has been doing the opposite for years (use an LLVM-based mingw on the C/C++ side and the GNU target on Rust) in their tier 2 target (the official binaries are Clang/msvc, but the CI builds also for mingw).
- Why is there no
IMPLIB
? How does CMake handle that?
Sorry, I don't know what you're talking about :sweat_smile:. However I've been using an LLVM based toolchain for a while, and I've never had to change anything that sounds like this (usually, if something supports GCC+mingw, it also works out of the box with Clang).
I've seen in the PR IMPLIB has been set to empty for the gnullvm target.
I set it to the same as GNU in my test.
As far as I know, the main difference between gnu
and gnullvm
are the runtime (libcompilerrt
+ libunwind
instead of libgcc_s
), but the rest of the tooling is the same.
If I understand correctly, this command is run in corrosion/required_libs, but it fails for me:
The command corrosion runs has an additional
--
before therustc
flag is stable, and those are separated by a--
.> cargo rustc --verbose --color never --target=<triple> -- --print=native-static-libs
Could you rerun this command with the
--
and report the output? Please also note that configuring CMake in debug mode will also provide additional helpful output (cmake -S<source_dir> -B<build_dir> --log-level=DEBUG <your_other_options>
)
Yeah, sorry, I somehow missed that!
> cargo rustc --verbose --color never --target=x86_64-pc-windows-gnullvm -- --print=native-static-libs
Compiling required_libs v0.1.0 (/home/piero/sdem/build/corrosion/required_libs)
Running `rustc --crate-name required_libs --edition=2018 lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=282 --crate-type staticlib --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 --print=native-static-libs -C metadata=869712cafa1f4636 -C extra-filename=-869712cafa1f4636 --out-dir /home/piero/sdem/build/corrosion/required_libs/target/x86_64-pc-windows-gnullvm/debug/deps --target x86_64-pc-windows-gnullvm -C incremental=/home/piero/sdem/build/corrosion/required_libs/target/x86_64-pc-windows-gnullvm/debug/incremental -L dependency=/home/piero/sdem/build/corrosion/required_libs/target/x86_64-pc-windows-gnullvm/debug/deps -L dependency=/home/piero/sdem/build/corrosion/required_libs/target/debug/deps`
note: Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
note: native-static-libs: -lkernel32 -ladvapi32 -lkernel32 -lntdll -luserenv -lws2_32 -lkernel32 -lws2_32 -lkernel32 -lunwind
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
ws2_32;ntoskrnl;userenv
Are these libraries also required for a minimal hello world example? If not, then it's likely that these libraries are added by dependencies (which probably report that they need to link to a library via a build-script). Such libraries missing is a known limitation of Corrosion, that needs upstream CMake additions to fix reliably.
IIRC, they were needed by something like std::sys::
, but I will try again later.
Thanks again for your answer!
ws2_32;ntoskrnl;userenv
Are these libraries also required for a minimal hello world example? If not, then it's likely that these libraries are added by dependencies (which probably report that they need to link to a library via a build-script). Such libraries missing is a known limitation of Corrosion, that needs upstream CMake additions to fix reliably.
IIRC, they were needed by something like
std::sys::
, but I will try again later.Thanks again for your answer!
I setup a new project.
Instead of using FetchContent
, I cloned corrosion and applied my patch before running CMake:
diff --git a/cmake/Corrosion.cmake b/cmake/Corrosion.cmake
index 3ad5bc1..f5132ea 100644
--- a/cmake/Corrosion.cmake
+++ b/cmake/Corrosion.cmake
@@ -355,7 +355,7 @@ function(_corrosion_add_library_target)
set(is_windows TRUE)
if(Rust_CARGO_TARGET_ENV STREQUAL "msvc")
set(is_windows_msvc TRUE)
- elseif(Rust_CARGO_TARGET_ENV STREQUAL "gnu")
+ elseif(Rust_CARGO_TARGET_ENV STREQUAL "gnu" OR Rust_CARGO_TARGET_ENV STREQUAL "gnullvm")
set(is_windows_gnu TRUE)
endif()
elseif(Rust_CARGO_TARGET_OS STREQUAL "darwin")
At that point, Corrosion found the needed libraries correctly:
> cmake .. -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=x86_64-w64-mingw32-clang -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-clang++ -DRust_CARGO_TARGET=x86_64-pc-windows-gnullvm
-- Determining required link libraries for target x86_64-pc-windows-gnullvm
-- Required static libs for target x86_64-pc-windows-gnullvm: kernel32;advapi32;kernel32;ntdll;userenv;ws2_32;kernel32;ws2_32;kernel32;unwind
-- Required link flags for target x86_64-pc-windows-gnullvm:
-- Determining required link libraries for target x86_64-unknown-linux-gnu
-- Required static libs for host target x86_64-unknown-linux-gnu: gcc_s;util;rt;pthread;m;dl;c
-- Found Rust: /var/tmp/dist/rust/bin/rustc (found version "1.78.0")
-- The C compiler identification is Clang 18.1.5
-- The CXX compiler identification is Clang 18.1.5
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /var/tmp/dist/mingw-w64-clang/bin/x86_64-w64-mingw32-clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /var/tmp/dist/mingw-w64-clang/bin/x86_64-w64-mingw32-clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/piero/hello/build
ntoskrnl
hasn't been added, but I guess something else is linking to it, or somehow providing the features for which I initially linked it and I can't replicate the error I had in the hello project.
As for the implib, Cmake generates indeed a libxyz.dll.a
,
So, I tried to run cargo directly with cdylib
instead of staticlib
, and it generated it as well, but in the deps
directory.
In particular, it generated these files:
CMAKE_SHARED_LIBRARY_PREFIX
).And Corrosion doesn't find the implib:
[ 0%] Built target cargo-prebuild_hello_rs
Compiling hello_rs v0.1.0 (/home/piero/hello/hello_rs)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s
Copying byproducts `libhello_rs.dll.a` to /home/piero/hello/build
Error copying file (if different) from "/home/piero/hello/build/./cargo/build/x86_64-pc-windows-gnullvm/debug/libhello_rs.dll.a" to "/home/piero/hello/build".
make[2]: *** [CMakeFiles/_cargo-build_hello_rs.dir/build.make:76: _cargo-build_hello_rs] Error 1
make[1]: *** [CMakeFiles/Makefile2:107: CMakeFiles/_cargo-build_hello_rs.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
Copying to the directory it expects resolved the problem. However, I also tried to create an example program that links to the DLL without the .a, and it works as well.
As for the implib, Cmake generates indeed a libxyz.dll.a, So, I tried to run cargo directly with cdylib instead of staticlib, and it generated it as well, but in the deps directory. In particular, it generated these files:
target/x86_64-pc-windows-gnullvm/debug/deps/libhello_rs.dll.a
Thanks a lot for testing. I believe probably cargo needs a patch to copy the implib to the same location (as I don't want to start digging into the deps
directory). I don't really know what I'm doing, but I gave it a shot in https://github.com/rust-lang/cargo/pull/14451 and hope that it is sufficient.
Thanks a lot for testing. I believe probably cargo needs a patch to copy the implib to the same location (as I don't want to start digging into the
deps
directory).
Makes sense.
I don't really know what I'm doing, but I gave it a shot in rust-lang/cargo#14451 and hope that it is sufficient.
Great, and it's already been merged approved!
gnullvm is a fairly new target (it's been raised from tier 3 to tier 2 without host tools quite recently), so it probably needs some refinements.
I have a draft PR which adds gnullvm
to CI, but it looks like there are also other problems besides the implib issue:
https://github.com/corrosion-rs/corrosion/pull/553
If someone has time to investigate, or knows what additional setup might be needed, I'd be glad for any comments.
Fixed in #553
Hi! Thanks for this project, it's very nice.
I tried it with the
x86_64-pc-windows-gnullvm
target, which is very similar tox86_64-pc-windows-gnu
but uses only LLVM tools. It worked almost out of the box, but I had to change this line inCorrosion.cmake
:(I had to add the
OR Rust_CARGO_TARGET_ENV STREQUAL "gnullvm"
part).In addition to that, I had to manually pass these variables to cmake:
I would be happy to open a PR to support it officially, if this could be helpful to someone else, but I don't know where the initial value of the native libraries is set (for me it was
gcc_s;util;rt;pthread;m;dl;c
, which matches my host libraries, but I'm cross compiling).If I understand correctly, this command is run in
corrosion/required_libs
, but it fails for me:Also, I'd need some help for writing any needed tests.