Building libffi for Windows ARM64 with Visual C++
The previous post covered Building libffi for Windows x64 with Visual C++. In this post, I detail the instructions needed to build for the ARM64 platform (building the zero variant of the HotSpot JVM for the Windows ARM64 platform was my overall objective). I used the same Windows x64 machine for this build. As in the previous post, Visual C++ and MSYS are prerequisites. Get the sources from GitHub:
cd /c/repos
git clone https://github.com/libffi/libffi.git
cd libffi
git checkout v3.4.8
MSYS Prerequisites
Launch MSYS2 and install automake and libtool using these commands:
pacman -S automake
pacman -S libtool
The Visual C++ compiler needs to be available in the path as well. Run cl
without any parameters to ensure the compiler is available. If it is available, it must be the ARM64 compiler to ensure we cross-compile! It most likely won’t be by default. If it isn’t, add it to the path as follows:
export PATH="$PATH:/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/bin/Hostx64/arm64/"
Generating the configure file
With the MSYS prerequisites installed, run the autogen.sh script:
user@machine /d/repos/libffi
$ ./autogen.sh
This creates a configure script in the root of the repository. Run it using bash. This command is the main difference between ARM64 and x86_64. Notice that I need to specify various include paths for the ARM64 compiler and linker that were not required in the x86_64 case.
export INCLUDE_PATH_ucrt=/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt
export INCLUDE_PATH_um=/c/progra~2/wi3cf2~1/10/include/100226~1.0/um
export INCLUDE_PATH_shared=/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared
export INCLUDE_PATH_MSVC=/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include
time bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64 -I $INCLUDE_PATH_MSVC -I $INCLUDE_PATH_ucrt -I $INCLUDE_PATH_um -I $INCLUDE_PATH_shared -L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64 -I $INCLUDE_PATH_MSVC -I $INCLUDE_PATH_ucrt -I $INCLUDE_PATH_um -I $INCLUDE_PATH_shared -L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
LD=link \
CPPFLAGS="-DFFI_BUILDING_DLL" \
CPP="cl -nologo -EP -I $INCLUDE_PATH_MSVC -I $INCLUDE_PATH_ucrt -I $INCLUDE_PATH_shared" \
CXXCPP="cl -nologo -EP -I $INCLUDE_PATH_MSVC -I $INCLUDE_PATH_ucrt -I $INCLUDE_PATH_shared" \
--disable-docs \
--prefix=/c/temp/libffi \
--host=aarch64-w64-mingw32
Building the Source Code
Run make
in the root of the repo. The generated LIB and DLL files should be in the aarch64-w64-mingw32/.libs/
subdirectory of the repo root. There will also be ffi.h and ffitarget.h include files in the aarch64-w64-mingw32/include/
subdirectory of the repo root. These 4 files are typically what will be required by other projects with a libffi dependency (like OpenJDK).
$ ls -1 aarch64-w64-mingw32/.libs/
libffi.la
libffi.lai
libffi_convenience.la
libffi_convenience.lib
libffi-8.dll*
libffi-8.exp
libffi-8.lib
$ ls -1 aarch64-w64-mingw32/include/
ffi.h
ffitarget.h
Makefile
Background Investigation Details
Investigating Configure Errors
My initial attempt at building libffi for Windows ARM64 started on the wrong path, based on this quote from libffi/libffi at v3.4.8.
To build static library for ARM64 with MSVC using visual studio solution, msvc_build folder have aarch64/Ffi_staticLib.sln required header files in aarch64/aarch64_include/
I thought this meant that it would be much faster for me to build libffi since I wouldn’t need all these bash configure stuff. The solution informed me that I needed to upgrade the toolset:

This was the resulting change.
diff --git a/msvc_build/aarch64/Ffi_staticLib.vcxproj b/msvc_build/aarch64/Ffi_staticLib.vcxproj
index 3187699..8e0353f 100644
--- a/msvc_build/aarch64/Ffi_staticLib.vcxproj
+++ b/msvc_build/aarch64/Ffi_staticLib.vcxproj
@@ -15,20 +15,20 @@
<ProjectGuid>{115502C0-BE05-4767-BF19-5C87D805FAD6}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>FfistaticLib</RootNamespace>
- <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>Ffi_staticLib_arm64</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v141</PlatformToolset>
+ <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v141</PlatformToolset>
+ <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
I then changed the architecture (in the Configuration Manager dropdown on the standard VS toolbox) from x64 to ARM64. There are a bunch of compiler errors!
1>D:\repos\libffi\src\closures.c(1015,30): error C2039: 'ftramp': is not a member of 'ffi_closure'
1> D:\repos\libffi\msvc_build\aarch64\aarch64_include\ffi.h(306,16):
1> see declaration of 'ffi_closure'
...
1>D:\repos\libffi\src\prep_cif.c(248,16): error C2065: 'FFI_BAD_ARGTYPE': undeclared identifier
How could a needed field be missing??!! I tried replacing ffi.h with the one from the x64 build but it was clearly wrong because it had architecture-specific code like this:
/* Specify which architecture libffi is configured for. */
#ifndef X86_WIN64
#define X86_WIN64
#endif
I then checked out the commit that added support for Windows AArch64.
git checkout d856743e6b02fcb5911491204131e277a7a4e10b
This allowed VS to build that solution! I set up the repo for OpenJDK by copying the .lib and .h files.
mkdir lib
cp msvc_build/aarch64/ARM64/Debug/Ffi_staticLib_arm64.lib lib/libffi.lib
cp msvc_build/aarch64/aarch64_include/ffi.h include/
cp src/aarch64/ffitarget.h include/
I then tried to configure OpenJDK using this command but the configure script failed!
date; time bash configure --with-jvm-variants=zero --with-libffi=/cygdrive/c/repos/libffi --openjdk-target=aarch64-unknown-cygwin --with-debug-level=slowdebug --with-jtreg=/cygdrive/c/java/binaries/jtreg/jtreg-7.5.1+1 --with-gtest=/cygdrive/c/repos/googletest --with-extra-ldflags=-profile --with-boot-jdk=/cygdrive/c/java/binaries/jdk/x64/jdk-24+36; time /cygdrive/c/repos/scratchpad/scripts/java/cygwin/build-jdk.sh windows aarch64 slowdebug
At this point, I had the build tools installed with the C++ compiler in C:\progra~2\micros~3\2022\buildt~1\vc\tools\msvc\1443~1.348\bin\hostx64\arm64\cl.exe
. I opened the VS Installer and installed the ARM64 compiler tools. This was necessary because this script was not present on my machine:
"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsamd64_arm64.bat"
Running vcvarsamd64_arm64.bat initialized the environment for ‘x64_arm64’ (cross-compilation targeting ARM64). I then ran dumpbin to see which symbols were in the .lib file VS generated.
cd /d C:\repos\libffi
dumpbin /all /out:ffi-arm64.txt libffi.lib
cd /d D:\repos\libffi
dumpbin /all /out:ffi-x64.txt libffi.lib
The symbols were very different, which was my sign that I just needed to try building for ARM64 in MSYS2. I also upgraded VS some of the paths use 14.44 and others were 14.43. I started MSYS2 then added the arm64 compiler to the PATH. I tried the long path again but only the 8.3 filename format path worked.
export PATH="/c/Program\ Files/Microsoft\ Visual\ Studio/2022/Enterprise/VC/Tools/MSVC/14.44.35207/bin/Hostx64/arm64/:$PATH"
export PATH="$PATH:/c/Program\ Files/Microsoft\ Visual\ Studio/2022/Enterprise/VC/Tools/MSVC/14.44.35207/bin/Hostx64/arm64/"
# Only this one works.
$ export PATH="$PATH:/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/bin/Hostx64/arm64/"
$ where cl.exe
I then switched the repo back to v3.4.8 and ran autogen.sh. This time I specified the –target option to request a aarch64 build. See Specifying Target Triplets (Autoconf) for an overview of the target triplets.
git co v3.4.8
ls -l configure
mkdir -p /c/temp/libffi
./autogen.sh
bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link CPP="cl -nologo -EP" CXXCPP="cl -nologo -EP" \
--disable-docs \
--prefix=/c/temp/libffi \
--target=aarch64-w64-mingw32
The above configure command failed with this error:
$ bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link CPP="cl -nologo -EP" CXXCPP="cl -nologo -EP" \
--disable-docs \
--prefix=/c/temp/libffi \
--target=aarch64-w64-mingw32
configure: loading site script /etc/config.site
checking build system type... x86_64-w64-mingw32
checking host system type... x86_64-w64-mingw32
checking target system type... aarch64-w64-mingw32
continue configure in default builddir "./aarch64-w64-mingw32"
....exec /bin/sh ../configure "--srcdir=.." "--enable-builddir=aarch64-w64-mingw32" "mingw32"
configure: loading site script /etc/config.site
checking build system type... x86_64-w64-mingw32
checking host system type... x86_64-w64-mingw32
checking target system type... aarch64-w64-mingw32
checking for gsed... sed
checking for a BSD-compatible install... /usr/bin/install -c
checking whether sleep supports fractional seconds... yes
checking filesystem timestamp resolution... 0.01
checking whether build environment is sane... yes
checking for a race-free mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking xargs -n works... yes
checking for gcc... /c/repos/libffi/msvcc.sh -marm64
checking whether the C compiler works... no
configure: error: in '/c/repos/libffi/aarch64-w64-mingw32':
configure: error: C compiler cannot create executables
See 'config.log' for more details
Snippet from aarch64-w64-mingw32/config.log
:
configure:4726: checking for C compiler version
configure:4735: /c/repos/libffi/msvcc.sh -marm64 --version >&5
/Wall enable all warnings /w disable all warnings
/W<n> set warning level (default n=1)
/Wv:xx[.yy[.zzzzz]] disable warnings introduced after version xx.yy.zzzzz
/WX treat warnings as errors /WL enable one line diagnostics
/wd<n> disable warning n /we<n> treat warning n as an error
/wo<n> issue warning n once /w<l><n> set warning level 1-4 for n
/external:W<n> - warning level for external headers
/external:templates[-] - evaluate warning level across template instantiation chain
/sdl enable additional security features and warnings
/options:strict unrecognized compiler options are an error
Microsoft (R) C/C++ Optimizing Compiler Version 19.44.35207.1 for ARM64
Copyright (C) Microsoft Corporation. All rights reserved.
configure:4746: $? = 0
configure:4735: /c/repos/libffi/msvcc.sh -marm64 -v >&5
cl : Command line warning D9002 : ignoring unknown option '-v'
cl : Command line error D8003 : missing source filename
configure:4746: $? = 0
configure:4735: /c/repos/libffi/msvcc.sh -marm64 -V >&5
cl : Command line error D8004 : '/V' requires an argument
configure:4746: $? = 0
configure:4735: /c/repos/libffi/msvcc.sh -marm64 -qversion >&5
cl : Command line warning D9002 : ignoring unknown option '-qversion'
cl : Command line error D8003 : missing source filename
configure:4746: $? = 0
configure:4735: /c/repos/libffi/msvcc.sh -marm64 -version >&5
cl : Command line warning D9002 : ignoring unknown option '-version'
cl : Command line error D8003 : missing source filename
configure:4746: $? = 0
configure:4766: checking whether the C compiler works
configure:4788: /c/repos/libffi/msvcc.sh -marm64 -DFFI_BUILDING_DLL conftest.c >&5
LINK : fatal error LNK1104: cannot open file 'MSVCRT.lib'
configure:4792: $? = 0
configure:4833: result: no
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "libffi"
| #define PACKAGE_TARNAME "libffi"
| #define PACKAGE_VERSION "3.3-rc0"
| #define PACKAGE_STRING "libffi 3.3-rc0"
| #define PACKAGE_BUGREPORT "http://github.com/libffi/libffi/issues"
| #define PACKAGE_URL ""
| #define PACKAGE "libffi"
| #define VERSION "3.3-rc0"
| /* end confdefs.h. */
|
| int
| main (void)
| {
|
| ;
| return 0;
| }
configure:4838: error: in '/c/repos/libffi/aarch64-w64-mingw32':
configure:4840: error: C compiler cannot create executables
See 'config.log' for more details
I noticed there is a --verbose
option in the script. Comparing the 2 architecture revealed that the compiler was being invoked the same way.
$ /c/repos/libffi/msvcc.sh -m64 --verbose
cl -MD -nologo -W3
cl : Command line error D8003 : missing source filename
$ /c/repos/libffi/msvcc.sh -marm64 --verbose
cl -MD -nologo -W3
cl : Command line error D8003 : missing source filename
I asked Copilot Which autoconf macro outputs “checking whether the C compiler works” and it said that’s the AC_PROG_CC macro. That string showed up in 3 spots in the codebase but they weren’t what I was looking for. The “checking for C compiler version” was in the generated configure script though.
# Provide some information about the compiler.
printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
set X $ac_compile
ac_compiler=$2
for ac_option in --version -v -V -qversion -version; do
{ { ac_try="$ac_compiler $ac_option >&5"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
This explained where those odd arguments in the config.log snippet were coming from. The question was now how this was different from the x64 case where it just worked? The diff showed that I was actually still on 3.3-rc0 so I needed to rerun autogen.sh on v3.4.8. I didn’t think I needed the --target
option since the correct compiler was selected (as far as I could tell from the --verbose
output above).
bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link CPP="cl -nologo -EP" CXXCPP="cl -nologo -EP" \
--disable-docs \
--prefix=/c/temp/libffi
The configure files were identical in both scenarios. However, there was a key difference in the config logs! Here is a snippet from the working x64 build’s config.log. Notice that the version detection errors were present in this case too (that was a red herring)!
configure:4679: /d/repos/libffi/msvcc.sh -m64 -version >&5
cl : Command line warning D9002 : ignoring unknown option '-version'
cl : Command line error D8003 : missing source filename
configure:4690: $? = 0
configure:4710: checking whether the C compiler works
configure:4732: /d/repos/libffi/msvcc.sh -m64 -DFFI_BUILDING_DLL conftest.c >&5
configure:4736: $? = 0
configure:4787: result: yes
configure:4679: /c/repos/libffi/msvcc.sh -marm64 -version >&5
cl : Command line warning D9002 : ignoring unknown option '-version'
cl : Command line error D8003 : missing source filename
configure:4690: $? = 0
configure:4710: checking whether the C compiler works
configure:4732: /c/repos/libffi/msvcc.sh -marm64 -DFFI_BUILDING_DLL conftest.c >&5
LINK : fatal error LNK1104: cannot open file 'MSVCRT.lib'
configure:4736: $? = 0
configure:4777: result: no
The linker error was really what I needed to address here. I created this conftest.c file to address the command line compilation issue:
int main (void)
{
return 0;
}
$ cl -MD -W3 conftest.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.44.35207.1 for ARM64
Copyright (C) Microsoft Corporation. All rights reserved.
conftest.c
Microsoft (R) Incremental Linker Version 14.44.35207.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:conftest.exe
conftest.obj
LINK : fatal error LNK1104: cannot open file 'MSVCRT.lib'
How does OpenJDK get around this? Interestingly, this was when I noticed that the OpenJDK log also had all the version checking errors (-v -V –version, etc). This is the snippet from OpenJDK’s config.log (notice the -libpaths):
configure:105502: checking whether the C compiler works
configure:105524: /cygdrive/d/java/forks/TheShermanTanker/jdk/build/windows-aarch64-zero-slowdebug/fixpath exec /cygdrive/c/progra~1/mib055~1/2022/enterp~1/vc/tools/msvc/1443~1.348/bin/hostx64/arm64/cl.exe -I/cygdrive/c/progra~1/mib055~1/2022/enterp~1/vc/tools/msvc/1443~1.348/include -I/cygdrive/c/progra~1/mib055~1/2022/enterp~1/vc/tools/msvc/1443~1.348/atlmfc/include -I/cygdrive/c/progra~1/mib055~1/2022/enterp~1/vc/auxili~1/vs/include -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/um -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/winrt -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/cppwinrt -I/cygdrive/c/progra~2/wi3cf2~1/netfxsdk/4.8/include/um -I/cygdrive/c/progra~1/mib055~1/2022/enterp~1/vc/tools/msvc/1443~1.348/include -I/cygdrive/c/progra~1/mib055~1/2022/enterp~1/vc/tools/msvc/1443~1.348/atlmfc/include -I/cygdrive/c/progra~1/mib055~1/2022/enterp~1/vc/auxili~1/vs/include -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/um -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/winrt -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/cppwinrt -I/cygdrive/c/progra~2/wi3cf2~1/netfxsdk/4.8/include/um conftest.c -link -libpath:/cygdrive/c/progra~1/mib055~1/2022/enterp~1/vc/tools/msvc/1443~1.348/lib/arm64 -libpath:/cygdrive/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -libpath:/cygdrive/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64 -profile >&5
Microsoft (R) C/C++ Optimizing Compiler Version 19.43.34810 for ARM64
Copyright (C) Microsoft Corporation. All rights reserved.
conftest.c
Microsoft (R) Incremental Linker Version 14.43.34810.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:conftest.exe
-libpath:c:\progra~1\mib055~1\2022\enterp~1\vc\tools\msvc\1443~1.348\lib\arm64
-libpath:c:\progra~2\wi3cf2~1\10\lib\100226~1.0\ucrt\arm64
-libpath:c:\progra~2\wi3cf2~1\10\lib\100226~1.0\um\arm64
-profile
conftest.obj
configure:105528: $? = 0
configure:105579: result: yes
Searching that codebase for libpath led to the location where the -libpath arguments are built in jdk/make/autoconf/toolchain_microsoft.m4. I should do the same thing and set the LDFLAGS.
$ cl -MD -W3 conftest.c -link -libpath:/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -libpath:/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -libpath:/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64
Microsoft (R) C/C++ Optimizing Compiler Version 19.44.35207.1 for ARM64
Copyright (C) Microsoft Corporation. All rights reserved.
conftest.c
Microsoft (R) Incremental Linker Version 14.44.35207.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:conftest.exe
-libpath:C:/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64
-libpath:C:/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64
-libpath:C:/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64
conftest.obj
That succeeded so I tried to set the LDFLAGS for libffi.
bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LDFLAGS="-link -libpath:/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -libpath:/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -libpath:/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
LD=link CPP="cl -nologo -EP" CXXCPP="cl -nologo -EP" \
--disable-docs \
--prefix=/c/temp/libffi
The error was now about missing kernel32.lib.
configure:4710: checking whether the C compiler works
configure:4732: /c/repos/libffi/msvcc.sh -marm64 -DFFI_BUILDING_DLL -link -libpath:/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -libpath:/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -libpath:/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64 conftest.c >&5
LINK : fatal error LNK1104: cannot open file 'kernel32.lib'
configure:4736: $? = 0
configure:4777: result: no
I verified that kernel32.lib exists in C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\arm64\
, which is the path /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64
. A solution to How can I convert a Windows short name path into long names within a batch script – Stack Overflow would have been nice but oh well.
$ /c/repos/libffi/msvcc.sh -marm64 --verbose -DFFI_BUILDING_DLL -link -libpath:/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -libpath:/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -libpath:/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64 conftest.c
cl -MD -nologo -W3 -DFFI_BUILDING_DLL C:/repos/libffi/conftest.c -link -libpath:/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64
LINK : fatal error LNK1104: cannot open file 'kernel32.lib'
Looks like the other paths are being dropped by the script. Further inspection of the script reveals that it has a -L option for these libraries. I tried the -link option but something wasn’t working so I moved on to -L. These are the libraries I needed:
bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64 -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link CPP="cl -nologo -EP" CXXCPP="cl -nologo -EP" \
--disable-docs \
--prefix=/c/temp/libffi
With the above command, the next issue was around cross compiling:
configure: loading site script /etc/config.site
checking build system type... x86_64-w64-mingw32
checking host system type... x86_64-w64-mingw32
checking target system type... x86_64-w64-mingw32
continue configure in default builddir "./x86_64-w64-mingw32"
....exec /bin/sh ../configure "--srcdir=.." "--enable-builddir=x86_64-w64-mingw32" "mingw32"
configure: loading site script /etc/config.site
checking build system type... x86_64-w64-mingw32
checking host system type... x86_64-w64-mingw32
checking target system type... x86_64-w64-mingw32
checking for gsed... sed
checking for a BSD-compatible install... /usr/bin/install -c
checking whether sleep supports fractional seconds... yes
checking filesystem timestamp resolution... 0.01
checking whether build environment is sane... yes
checking for a race-free mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking xargs -n works... yes
checking for gcc... /c/repos/libffi/msvcc.sh -marm64 -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64
checking whether the C compiler works... yes
checking for C compiler default output file name... conftest.exe
checking for suffix of executables... .exe
checking whether we are cross compiling... configure: error: in '/c/repos/libffi/x86_64-w64-mingw32':
configure: error: cannot run C compiled programs.
If you meant to cross compile, use '--host'.
See 'config.log' for more details
At least this error message let me know what I needed to do to.
time bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64 -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link CPP="cl -nologo -EP" CXXCPP="cl -nologo -EP" \
--disable-docs \
--prefix=/c/temp/libffi \
--host=aarch64-w64-mingw32
Next error after that change in the checking how to run the C++ preprocessor
step, specifically error: C++ preprocessor "cl -nologo -EP" fails sanity check
.
configure:14431: checking how to run the C++ preprocessor
configure:14498: result: cl -nologo -EP
configure:14512: cl -nologo -EP -DFFI_BUILDING_DLL conftest.cpp
conftest.cpp
conftest.cpp(12): fatal error C1034: limits.h: no include path set
configure:14512: $? = 2
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "libffi"
| #define PACKAGE_TARNAME "libffi"
| #define PACKAGE_VERSION "3.4.8"
| #define PACKAGE_STRING "libffi 3.4.8"
| #define PACKAGE_BUGREPORT "http://github.com/libffi/libffi/issues"
| #define PACKAGE_URL ""
| #define PACKAGE "libffi"
| #define VERSION "3.4.8"
| #define LT_OBJDIR ".libs/"
| /* end confdefs.h. */
| #include <limits.h>
| Syntax error
configure:14512: cl -nologo -EP -DFFI_BUILDING_DLL conftest.cpp
conftest.cpp
conftest.cpp(12): fatal error C1034: limits.h: no include path set
configure:14512: $? = 2
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "libffi"
| #define PACKAGE_TARNAME "libffi"
| #define PACKAGE_VERSION "3.4.8"
| #define PACKAGE_STRING "libffi 3.4.8"
| #define PACKAGE_BUGREPORT "http://github.com/libffi/libffi/issues"
| #define PACKAGE_URL ""
| #define PACKAGE "libffi"
| #define VERSION "3.4.8"
| #define LT_OBJDIR ".libs/"
| /* end confdefs.h. */
| #include <limits.h>
| Syntax error
configure:14547: error: in '/c/repos/libffi/aarch64-w64-mingw32':
configure:14549: error: C++ preprocessor "cl -nologo -EP" fails sanity check
See 'config.log' for more details
My fix was to provide the MSVC include path:
time bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link CPP="cl -nologo -EP" CXXCPP="cl -nologo -EP" \
--disable-docs \
--prefix=/c/temp/libffi \
--host=aarch64-w64-mingw32
I used this new conftest.c to ensure that the compiler would succeed.
#include <limits.h>
int main (void)
{
return 0;
}
/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64 conftest.c
The include path was respected with this manually executed command so I ran msvcc.sh in verbose mode to be sure it was picking up all my arguments:
time bash configure \
CC="/c/repos/libffi/msvcc.sh --verbose -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link CPP="cl -nologo -EP" CXXCPP="cl -nologo -EP" \
--disable-docs \
--prefix=/c/temp/libffi \
--host=aarch64-w64-mingw32
The above command failed but I noticed that this is the C++ preprocessor. I needed the same command for the CXX environment variable.
time bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link CPP="cl -nologo -EP" CXXCPP="cl -nologo -EP" \
--disable-docs \
--prefix=/c/temp/libffi \
--host=aarch64-w64-mingw32
I saved this test program as conftest.cpp this time (notice the extension).
#include <limits.h>
int main (void)
{
return 0;
}
The test below showed that providing the include path lets cl.exe complete successfully.
$ cl -nologo -EP -DFFI_BUILDING_DLL conftest.cpp
conftest.cpp
conftest.cpp(1): fatal error C1034: limits.h: no include path set
$ cl -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -nologo -EP -DFFI_BUILDING_DLL conftest.cpp
conftest.cpp
#pragma once
...
The issue must have been in the CPP command so I updated it:
time bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64 -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link CPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" CXXCPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" \
--disable-docs \
--prefix=/c/temp/libffi \
--host=aarch64-w64-mingw32
The configure script now completed! I had a feeling I would need to keep adding paths like this during the build process.
...
checking size of long double... 0
checking whether byte ordering is bigendian... no
checking assembler .cfi pseudo-op support... no
checking whether compiler supports pointer authentication... no
checking for _ prefix in compiled symbols... no
configure: versioning on shared library symbols is no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating include/Makefile
config.status: creating include/ffi.h
config.status: creating Makefile
config.status: creating testsuite/Makefile
config.status: creating man/Makefile
config.status: creating doc/Makefile
config.status: creating libffi.pc
config.status: creating fficonfig.h
config.status: executing buildir commands
config.status: create top_srcdir/Makefile guessed from local Makefile
config.status: build in aarch64-w64-mingw32 (HOST=)
config.status: executing depfiles commands
config.status: executing libtool commands
config.status: executing include commands
config.status: executing src commands
real 1m29.429s
user 0m32.473s
sys 0m35.396s
Investigating Build Errors
Just as I suspected, there were build errors when I ran make
. Specifically, 8 of these C1083 errors:
libtool: compile: /c/repos/libffi/msvcc.sh -marm64 -I "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -L "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -DFFI_BUILDING_DLL -O2 -c ../src/prep_cif.c -DDLL_EXPORT -DPIC -o src/.libs/prep_cif.obj
C:/repos/libffi/include\ffi.h(66): fatal error C1083: Cannot open include file: 'stddef.h': No such file or directory
That file lives in C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt
. The OpenJDK build includes these 5 paths (among many others) but I didn’t think I’d need the RT-related paths. I added the other 3 to the configure command then ran make
again.
-I/cygdrive/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/um -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/winrt -I/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/cppwinrt
The more critical error was this one:
libtool: compile: /c/repos/libffi/msvcc.sh -marm64 -I "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -L "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -DFFI_BUILDING_DLL -I. -I../include -Iinclude -I../src -c ../src/aarch64/win64_armasm.S -DDLL_EXPORT -DPIC -o src/aarch64/.libs/win64_armasm.obj
win64_armasm.S
C:/repos/libffi/src/aarch64/win64_armasm.S(27): fatal error C1083: Cannot open include file: 'ksarm64.h': No such file or directory
Where did that file go? Based on the inability to build the VS solution in my first attempt, I searched for which commit could have deleted this ksarm64.h file. I used the suggestion at git – How to find a deleted file in the project commit history? – Stack Overflow
git log --diff-filter=D --summary | grep delete
git log --diff-filter=D --summary | grep delete | grep ks
This search for commits did not yield anything but a web search of ksarm64.h – Search led me to the [Arm64/Windows] Missing ksarm64.h ? · Issue #7409 · dotnet/runtime GitHub issue, which said that ksarm64.h is part of the Windows SDK. ksarm64.h isn’t include in Windows SDK – Developer Community was the pointer about where it lives: c/progra~2/wi3cf2~1/10/include/100226~1.0/shared
. I had excluded this path because I wanted a minimal set of include paths. This was the next command I tried. I should have exported these paths to an environment variable like I have at the top but I just kept moving forward.
time bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64 -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link \
CPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" \
CXXCPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" \
--disable-docs \
--prefix=/c/temp/libffi \
--host=aarch64-w64-mingw32
I was still seeing errors on a new clone of the repo (under the dups subdirectory):
Making all in man
make[3]: Entering directory '/d/repos/dups/libffi/aarch64-w64-mingw32/man'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/d/repos/dups/libffi/aarch64-w64-mingw32/man'
make[3]: Entering directory '/d/repos/dups/libffi/aarch64-w64-mingw32'
source='../src/prep_cif.c' object='src/prep_cif.lo' libtool=yes \
DEPDIR=.deps depmode=none /bin/sh ../depcomp \
/bin/sh ./libtool --tag=CC --mode=compile /c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64 -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -DFFI_BUILDING_DLL -O2 -c -o src/prep_cif.lo ../src/prep_cif.c
libtool: compile: /c/repos/libffi/msvcc.sh -marm64 -I "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -I "/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt" -I "/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" -L "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -DFFI_BUILDING_DLL -O2 -c ../src/prep_cif.c -DDLL_EXPORT -DPIC -o src/.libs/prep_cif.obj
D:/repos/dups/libffi/aarch64-w64-mingw32/include\ffi.h(105): fatal error C1083: Cannot open include file: 'stddef.h': No such file or directory
I could reproduce these errors as follows:
mkdir src/.libs/
cd aarch64-w64-mingw32/
/c/repos/libffi/msvcc.sh -marm64 -I "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -I "/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt" -I "/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" -L "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -DFFI_BUILDING_DLL -O2 -c ../src/raw_api.c -DDLL_EXPORT -DPIC -o src/.libs/raw_api.obj
D:/repos/dups/libffi/aarch64-w64-mingw32/include\ffi.h(105): fatal error C1083: Cannot open include file: 'stddef.h': No such file or directory
Adding the --verbose
flag to the last command above showed me the problem: the -I paths were broken!
cl -MD -nologo -W3 -I"C:/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -I"C:/software/msys64/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt" -I"C:/software/msys64/cygdrive/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" -DHAVE_CONFIG_H -I"D:/repos/dups/libffi/aarch64-w64-mingw32" -I"D:/repos/dups/libffi" -I"D:/repos/dups/libffi/aarch64-w64-mingw32" -I"D:/repos/dups/libffi/include" -I"D:/repos/dups/libffi/aarch64-w64-mingw32/include" -I"D:/repos/dups/libffi/src" -DFFI_BUILDING_DLL -O2 -c D:/repos/dups/libffi/src/raw_api.c -DDLL_EXPORT -DPIC -Fosrc/.libs/raw_api.obj -Fdsrc/.libs/raw_api -Fpsrc/.libs/raw_api -Fasrc/.libs/raw_api -link -LIBPATH:C:/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -LIBPATH:C:/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -LIBPATH:C:/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64 -OPT:REF -OPT:ICF -INCREMENTAL:NO
D:/repos/dups/libffi/aarch64-w64-mingw32/include\ffi.h(105): fatal error C1083: Cannot open include file: 'stddef.h': No such file or directory
This was my solution to these path issues:
/c/repos/libffi/msvcc.sh --verbose -marm64 -I "C:/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -I "C:/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt" -I "C:/progra~2/wi3cf2~1/10/include/100226~1.0/shared" -L "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -DFFI_BUILDING_DLL -O2 -c ../src/raw_api.c -DDLL_EXPORT -DPIC -o src/.libs/raw_api.obj
Now the cl.exe command looked like this:
cl -MD -nologo -W3 -I"C:/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -I"C:/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt" -I"C:/progra~2/wi3cf2~1/10/include/100226~1.0/shared" -DHAVE_CONFIG_H -I"D:/repos/dups/libffi/aarch64-w64-mingw32" -I"D:/repos/dups/libffi" -I"D:/repos/dups/libffi/aarch64-w64-mingw32" -I"D:/repos/dups/libffi/include" -I"D:/repos/dups/libffi/aarch64-w64-mingw32/include" -I"D:/repos/dups/libffi/src" -DFFI_BUILDING_DLL -O2 -c D:/repos/dups/libffi/src/raw_api.c -DDLL_EXPORT -DPIC -Fosrc/.libs/raw_api.obj -Fdsrc/.libs/raw_api -Fpsrc/.libs/raw_api -Fasrc/.libs/raw_api -link -LIBPATH:C:/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -LIBPATH:C:/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -LIBPATH:C:/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64 -OPT:REF -OPT:ICF -INCREMENTAL:NO
D:/repos/dups/libffi/src/raw_api.c(188): warning C4013: 'bcopy' undefined; assuming extern returning int
libffi/msvcc.sh at v3.4.8 · libffi/libffi uses cygpath -ma
, which outputs mixed absolute paths (windows form with forward slashes). Here is the corrected configure command (without the /cygdrive
path prefixes):
time bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64 -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link \
CPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" \
CXXCPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" \
--disable-docs \
--prefix=/c/temp/libffi \
--host=aarch64-w64-mingw32
The build now failed with this error:
$ /c/repos/libffi/msvcc.sh -marm64 -I "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" -L "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -DFFI_BUILDING_DLL "-I. -I../include -Iinclude -I../src" -c ../src/aarch64/win64_armasm.S -o src/aarch64/win64_armasm.obj >/dev/null 2>&1
/bin/sh ./libtool --tag=CC --mode=link /c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -L /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L /c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64 -O2 -o libffi_convenience.la src/prep_cif.lo src/types.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo src/tramp.lo src/aarch64/ffi.lo src/aarch64/win64_armasm.lo
libtool: error: require no space between '-L' and '/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64'
I tried the same command without the spaces:
/c/repos/libffi/msvcc.sh -marm64 -I "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" -L "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64" -L "/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -DFFI_BUILDING_DLL "-I. -I../include -Iinclude -I../src" -c ../src/aarch64/win64_armasm.S -o src/aarch64/win64_armasm.obj >/dev/null 2>&1
/bin/sh ./libtool --tag=CC --mode=link /c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64 -O2 -o libffi_convenience.la src/prep_cif.lo src/types.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo src/tramp.lo src/aarch64/ffi.lo src/aarch64/win64_armasm.lo
This resolved the error about the spaces but then failed with:
Microsoft (R) Library Manager Version 14.44.35207.1
Copyright (C) Microsoft Corporation. All rights reserved.
LINK : fatal error LNK1181: cannot open input file 'src\.libs\prep_cif.obj'
Here’s the next iteration of the configure script:
time bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CPPFLAGS="-DFFI_BUILDING_DLL" \
LD=link \
CPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" \
CXXCPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" \
--disable-docs \
--prefix=/c/temp/libffi \
--host=aarch64-w64-mingw32
The build now progressed to this error:
libtool: compile: /c/repos/libffi/msvcc.sh -marm64 -I "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" "-L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64" "-L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64" "-L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -DFFI_BUILDING_DLL -O2 -c ../src/closures.c -DDLL_EXPORT -DPIC -o src/.libs/closures.obj
D:\repos\dups\libffi\src\dlmalloc.c(453): fatal error C1083: Cannot open include file: 'windows.h': No such file or directory
This is where the /c/progra~2/wi3cf2~1/10/include/100226~1.0/um
include path was required.
time bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/um -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/um -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
LD=link \
CPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" \
CXXCPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" \
--disable-docs \
--prefix=/c/temp/libffi \
--host=aarch64-w64-mingw32
This led me to a new error from make
:
...
libtool: compile: /c/repos/libffi/msvcc.sh -marm64 -I "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/um" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" "-L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64" "-L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64" "-L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O2 -c ../src/prep_cif.c -DDLL_EXPORT -DPIC -o src/.libs/prep_cif.obj
D:/repos/dups/libffi/src/prep_cif.c(219): warning C4273: 'ffi_prep_cif': inconsistent dll linkage
D:/repos/dups/libffi/src/prep_cif.c(225): warning C4273: 'ffi_prep_cif_var': inconsistent dll linkage
D:/repos/dups/libffi/src/prep_cif.c(257): warning C4273: 'ffi_prep_closure': inconsistent dll linkage
D:/repos/dups/libffi/src/prep_cif.c(268): warning C4273: 'ffi_get_struct_offsets': inconsistent dll linkage
...
libtool: compile: /c/repos/libffi/msvcc.sh -marm64 -I "/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/um" -I "/c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" "-L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64" "-L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64" "-L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O2 -c ../src/types.c -DDLL_EXPORT -DPIC -o src/.libs/types.obj
D:/repos/dups/libffi/src/types.c(77): error C2491: 'ffi_type_void': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(81): error C2491: 'ffi_type_uint8': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(82): error C2491: 'ffi_type_sint8': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(83): error C2491: 'ffi_type_uint16': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(84): error C2491: 'ffi_type_sint16': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(85): error C2491: 'ffi_type_uint32': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(86): error C2491: 'ffi_type_sint32': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(87): error C2491: 'ffi_type_uint64': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(88): error C2491: 'ffi_type_sint64': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(90): error C2491: 'ffi_type_pointer': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(92): error C2491: 'ffi_type_float': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(93): error C2491: 'ffi_type_double': definition of dllimport data not allowed
D:/repos/dups/libffi/src/types.c(111): error C2491: 'ffi_type_longdouble': definition of dllimport data not allowed
This seemed pretty odd, considering these errors didn’t show up for x64. I didn’t see any defines related to DLLs. Upon further inspection, I realized that I had removed the CPPFLAGS variable somewhere along the way! Restoring it finally got the job done! No make errors at all, phew!
time bash configure \
CC="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/um -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
CXX="/c/repos/libffi/msvcc.sh -marm64 -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/um -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared -L/c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/ucrt/arm64 -L/c/progra~2/wi3cf2~1/10/lib/100226~1.0/um/arm64" \
LD=link \
CPPFLAGS="-DFFI_BUILDING_DLL" \
CPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" \
CXXCPP="cl -nologo -EP -I /c/Progra~1/MIB055~1/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/ucrt -I /c/progra~2/wi3cf2~1/10/include/100226~1.0/shared" \
--disable-docs \
--prefix=/c/temp/libffi \
--host=aarch64-w64-mingw32
Leave a Reply