Обучение
Модуль
Узнайте, как пакет SDK семантического ядра подключает машинный код к большим языковым моделям для создания смарт-приложений.
Этот браузер больше не поддерживается.
Выполните обновление до Microsoft Edge, чтобы воспользоваться новейшими функциями, обновлениями для системы безопасности и технической поддержкой.
Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Вы можете создавать двоичные файлы Arm64X, также известные как файлы PE Arm64X, чтобы поддерживать загрузку одного двоичного файла в процессы x64/Arm64EC и Arm64.
Чтобы включить сборку двоичных файлов Arm64X, страницы свойств конфигурации Arm64EC имеют новое свойство Build Project as ARM64X, известное как BuildAsX
в файле проекта.
Когда пользователь создает проект, Visual Studio обычно компилируется для Arm64EC, а затем связывает выходные данные с двоичным файлом Arm64EC. Если BuildAsX
задано значение true
, Visual Studio будет выполнять компиляцию для Arm64EC и для Arm64. Затем этап объединения Arm64EC используется для связывания обоих в единый двоичный файл Arm64X. Выходной каталог для этого двоичного файла Arm64X будет таким же, каким он задан в конфигурации Arm64EC.
Для BuildAsX
правильной работы пользователь должен иметь существующую конфигурацию Arm64 в дополнение к конфигурации Arm64EC. Конфигурации Arm64 и Arm64EC должны иметь одну и ту же среду выполнения C и стандартную библиотеку C++ (например, оба набора /MT). Чтобы избежать неэффективности сборки, например создания полных проектов Arm64, а не просто компиляции, все прямые и косвенные ссылки на проект должны иметь BuildAsX
значение true.
В системе сборки предполагается, что конфигурации Arm64 и Arm64EC имеют то же имя. Если конфигурации Arm64 и Arm64EC имеют разные имена (например Debug|ARM64
, и MyDebug|ARM64EC
), можно вручную изменить vcxproj или Directory.Build.props
файл, чтобы добавить ARM64ConfigurationNameForX
свойство в конфигурацию Arm64EC, которая предоставляет имя конфигурации Arm64.
Если нужный двоичный файл Arm64X является сочетанием двух отдельных проектов, один проект как Arm64, а другой как Arm64EC, можно вручную изменить vcxproj проекта Arm64EC, чтобы добавить свойство ARM64ProjectForX
и указать путь к проекту Arm64. Два проекта должны находиться в одном решении.
Чтобы создать двоичные файлы проекта CMake в качестве Arm64X, можно использовать любую версию CMake , которая поддерживает сборку как Arm64EC. Процедура начинается с первоначального создания проекта, нацеленного на Arm64, чтобы сгенерировать входные данные для компоновщика Arm64. Впоследствии проект должен быть снова построен с целью Arm64EC, на этот раз с объединением входных данных Arm64 и Arm64EC для формирования двоичных файлов Arm64X. Приведенные ниже действия используют использование CMakePresets.json.
Убедитесь, что у вас есть отдельные предустановки конфигурации, предназначенные для Arm64 и Arm64EC. Например:
{
"version": 3,
"configurePresets": [
{
"name": "windows-base",
"hidden": true,
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl.exe",
"CMAKE_CXX_COMPILER": "cl.exe"
},
"generator": "Visual Studio 17 2022",
},
{
"name": "arm64-debug",
"displayName": "arm64 Debug",
"inherits": "windows-base",
"hidden": true,
"architecture": {
"value": "arm64",
"strategy": "set"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "arm64ec-debug",
"displayName": "arm64ec Debug",
"inherits": "windows-base",
"hidden": true,
"architecture": {
"value": "arm64ec",
"strategy": "set"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
}
]
}
Добавьте две новые конфигурации, наследуемые от предустановок Arm64 и Arm64EC, которые вы создали выше. Задайте значение BUILD_AS_ARM64X
ARM64EC
в конфигурации, наследуемой от Arm64EC и BUILD_AS_ARM64X
ARM64
в другой. Эти переменные будут использоваться для обозначения того, что сборки из этих двух предустановок являются частью Arm64X.
{
"name": "arm64-debug-x",
"displayName": "arm64 Debug (arm64x)",
"inherits": "arm64-debug",
"cacheVariables": {
"BUILD_AS_ARM64X": "ARM64"
},
{
"name": "arm64ec-debug-x",
"displayName": "arm64ec Debug (arm64x)",
"inherits": "arm64ec-debug",
"cacheVariables": {
"BUILD_AS_ARM64X": "ARM64EC"
}
Добавьте новый cmake-файл в проект CMake с именем arm64x.cmake
. Скопируйте приведенный ниже фрагмент в новый CMAKE-файл.
# directory where the link.rsp file generated during arm64 build will be stored
set(arm64ReproDir "${CMAKE_CURRENT_SOURCE_DIR}/repros")
# This function reads in the content of the rsp file outputted from arm64 build for a target. Then passes the arm64 libs, objs and def file to the linker using /machine:arm64x to combine them with the arm64ec counterparts and create an arm64x binary.
function(set_arm64_dependencies n)
set(REPRO_FILE "${arm64ReproDir}/${n}.rsp")
file(STRINGS "${REPRO_FILE}" ARM64_OBJS REGEX obj\"$)
file(STRINGS "${REPRO_FILE}" ARM64_DEF REGEX def\"$)
file(STRINGS "${REPRO_FILE}" ARM64_LIBS REGEX lib\"$)
string(REPLACE "\"" ";" ARM64_OBJS "${ARM64_OBJS}")
string(REPLACE "\"" ";" ARM64_LIBS "${ARM64_LIBS}")
string(REPLACE "\"" ";" ARM64_DEF "${ARM64_DEF}")
string(REPLACE "/def:" "/defArm64Native:" ARM64_DEF "${ARM64_DEF}")
target_sources(${n} PRIVATE ${ARM64_OBJS})
target_link_options(${n} PRIVATE /machine:arm64x "${ARM64_DEF}" "${ARM64_LIBS}")
endfunction()
# During the arm64 build, create link.rsp files that containes the absolute path to the inputs passed to the linker (objs, def files, libs).
if("${BUILD_AS_ARM64X}" STREQUAL "ARM64")
add_custom_target(mkdirs ALL COMMAND cmd /c (if not exist \"${arm64ReproDir}/\" mkdir \"${arm64ReproDir}\" ))
foreach (n ${ARM64X_TARGETS})
add_dependencies(${n} mkdirs)
# tell the linker to produce this special rsp file that has absolute paths to its inputs
target_link_options(${n} PRIVATE "/LINKREPROFULLPATHRSP:${arm64ReproDir}/${n}.rsp")
endforeach()
# During the ARM64EC build, modify the link step appropriately to produce an arm64x binary
elseif("${BUILD_AS_ARM64X}" STREQUAL "ARM64EC")
foreach (n ${ARM64X_TARGETS})
set_arm64_dependencies(${n})
endforeach()
endif()
/LINKREPROFULLPATHRSP поддерживается только в том случае, если вы используете компоновщик MSVC из Visual Studio 17.11 или более поздней версии.
Если вам нужно использовать старый компоновщик, скопируйте приведенный ниже фрагмент кода. Этот маршрут использует старый флаг /LINK_REPRO. Использование маршрута /LINK_REPRO приведет к замедлению общего времени сборки из-за копирования файлов и известных проблем при использовании генератора Ninja.
# directory where the link_repro directories for each arm64x target will be created during arm64 build.
set(arm64ReproDir "${CMAKE_CURRENT_SOURCE_DIR}/repros")
# This function globs the linker input files that was copied into a repro_directory for each target during arm64 build. Then it passes the arm64 libs, objs and def file to the linker using /machine:arm64x to combine them with the arm64ec counterparts and create an arm64x binary.
function(set_arm64_dependencies n)
set(ARM64_LIBS)
set(ARM64_OBJS)
set(ARM64_DEF)
set(REPRO_PATH "${arm64ReproDir}/${n}")
if(NOT EXISTS "${REPRO_PATH}")
set(REPRO_PATH "${arm64ReproDir}/${n}_temp")
endif()
file(GLOB ARM64_OBJS "${REPRO_PATH}/*.obj")
file(GLOB ARM64_DEF "${REPRO_PATH}/*.def")
file(GLOB ARM64_LIBS "${REPRO_PATH}/*.LIB")
if(NOT "${ARM64_DEF}" STREQUAL "")
set(ARM64_DEF "/defArm64Native:${ARM64_DEF}")
endif()
target_sources(${n} PRIVATE ${ARM64_OBJS})
target_link_options(${n} PRIVATE /machine:arm64x "${ARM64_DEF}" "${ARM64_LIBS}")
endfunction()
# During the arm64 build, pass the /link_repro flag to linker so it knows to copy into a directory, all the file inputs needed by the linker for arm64 build (objs, def files, libs).
# extra logic added to deal with rebuilds and avoiding overwriting directories.
if("${BUILD_AS_ARM64X}" STREQUAL "ARM64")
foreach (n ${ARM64X_TARGETS})
add_custom_target(mkdirs_${n} ALL COMMAND cmd /c (if exist \"${arm64ReproDir}/${n}_temp/\" rmdir /s /q \"${arm64ReproDir}/${n}_temp\") && mkdir \"${arm64ReproDir}/${n}_temp\" )
add_dependencies(${n} mkdirs_${n})
target_link_options(${n} PRIVATE "/LINKREPRO:${arm64ReproDir}/${n}_temp")
add_custom_target(${n}_checkRepro ALL COMMAND cmd /c if exist \"${n}_temp/*.obj\" if exist \"${n}\" rmdir /s /q \"${n}\" 2>nul && if not exist \"${n}\" ren \"${n}_temp\" \"${n}\" WORKING_DIRECTORY ${arm64ReproDir})
add_dependencies(${n}_checkRepro ${n})
endforeach()
# During the ARM64EC build, modify the link step appropriately to produce an arm64x binary
elseif("${BUILD_AS_ARM64X}" STREQUAL "ARM64EC")
foreach (n ${ARM64X_TARGETS})
set_arm64_dependencies(${n})
endforeach()
endif()
В нижней части файла верхнего уровня CMakeLists.txt
в проекте добавьте приведенный ниже фрагмент кода. Обязательно замените содержимое угловых квадратных скобок фактическими значениями. При этом будет использоваться файл, который вы только что создали выше arm64x.cmake
.
if(DEFINED BUILD_AS_ARM64X)
set(ARM64X_TARGETS <Targets you want to Build as ARM64X>)
include("<directory location of the arm64x.cmake file>/arm64x.cmake")
endif()
Создайте проект CMake с помощью предустановки Arm64X с поддержкой Arm64 (arm64-debug-x).
Создайте проект CMake с помощью предустановки Arm64X с поддержкой Arm64EC (arm64ec-debug-x). Окончательные библиотеки DLL, содержащиеся в выходном каталоге в этой сборке, будут бинарными файлами Arm64X.
Чистая DLL переадресатора Arm64X — это небольшая Arm64X DLL, которая перенаправляет API в отдельные DLL в зависимости от их типа.
API Arm64 перенаправляются в библиотеку DLL Arm64.
API x64 перенаправляются в библиотеку DLL x64 или Arm64EC.
Чистое средство пересылки Arm64X позволяет использовать двоичный файл Arm64X даже при возникновении проблем с созданием объединенного двоичного файла Arm64X, содержащего весь код Arm64EC и Arm64. Узнайте больше о библиотеках DLL Arm64X pure forwarder на странице обзора файлов PE для Arm64X.
Вы можете создать чистый сервер пересылки Arm64X из командной строки разработчика Arm64, выполнив указанные ниже действия. Результирующий чистый пересылатель Arm64X будет направлять вызовы x64 на foo_x64.DLL
, а вызовы Arm64 на foo_arm64.DLL
.
Создайте пустые OBJ
файлы, которые будут использоваться линкером для создания чистого форвардера. Они пусты, так как чистый сервер пересылки не имеет в нем кода. Для этого создайте пустой файл. В приведенном ниже примере мы назвали файл empty.cpp. Затем пустые OBJ
файлы создаются с помощью cl
одного для Arm64 (empty_arm64.obj
) и одного для Arm64EC (empty_x64.obj
):
cl /c /Foempty_arm64.obj empty.cpp
cl /c /arm64EC /Foempty_x64.obj empty.cpp
Если появится сообщение об ошибке "cl: предупреждение командной строки D9002: игнорировать неизвестный параметр -arm64EC", используется неверный компилятор. Чтобы устранить эту проблему, перейдите в командную строку разработчика Arm64.
Создайте DEF
файлы для x64 и Arm64. Эти файлы перечисляют все экспорты API библиотеки DLL и указывают загрузчику имя библиотеки DLL, которая может выполнять эти вызовы API.
foo_x64.def
:
EXPORTS
MyAPI1 = foo_x64.MyAPI1
MyAPI2 = foo_x64.MyAPI2
foo_arm64.def
:
EXPORTS
MyAPI1 = foo_arm64.MyAPI1
MyAPI2 = foo_arm64.MyAPI2
Затем вы можете использовать link
для создания LIB
файлов импорта как для x64, так и для Arm64.
link /lib /machine:x64 /def:foo_x64.def /out:foo_x64.lib
link /lib /machine:arm64 /def:foo_arm64.def /out:foo_arm64.lib
Свяжите пустые OBJ
файлы и импортируйте LIB
файлы с помощью флага /MACHINE:ARM64X
для создания перенаправляющей DLL Arm6X.
link /dll /noentry /machine:arm64x /defArm64Native:foo_arm64.def /def:foo_x64.def empty_arm64.obj empty_x64.obj /out:foo.dll foo_arm64.lib foo_x64.lib
Полученный foo.dll
можно загрузить в процесс Arm64 или x64/Arm64EC. При загрузке процесса Arm64 операционная система немедленно загружает foo_arm64.dll
на его место, и все вызовы API будут обрабатываться foo_arm64.dll
.
Отзыв о Windows on Arm
Windows on Arm — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв:
Обучение
Модуль
Узнайте, как пакет SDK семантического ядра подключает машинный код к большим языковым моделям для создания смарт-приложений.
События
Присоединение к вызову ИИ Навыков
8 апр., 15 - 28 мая, 07
Отточите свои навыки ИИ и введите подметки, чтобы выиграть бесплатный экзамен сертификации
Зарегистрируйтесь!