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

Fix debug build failure on Windows ARM64+MSVC #5285

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

anthony-linaro
Copy link

When compiling natively on a Windows ARM64 machine and using MSVC in a "Debug" configuration, there was a linker error, namely LNK1322.

This patch enables the compiler flag to fix those issues for those builds.

Tested with the following commands:

cmake -DCMAKE_BUILD_TYPE:STRING=Debug -DBUILD_SHARED_LIBS:BOOL=OFF -DBUILD_TESTING:BOOL=ON -DHDF5_BUILD_TOOLS:BOOL=ON ..
cmake --build . --config Debug
ctest -C Debug -j4

Testing done on a Thinkpad T14s Gen6 (Snapdragon X Elite), with VS2022.

@byrnHDF
Copy link
Contributor

byrnHDF commented Jan 30, 2025

Wouldn't these changes be needed for all the libraries?

@anthony-linaro
Copy link
Author

Not necessarily - the linker error only triggers in certain edge-cases, which the C library happened to hit

Is there a set of commands I can use to test the other libraries, if the lines I gave didn't build them?

@byrnHDF
Copy link
Contributor

byrnHDF commented Jan 30, 2025

Not necessarily - the linker error only triggers in certain edge-cases, which the C library happened to hit

Is there a set of commands I can use to test the other libraries, if the lines I gave didn't build them?

release_docs/INSTALL_CMAKE.txt shows the default options in sectio VI. the default options are at the beginning of that section:

---------------- General Build Options -------------------------------------
BUILD_SHARED_LIBS "Build Shared Libraries" ON
BUILD_STATIC_LIBS "Build Static Libraries" ON
BUILD_STATIC_EXECS "Build Static Executables" OFF
BUILD_TESTING "Build HDF5 Unit Testing" ON
if (WINDOWS)
HDF5_DISABLE_PDB_FILES "Do not install PDB files" OFF

---------------- HDF5 Build Options ----------------------------------------
HDF5_BUILD_CPP_LIB "Build HDF5 C++ Library" OFF
HDF5_BUILD_EXAMPLES "Build HDF5 Library Examples" ON
HDF5_BUILD_FORTRAN "Build FORTRAN support" OFF
HDF5_BUILD_JAVA "Build JAVA support" OFF
HDF5_BUILD_HL_LIB "Build HIGH Level HDF5 Library" ON
HDF5_BUILD_TOOLS "Build HDF5 Tools" ON
HDF5_BUILD_PARALLEL_TOOLS "Build Parallel HDF5 Tools" OFF
HDF5_BUILD_STATIC_TOOLS "Build Static Tools Not Shared Tools" OFF

@@ -1131,6 +1135,10 @@ if (BUILD_SHARED_LIBS)
PUBLIC "$<$<BOOL:${HDF5_ENABLE_HDFS}>:${HDFS_INCLUDE_DIR}>"
INTERFACE "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>;$<BUILD_INTERFACE:${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR}>"
)
if(MSVC AND CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64" AND ${HDF_CFG_NAME} MATCHES "Debug")
# Required to work around linker error LNK1322
target_link_options(${HDF5_LIB_TARGET} PRIVATE "/Gy")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be ${HDF5_LIBSH_TARGET}, but this kind of flag also seems like something that should be set much higher up in the process rather than here, especially considering the very specific platform and build combination logic.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a place you would suggest to be more appropriate? I'm not massively familiar with the codebase, and would like to make sure I've done things correctly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't really have other calls to target_link_options in the library other than a few niche places in the C++ wrappers, it may take a small bit of work. I suggest having another variable similar to HDF5_CMAKE_C_FLAGS, say HDF5_CMAKE_C_LINK_FLAGS, then setting whatever you need in config/cmake/HDFCompilerFlags.cmake maybe. You can see some examples there like:

list (APPEND HDF5_CMAKE_C_FLAGS "-erroff=%none -DBSD_COMP")

where flags are added to the HDF5_CMAKE_C_FLAGS list. Once you have your flag added to the new variable there, you can have these calls be:

target_link_options (${HDF5_LIB_TARGET} PRIVATE "${HDF5_CMAKE_C_LINK_FLAGS}")
target_link_options (${HDF5_LIBSH_TARGET} PRIVATE "${HDF5_CMAKE_C_LINK_FLAGS}")

for whatever the variable is called. That way will be a bit more maintainable in case other flags need to be added in the future and keeps the platform-specific logic out of the main CMake files.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option is the macro in HDFMacros.cmake
macro (TARGET_C_PROPERTIES wintarget libtype)
target_compile_options(${wintarget} PRIVATE
"$<$<C_COMPILER_ID:MSVC>:${WIN_COMPILE_FLAGS}>"
"$<$<CXX_COMPILER_ID:MSVC>:${WIN_COMPILE_FLAGS}>"
)
if(MSVC)
set_property(TARGET ${wintarget} APPEND PROPERTY LINK_FLAGS "${WIN_LINK_FLAGS}")
endif()
#Disable UNITY_BUILD for now
set_property(TARGET ${wintarget} APPEND PROPERTY UNITY_BUILD OFF)
endmacro ()

@anthony-linaro
Copy link
Author

@byrnHDF Thanks for that, not sure how I missed it when I was reading the docs! Would the following command line (where I switched a number of options on) suffice for making sure things were compiled? Have I missed anything obvious?

cmake -DCMAKE_BUILD_TYPE:STRING=Debug -DBUILD_STATIC_EXECS=ON -DHDF5_BUILD_CPP_LIB=ON -DHDF5_BUILD_PARALLEL_TOOLS=ON -DHDF5_BUILD_STATIC_TOOLS=ON -DBUILD_TESTING:BOOL=ON -DHDF5_BUILD_TOOLS:BOOL=ON ..

@hyoklee
Copy link
Member

hyoklee commented Jan 31, 2025

@anthony-linaro , thank you for your PR!

I could confirm the LNK1322 problem using cross-compiler.
Are you seeing the same 7 errors here?

Copy link
Member

@hyoklee hyoklee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anthony-linaro
Copy link
Author

@hyoklee - Yes, those are the same errors

I've been looking at enabling wider tooling with the following command line:

cmake -G"Ninja" -DCMAKE_BUILD_TYPE:STRING=Debug -DBUILD_STATIC_EXECS=ON -DHDF5_BUILD_CPP_LIB=ON -DHDF5_BUILD_PARALLEL_TOOLS=ON -DHDF5_BUILD_STATIC_TOOLS=ON -DBUILD_TESTING:BOOL=ON -DHDF5_BUILD_TOOLS:BOOL=ON ..

Sadly, even with /Gy specified, it still seems to be throwing those errors on my machine when building those extra libraries - does your build on cdash build additional things like the CPP lib too?

@jhendersonHDF
Copy link
Collaborator

Sadly, even with /Gy specified, it still seems to be throwing those errors on my machine when building those extra libraries - does your build on cdash build additional things like the CPP lib too?

As @byrnHDF mentioned, some of the components of HDF5 may also need a target_link_options made on them if you enable those components. I don't know that we currently have a "full build" test, but it would involve at least HDF5_ALLOW_UNSUPPORTED=ON HDF5_BUILD_CPP_LIB=ON HDF5_BUILD_FORTRAN=ON HDF5_BUILD_JAVA=ON HDF5_ENABLE_PARALLEL=ON.

@anthony-linaro
Copy link
Author

anthony-linaro commented Jan 31, 2025

This is with /Gy forcibly set for every single file, as a test - sadly it looks like it's not possible to compile anything but the C library (and other associated things like tests in the default build) in Debug mode for these platforms - I have included some relevant extracts:

CMD:

[792/3112] Linking C executable bin\dtypes.exe
FAILED: bin/dtypes.exe
C:\Windows\system32\cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=test\CMakeFiles\dtypes.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\arm64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\arm64\mt.exe --manifests  -- C:\PROGRA~1\MICROS~3\2022\COMMUN~1\VC\Tools\MSVC\1442~1.344\bin\HOSTAR~1\arm64\link.exe /nologo test\CMakeFiles\dtypes.dir\dtypes.c.obj  /out:bin\dtypes.exe /implib:bin\dtypes.lib /pdb:bin\dtypes.pdb /version:0.0 /machine:ARM64 -stack:10000000 /debug /INCREMENTAL /subsystem:console  bin\hdf5_test_D.lib  bin\hdf5_D.lib  shlwapi.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
LINK Pass 1: command "C:\PROGRA~1\MICROS~3\2022\COMMUN~1\VC\Tools\MSVC\1442~1.344\bin\HOSTAR~1\arm64\link.exe /nologo test\CMakeFiles\dtypes.dir\dtypes.c.obj /out:bin\dtypes.exe /implib:bin\dtypes.lib /pdb:bin\dtypes.pdb /version:0.0 /machine:ARM64 -stack:10000000 /debug /INCREMENTAL /subsystem:console bin\hdf5_test_D.lib bin\hdf5_D.lib shlwapi.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:test\CMakeFiles\dtypes.dir/intermediate.manifest test\CMakeFiles\dtypes.dir/manifest.res" failed (exit code 1322) with the following output:
dtypes.c.obj : fatal error LNK1322: cannot avoid potential ARM hazard (Cortex-A53 MPCore processor bug #843419) in section 0x34; please consider using compiler option /Gy if it was not used

build.ninja:

#############################################
# Link the executable bin\dtypes.exe

build bin\dtypes.exe: C_EXECUTABLE_LINKER__dtypes_Debug test\CMakeFiles\dtypes.dir\dtypes.c.obj | bin\hdf5_test_D.lib bin\hdf5_D.lib || bin\hdf5_D.dll bin\hdf5_test_D.dll
  FLAGS = -std:c11 /DWIN32 /D_WINDOWS -wd5105 /Gy /Zi /Ob0 /Od /RTC1 -MDd
  LINK_FLAGS = /machine:ARM64 -stack:10000000 /debug /INCREMENTAL /subsystem:console
  LINK_LIBRARIES = bin\hdf5_test_D.lib  bin\hdf5_D.lib  shlwapi.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
  OBJECT_DIR = test\CMakeFiles\dtypes.dir
  POST_BUILD = cd .
  PRE_LINK = cd .
  TARGET_COMPILE_PDB = test\CMakeFiles\dtypes.dir\
  TARGET_FILE = bin\dtypes.exe
  TARGET_IMPLIB = bin\dtypes.lib
  TARGET_PDB = bin\dtypes.pdb

Note it was set as a CFLAG here - upon a further amount of googling, it appears to be the "more correct" way of doing it

@hyoklee
Copy link
Member

hyoklee commented Jan 31, 2025

@anthony-linaro , thank you so much for going extra miles in testing!

Interestingly, I don't see any link issue with your PR + enabling wider tooling configuration for cross-compilation:

https://my.cdash.org/viewBuildError.php?buildid=2803684

I'm using the latest 🌶️ Windows 2025 GitHub Action:

https://github.com/hyoklee/actions/actions/runs/13077623330/workflow

I wish I have the same real machine to help you further.

@hyoklee - Yes, those are the same errors

I've been looking at enabling wider tooling with the following command line:

cmake -G"Ninja" -DCMAKE_BUILD_TYPE:STRING=Debug -DBUILD_STATIC_EXECS=ON -DHDF5_BUILD_CPP_LIB=ON -DHDF5_BUILD_PARALLEL_TOOLS=ON -DHDF5_BUILD_STATIC_TOOLS=ON -DBUILD_TESTING:BOOL=ON -DHDF5_BUILD_TOOLS:BOOL=ON ..

Sadly, even with /Gy specified, it still seems to be throwing those errors on my machine when building those extra libraries - does your build on cdash build additional things like the CPP lib too?

@anthony-linaro
Copy link
Author

@hyoklee If it works for you when doing cross-compilation, that is fine - is this mergeable as-is, or should I go with the others' reviews, and try and re-organise where I set the /Gy flag?

@hyoklee
Copy link
Member

hyoklee commented Feb 11, 2025

Hi, @anthony-linaro , I'm fine as is as you an see that I've already approved it.

@byrnHDF byrnHDF self-assigned this Feb 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants