The latest attempt building NSIS for WoA using MSYS2 CLANGARM64 fails w/
scons: *** [build/urelease/System/unicode/Source/Call-arm64CPP.o] Source `Contrib/System/Source/Call-arm64CPP.S' not found, needed by target `build/urelease/System/unicode/Source/Call-arm64CPP.o'.
scons: building terminated because of errors.
due to missing assembly.
Also, please feel to upstream any of the patches so far.
This is also related to Clang support in general: https://sourceforge.net/p/nsis/feature-requests/570/
The arm64 assembly file for the system plugin is missing because noone has written one yet. The amd64 assembly file is only half complete, it doesn't support callbacks which need to be implemented. You can use SKIPPLUGINS="System" to get past this error.
I took a quick look at all the patches, and there are a few things to note:
Thanks for having a go at supporting another system. Last time I tried a WoA build, it was with MSVC and most of the tools worked but the installers did not work. So let us know if you do manage to get the installers themselves to work.
Thanks for the feedback. It would be great to add as much you think makes sense now to ease experimenting on this platform.
mingw-w64 no longer implies the GCC toolchain exclusively, as LLVM-MinGW (basis for the MSYS2 CLANGARM64 environment ) is the only viable (non-MSVC) WoA option until GCC 15 arrives:
https://www.mingw-w64.org/downloads/#llvm-mingw
https://www.phoronix.com/news/GCC-aarch64-w64-mingw32
I don't know SCons at all, but I wish it could be as flexible leveraging all of these toolchains on Windows as e.g. CMake is seamlessly able to.
Last edit: Milos Komarcevic 2024-05-30
I'm sorry to hear this. C++11 and following can be threatening but the net benefit is fantastic.
nsExecdoes not interoperate with, for instanceC:\Windows\System32\netsh.exeas it currently stands. I believe this can be fixed by (TIMEOUT=0on the Exec callI've written our own extension that successfully calls CreateProcess, where using stock nsExec on netsh does not. A workaround like the above would be very welcome indeed
64-bit netsh related report here. It is not supposed to use the DLL thing when running 32-bit NSIS on 64-bit Windows. I don't even remember why the DLL thing exists.
Thanks for the reply @anders_k! I was wondering if I had chosen a too-stale thread to reply to.
We are using amd64-unicode (which I didn't explicitly state before -- sorry), so 32-bit NSIS doesn't enter into this, right?
What I do know is that my extension dll that calls
CreateProcessdirectly works,nsExec::ExecToLogfails to launch netsh on Windows-on-ARM.I also know that
C:\Windows\System32\netsh.exeon a Windows-on-ARM system is, despite the misleading name of its location, an Aarch64 executable.Also, looking back through the history, I didn't see a drop-dead reason for the multi-layered
CreateProcesscall was being done. It strikes me as conceivable that it was a way to thunk between 32-bit and 64-bit environments in pre-win2k or Windows95 timeframes?Is there something else I'm missing? tia...
Last edit: Arthur Klassen 2024-10-30
For part 1, I assume the fix is going to change
if (!IsWOW64()) {toif (sizeof(void*) < 8 && !IsWOW64()) {.As for the timeout, I don't really understand why you would need TIMEOUT=0 because 0 is already the default. If you don't do this, does it respond with "timeout" on the stack after nsExec::Exec?
Anders...
I don't know what the right patch is, exactly, in
nsExec. All I know for sure is thatnetsh(and possibly other tools) to reliably launch fromnsExec::Exec*methods WHEN we have generated an amd64-unicode installer and we are running it on Windows-on-ARM.netshto run from our own DLL that callsCreateProcessdirectly on the tool we want to run.Currently, we are relying on our DLL to launch our tool but if
nxExecwere to run correctly again, we would prefer to use that. I don't know whether the fix is:CreateProcess-- and I don't understand what the double launch is getting when a TIMEOUT is not involved. I suspectd the double launch is being done regardless to keep the code path consistent, so maybe NOT do the doubleCreateProcesswhen timeout is 0?nsExec.dllto some WoW-directory before doing the first of the twoCreateProcesscalls. I don't know what the ARM64 analog for that is at all.We can't possibly be the only ones who will ever bump into this and given that compiling an ARM64-NSIS framework is not on yet either, it would be to others' benefit at all to have a clear path forward, no?
If you don't know which is the right approach, we will be using our own DLL and will add the stdout capture that we've come to rely on from nsexec for ourselves.
If you DO have some idea what the right approach is, I am willing to create a patch to submit back to you around that work when I get it done.
Did you try changing nsExec with my suggestion above?
Hey Anders... the patch you suggested did the trick. We'll patch the version of nsExec.dll we're using for the moment and will look forward to consuming the REAL version when it gets rolled into an official release.
Thanks for your patience with my failure-to-grok. ...ank
FWIW, I independently debugged this (before I saw this report) in my own NSIS 3.10 based installer, and the specific problem with relaunching on ARM64 is the fact that the code is overwriting the IMAGE_FILE_LARGE_ADDRESS_AWARE flag on the new binary (which was present in the original NsExec.dll).
If you enable loader snaps on the temporary binary using gflags.exe, you will see the following:
If I manually modify the PE header of the dropped binary to restore the IMAGE_FILE_LARGE_ADDRESS_AWARE flag, the binary loads properly. I know it doesn't really matter anymore after r7445, but I thought I'd post it anyway since it wasn't trivial to debug why NsExec was silently broken on ARM64.
Are you saying no 64-bit executables without IMAGE_FILE_LARGE_ADDRESS_AWARE set can run on ARM64?
We don't actually need a large address space for a program that is a simple one function thing but setting the flag would not hurt.
I did not parse that as a "try nsexec.dll with this change", so I did not try it. sorry. will give it a shot.
I super second this. Nsis already builds with Clang (just see the CLANG64 builds by MSYS).
I can help testing the ARM64 , changes and builds. Right now I'm hitting:
While building in the CLANGARM64 environment
The ARM64 assembly file has not been written yet. There is some code in system.c that is supposed to let you build a minimal version that lets MUI2 work (but not generic System::Call) but I don't remember off the top of my head how exactly you get that to happen. Perhaps if you create a Call-arm64CPP.S file with just the word END in it (or .end if clang uses GCC syntax)?
scons SKIPPLUGINS=system ... if you want to skip this plug-in completely.