onnxruntime/tools/python/util/vcpkg_helpers.py
Changming Sun 059859e105 update
2025-02-07 14:44:34 -08:00

372 lines
No EOL
16 KiB
Python

import os
from pathlib import Path
# provide build options for vcpkg installed packages
def add_port_configs(f, has_exception):
f.write(
r"""if(PORT MATCHES "onnx")
list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS
"-DONNX_DISABLE_STATIC_REGISTRATION=ON"
)
endif()
if(PORT MATCHES "benchmark")
list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS
"-DBENCHMARK_ENABLE_WERROR=OFF"
)
endif()
"""
)
if not has_exception:
f.write(
r"""if(PORT MATCHES "onnx")
list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS
"-DONNX_DISABLE_EXCEPTIONS=ON"
)
endif()
"""
)
def generate_triplet_for_posix_platform(
build_dir, os_name, enable_rtti, enable_exception, enable_binskim, enable_asan, crt_linkage, target_abi
):
folder_name_parts = []
if enable_asan:
folder_name_parts.append("asan")
if enable_binskim:
folder_name_parts.append("binskim")
if not enable_rtti:
folder_name_parts.append("nortti")
if not enable_exception:
folder_name_parts.append("noexception")
if len(folder_name_parts) == 0:
folder_name = "default"
else:
folder_name = "_".join(folder_name_parts)
file_name_parts = [target_abi, os_name]
file_name = "-".join(file_name_parts) + ".cmake"
dest_path = Path(build_dir) / folder_name / file_name
print(f"Creating file {dest_path}")
os.makedirs(dest_path.parent, exist_ok=True)
with open(dest_path, "w", encoding="utf-8") as f:
add_copyright_header(f)
if os_name == "android":
if target_abi == "arm-neon":
f.write("set(VCPKG_TARGET_ARCHITECTURE arm)\n")
f.write(
"set(VCPKG_MAKE_BUILD_TRIPLET --host=armv7a-linux-androideabi)\n"
)
f.write(
"list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS -DANDROID_ABI=armeabi-v7a -DANDROID_ARM_NEON=ON -DCMAKE_ANDROID_ARM_NEON=ON)\n"
)
elif target_abi == "arm64":
f.write("set(VCPKG_TARGET_ARCHITECTURE arm64)\n")
f.write("set(VCPKG_MAKE_BUILD_TRIPLET --host=aarch64-linux-android)\n")
f.write(
"list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS -DANDROID_ABI=arm64-v8a)\n"
)
elif target_abi == "x64":
f.write("set(VCPKG_TARGET_ARCHITECTURE x64)\n")
f.write("set(VCPKG_MAKE_BUILD_TRIPLET --host=x86_64-linux-android)\n")
f.write(
"list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS -DANDROID_ABI=x86_64)\n"
)
elif target_abi == "x86":
f.write("set(VCPKG_TARGET_ARCHITECTURE x86)\n")
f.write("set(VCPKG_MAKE_BUILD_TRIPLET --host=i686-linux-android)\n")
f.write(
"list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS -DANDROID_ABI=x86)\n"
)
f.write(
"list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS -DANDROID_USE_LEGACY_TOOLCHAIN_FILE=false -DANDROID_PLATFORM=android-24 -DANDROID_MIN_SDK=24)\n"
)
elif target_abi == "universal2":
# Assume the host machine is Intel based
f.write("set(VCPKG_TARGET_ARCHITECTURE x64)\n")
else:
f.write(f"set(VCPKG_TARGET_ARCHITECTURE {target_abi})\n")
f.write(f"set(VCPKG_CRT_LINKAGE {crt_linkage})\n")
f.write("set(VCPKG_LIBRARY_LINKAGE static)\n")
if enable_binskim and os_name == "linux":
ldflags = [
"-Wl,-Bsymbolic-functions",
"-Wl,-z,relro",
"-Wl,-z,now",
"-Wl,-z,noexecstack",
]
else:
ldflags = []
# Enable debug info for all build configs
cflags = ["-g", "-ffunction-sections", "-fdata-sections"]
cflags_release = ["-DNDEBUG", "-O3"]
if enable_binskim:
# A warning may be generated from include/features.h if the _FORTIFY_SOURCE flag was used in a debug build
cflags_release += [
"-Wp,-D_FORTIFY_SOURCE=2",
"-Wp,-D_GLIBCXX_ASSERTIONS",
"-fstack-protector-strong",
]
if target_abi == "x64":
cflags_release += ["-fstack-clash-protection", "-fcf-protection"]
elif enable_asan:
cflags += ["-fsanitize=address"]
ldflags += ["-fsanitize=address"]
# Enable debug info for all build configs
ldflags.append("-g")
# Avoid unboundTypeError for WebNN EP since unbound type names are illegal with RTTI disabled
# in Embind API, relevant issue: https://github.com/emscripten-core/emscripten/issues/7001
if not enable_rtti:
cflags.append("-DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0")
cxxflags = cflags.copy()
if not enable_rtti:
if os_name == "android":
f.write(
"list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS -DCMAKE_ANDROID_RTTI=OFF)\n"
)
else:
cxxflags.append("-fno-rtti")
if not enable_exception:
cxxflags += ["-fno-exceptions", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables"]
if len(cflags) >= 1:
f.write('set(VCPKG_C_FLAGS "{}")\n'.format(" ".join(cflags)))
if len(cxxflags) >= 1:
f.write('set(VCPKG_CXX_FLAGS "{}")\n'.format(" ".join(cxxflags)))
if len(cflags_release) >= 1:
f.write(
'set(VCPKG_C_FLAGS_RELEASE "{}")\n'.format(" ".join(cflags_release))
)
f.write(
'set(VCPKG_CXX_FLAGS_RELEASE "{}")\n'.format(" ".join(cflags_release))
)
f.write(
'set(VCPKG_C_FLAGS_RELWITHDEBINFO "{}")\n'.format(" ".join(cflags_release))
)
f.write(
'set(VCPKG_CXX_FLAGS_RELWITHDEBINFO "{}")\n'.format(" ".join(cflags_release))
)
if os_name == "linux":
f.write("set(VCPKG_CMAKE_SYSTEM_NAME Linux)\n")
elif os_name == "android":
f.write("set(VCPKG_CMAKE_SYSTEM_NAME Android)\n")
else:
f.write("set(VCPKG_CMAKE_SYSTEM_NAME Darwin)\n")
osx_abi = None
if target_abi == "x64":
osx_abi = "x86_64"
elif target_abi == "universal2":
osx_abi = "x86_64;arm64"
else:
osx_abi = target_abi
f.write(f'set(VCPKG_OSX_ARCHITECTURES "{osx_abi}")\n')
f.write("set(CMAKE_POSITION_INDEPENDENT_CODE ON)\n")
f.write(
"list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS --compile-no-warning-as-error -DBENCHMARK_ENABLE_WERROR=OFF)\n"
)
if ldflags:
f.write('set(VCPKG_LINKER_FLAGS "{}")\n'.format(" ".join(ldflags)))
if os_name == "osx":
f.write(
"list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS -DCMAKE_CXX_STANDARD=20)\n"
)
else:
f.write(
"list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS -DCMAKE_CXX_STANDARD=17)\n"
)
add_port_configs(f, enable_exception)
# provide build options for vcpkg installed packages
def add_copyright_header(f):
f.write(
r"""# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
"""
)
def generate_vcpkg_triplets_for_emscripten(build_dir, emscripten_root):
# Gen WASM triplets
for enable_rtti in [True, False]:
for enable_asan in [True, False]:
for target_abi in ["wasm32", "wasm64"]:
folder_name_parts = []
if enable_asan:
folder_name_parts.append("asan")
if len(folder_name_parts) == 0:
folder_name = "default"
else:
folder_name = "_".join(folder_name_parts)
os_name = "emscripten"
folder_name_parts = []
if enable_asan:
folder_name_parts.append("asan")
if not enable_rtti:
folder_name_parts.append("nortti")
if len(folder_name_parts) == 0:
folder_name = "default"
else:
folder_name = "_".join(folder_name_parts)
file_name_parts = [target_abi, os_name]
file_name = "-".join(file_name_parts) + ".cmake"
dest_path = Path(build_dir) / folder_name / file_name
print(f"Creating file {dest_path}")
os.makedirs(dest_path.parent, exist_ok=True)
with open(dest_path, "w", encoding="utf-8") as f:
add_copyright_header(f)
f.write(r"""
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Emscripten)
""")
f.write(f"set(VCPKG_TARGET_ARCHITECTURE {target_abi})\n")
emscripten_root_path_cmake_path = emscripten_root.replace("\\","/")
f.write(f"set(EMSCRIPTEN_ROOT_PATH \"{emscripten_root_path_cmake_path}\")\n")
vcpkg_toolchain_file = (Path(build_dir) / "emsdk_vcpkg_toolchain.cmake").absolute()
vcpkg_toolchain_file_cmake_path = str(vcpkg_toolchain_file).replace("\\","/")
f.write(f"set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE \"{vcpkg_toolchain_file_cmake_path}\")\n")
cflags_release = ["-DNDEBUG", "-O3", "-pthread"]
ldflags = []
cflags = ["-ffunction-sections", "-fdata-sections", "-msimd128", "-pthread", "-Wno-pthreads-mem-growth"]
if enable_asan:
cflags += ["-fsanitize=address"]
ldflags += ["-fsanitize=address"]
if target_abi == 'wasm64':
cflags.append("-sMEMORY64")
ldflags.append("-sMEMORY64")
cxxflags = cflags.copy()
if len(cflags) >= 1:
f.write('set(VCPKG_C_FLAGS "{}")\n'.format(" ".join(cflags)))
if len(cxxflags) >= 1:
f.write('set(VCPKG_CXX_FLAGS "{}")\n'.format(" ".join(cxxflags)))
if len(cflags_release) >= 1:
cflags_release += cflags
f.write(
'set(VCPKG_C_FLAGS_RELEASE "{}")\n'.format(" ".join(cflags_release))
)
f.write(
'set(VCPKG_CXX_FLAGS_RELEASE "{}")\n'.format(" ".join(cflags_release))
)
f.write(
'set(VCPKG_C_FLAGS_RELWITHDEBINFO "{}")\n'.format(" ".join(cflags_release))
)
f.write(
'set(VCPKG_CXX_FLAGS_RELWITHDEBINFO "{}")\n'.format(" ".join(cflags_release))
)
def generate_vcpkg_triplets(build_dir):
# Gen Windows triplets
target_abis = ["x86", "x64", "arm64", "arm64ec"]
crt_linkages = ["static", "dynamic"]
for enable_rtti in [True, False]:
for enable_binskim in [True, False]:
for enable_asan in [True, False]:
for crt_linkage in crt_linkages:
# Address Sanitizer libs do not have a Qspectre version. So they two cannot be both enabled.
if enable_asan and enable_binskim:
continue
for target_abi in target_abis:
folder_name_parts = []
if enable_asan:
folder_name_parts.append("asan")
if enable_binskim:
folder_name_parts.append("binskim")
if not enable_rtti:
folder_name_parts.append("nortti")
if len(folder_name_parts) == 0:
folder_name = "default"
else:
folder_name = "_".join(folder_name_parts)
file_name_parts = [target_abi, "windows", "static"]
if crt_linkage == "dynamic":
file_name_parts.append("md")
file_name = "-".join(file_name_parts) + ".cmake"
dest_path = Path(build_dir) / folder_name / file_name
print(f"Creating file {dest_path}")
os.makedirs(dest_path.parent, exist_ok=True)
with open(dest_path, "w", encoding="utf-8") as f:
add_copyright_header(f)
f.write(f"set(VCPKG_TARGET_ARCHITECTURE {target_abi})\n")
f.write(f"set(VCPKG_CRT_LINKAGE {crt_linkage})\n")
# we only support static. The default triplets use dynamic.
# The default triplets do not work with asan(protoc.exe crashes at startup). Therefore we do not override the default triplets and do not append asan to them.
# The default triplets are used for generating host dependencies(such as protoc.exe)
f.write("set(VCPKG_LIBRARY_LINKAGE static)\n")
cflags = ["/MP", "/DWIN32", "/D_WINDOWS"]
# TODO: if not gdk
cflags += [
"/DWINAPI_FAMILY=100",
"/DWINVER=0x0A00",
"/D_WIN32_WINNT=0x0A00",
"/DNTDDI_VERSION=0x0A000000",
]
cxxflags = None
ldflags = None
cflags += []
if enable_binskim:
# "/W3" is for https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings
cflags += ["/guard:cf", "/Qspectre", "/W3"]
ldflags = ["/profile", "/DYNAMICBASE"]
elif enable_asan:
cflags.append("/fsanitize=address")
cxxflags = cflags.copy()
cxxflags.append("/Zc:__cplusplus")
if not enable_rtti:
# Disable RTTI and turn usage of dynamic_cast and typeid into errors
cxxflags += ["/GR-", "/we4541"]
# TODO: should it be a cmake list separated by semicolons?
if len(cflags) >= 1:
f.write(
'set(VCPKG_C_FLAGS "{}")\n'.format(" ".join(cflags))
)
if len(cxxflags) >= 1:
f.write(
'set(VCPKG_CXX_FLAGS "{}")\n'.format(" ".join(cxxflags))
)
f.write(
"list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS --compile-no-warning-as-error -DCMAKE_CXX_STANDARD=17)\n"
)
if ldflags:
f.write(
'set(VCPKG_LINKER_FLAGS "{}")\n'.format(
" ".join(ldflags)
)
)
add_port_configs(f, True)
# Gen Linux/MacOS/Android triplets
crt_linkages = ["static", "dynamic"]
for os_name in ["linux", "osx", "android"]:
if os_name == "android":
target_abis = ["x64", "arm64", "arm-neon", "x86"]
crt_linkages = ["static"]
elif os_name == "linux":
target_abis = ["x64", "arm64"]
crt_linkages = ["dynamic"]
else:
target_abis = ["x64", "arm64", "universal2"]
crt_linkages = ["dynamic"]
for enable_rtti in [True, False]:
for enable_exception in [True, False]:
for enable_binskim in [False] if os_name == "android" else [True, False]:
for enable_asan in [True, False]:
if enable_asan and enable_binskim:
continue
for crt_linkage in crt_linkages:
for target_abi in target_abis:
generate_triplet_for_posix_platform(
build_dir,
os_name,
enable_rtti,
enable_exception,
enable_binskim,
enable_asan,
crt_linkage,
target_abi,
)