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

CMake fails on Windows when building ARM64 on x64 host #1352

Open
dmiller-nmap opened this issue Sep 18, 2024 · 6 comments
Open

CMake fails on Windows when building ARM64 on x64 host #1352

dmiller-nmap opened this issue Sep 18, 2024 · 6 comments

Comments

@dmiller-nmap
Copy link
Contributor

The SUITABLE_SNPRINTF check fails because the resulting ARM64 code cannot be run on the x64 host. CMAKE_CROSSCOMPILING is not set because both systems have the same CMAKE_SYSTEM_NAME ("Windows"). Not sure the best way to handle this, since a general check for identical architectures would miss the cases of ARM64 and x64 host systems targeting x86.

libpcap/CMakeLists.txt

Lines 738 to 792 in 3bb233f

if (NOT CMAKE_CROSSCOMPILING)
#
# Require a proof of suitable snprintf(3), same as in Autoconf.
#
include(CheckCSourceRuns)
check_c_source_runs("
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <sys/types.h>
int main()
{
char buf[100];
uint64_t t = (uint64_t)1 << 32;
snprintf(buf, sizeof(buf), \"%zu\", sizeof(buf));
if (strncmp(buf, \"100\", sizeof(buf)))
return 1;
snprintf(buf, sizeof(buf), \"%zd\", -sizeof(buf));
if (strncmp(buf, \"-100\", sizeof(buf)))
return 2;
snprintf(buf, sizeof(buf), \"%\" PRId64, -t);
if (strncmp(buf, \"-4294967296\", sizeof(buf)))
return 3;
snprintf(buf, sizeof(buf), \"0o%\" PRIo64, t);
if (strncmp(buf, \"0o40000000000\", sizeof(buf)))
return 4;
snprintf(buf, sizeof(buf), \"0x%\" PRIx64, t);
if (strncmp(buf, \"0x100000000\", sizeof(buf)))
return 5;
snprintf(buf, sizeof(buf), \"%\" PRIu64, t);
if (strncmp(buf, \"4294967296\", sizeof(buf)))
return 6;
return 0;
}
"
SUITABLE_SNPRINTF
)
if(NOT SUITABLE_SNPRINTF)
message(FATAL_ERROR
"The snprintf(3) implementation in this libc is not suitable,
libpcap would not work correctly even if it managed to compile."
)
endif()
else()
message(STATUS "Skipped SUITABLE_SNPRINTF because cross-compiling.")
endif()

@infrastation
Copy link
Member

Could you add the steps to reproduce the problem?

@mcr
Copy link
Member

mcr commented Sep 18, 2024

I don't think we've ever supported cross-compiling on Windows.

But, it seems that "Windows" as a value for CMAKE_SYSTEM_NAME is wrong, if it implies x86_64, and Windows now supports building for ARM. Maybe WSL + ./configure is a better route.

@dmiller-nmap
Copy link
Contributor Author

The CMake command I ran is in a script in Npcap's source tree. I believe the crucial part is the -A ARM64, but here is the entire command as run:

%CMAKE% -A ARM64 -DCMAKE_DISABLE_FIND_PACKAGE_OpenSSL=TRUE -DOpenSSL_FOUND=FALSE -DCMAKE_C_FLAGS_INIT="/guard:cf" -DCMAKE_SHARED_LINKER_FLAGS_INIT="/guard:cf" -DPacket_ROOT=..\%NPCAP_SDK% -DLIBRARY_NAME=wpcap -G "Visual Studio 17 2022" ..\libpcap\

@guyharris
Copy link
Member

I believe the crucial part is the -A ARM64

According to the CMake 3.12 "cmake" command documentation (3.12 being the minimum version of CMake we require on Windows), -A "[Specifies] platform name if supported by generator." Following various links, it appears that this affects the value of the CMAKE_VS_PLATFORM_NAME variable.

Unfortunately, as you noted, CMAKE_CROSSCOMPILING is defined to mean "compiling for a different operating system", not "compiling for a different instruction set"; good luck if you're compiling for an Arm embedded Linux system on an x86 Linux system.

It appears that "cross-compiling for a different instruction set" amounts to CMAKE_SYSTEM_PROCESSOR not being equal to CMAKE_HOST_SYSTEM_PROCESSOR.

guyharris added a commit to guyharris/libpcap that referenced this issue Sep 19, 2024
CMake appears to have the notion that a build is only a cross-compile if
the targt *operating system* is different.  This is an incorrect notion,
as even if the target is the *same* OS but a different instruction set,
you may not be able to do tests that involve compiling and running a
program.

Check whether CMAKE_GENERATOR_PLATFORM is set and has a value different
from that of CMAKE_HOST_SYSTEM_PROCESSOR and, if that's the case, set
CMAKE_CROSSCOMPILING to TRUE.

This should fix issue the-tcpdump-group#1352.

(A different strategy may be necessary for cross-builds with UNIX
toolchains.)
guyharris added a commit that referenced this issue Sep 19, 2024
CMake appears to have the notion that a build is only a cross-compile if
the targt *operating system* is different.  This is an incorrect notion,
as even if the target is the *same* OS but a different instruction set,
you may not be able to do tests that involve compiling and running a
program.

Check whether CMAKE_GENERATOR_PLATFORM is set and has a value different
from that of CMAKE_HOST_SYSTEM_PROCESSOR and, if that's the case, set
CMAKE_CROSSCOMPILING to TRUE.

This should fix issue #1352.

(A different strategy may be necessary for cross-builds with UNIX
toolchains.)
@guyharris
Copy link
Member

See if this fixes it. (The check for a cross-compile doesn't occur in the 1.10 branch, so this doesn't need to be backported; we're not doing a check for a working snprintf() there.)

@dmiller-nmap
Copy link
Contributor Author

It's working for me now, thanks.

guyharris added a commit to guyharris/tcpdump that referenced this issue Sep 20, 2024
CMake appears to have the notion that a build is only a cross-compile if
the targt *operating system* is different.  This is an incorrect notion,
as even if the target is the *same* OS but a different instruction set,
you may not be able to do tests that involve compiling and running a
program.

Check whether CMAKE_GENERATOR_PLATFORM is set and has a value different
from that of CMAKE_HOST_SYSTEM_PROCESSOR and, if that's the case, set
CMAKE_CROSSCOMPILING to TRUE.

This comes from libpcap, where the equivalent change fixed issue
the-tcpdump-group/libpcap#1352.

(A different strategy may be necessary for cross-builds with UNIX
toolchains.)
guyharris added a commit to the-tcpdump-group/tcpdump that referenced this issue Sep 22, 2024
CMake appears to have the notion that a build is only a cross-compile if
the targt *operating system* is different.  This is an incorrect notion,
as even if the target is the *same* OS but a different instruction set,
you may not be able to do tests that involve compiling and running a
program.

Check whether CMAKE_GENERATOR_PLATFORM is set and has a value different
from that of CMAKE_HOST_SYSTEM_PROCESSOR and, if that's the case, set
CMAKE_CROSSCOMPILING to TRUE.

This comes from libpcap, where the equivalent change fixed issue
the-tcpdump-group/libpcap#1352.

(A different strategy may be necessary for cross-builds with UNIX
toolchains.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants