-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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 cross-generator fixes #2790
Changes from 8 commits
2db77a6
8e3aa0c
a3591f8
177aee0
1547006
42f701c
125667d
5c39112
d856b56
1809c22
76b3259
53ba310
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,22 @@ else() | |
endif() | ||
endif() | ||
|
||
if(CMAKE_GENERATOR_PLATFORM) | ||
# Multi-platform generator | ||
set(onnxruntime_target_platform ${CMAKE_GENERATOR_PLATFORM}) | ||
else() | ||
set(onnxruntime_target_platform ${CMAKE_SYSTEM_PROCESSOR}) | ||
endif() | ||
if(onnxruntime_target_platform STREQUAL "ARM64") | ||
set(onnxruntime_target_platform "ARM64") | ||
elseif(onnxruntime_target_platform STREQUAL "ARM" OR CMAKE_GENERATOR MATCHES "ARM") | ||
set(onnxruntime_target_platform "ARM") | ||
elseif(onnxruntime_target_platform STREQUAL "x64" OR onnxruntime_target_platform STREQUAL "x86_64" OR onnxruntime_target_platform STREQUAL "AMD64" OR CMAKE_GENERATOR MATCHES "Win64") | ||
set(onnxruntime_target_platform "x64") | ||
elseif(onnxruntime_target_platform STREQUAL "x86" OR onnxruntime_target_platform STREQUAL "i386" OR onnxruntime_target_platform STREQUAL "i686") | ||
set(onnxruntime_target_platform "x86") | ||
endif() | ||
|
||
Comment on lines
+53
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit ugly, but we must take into consideration possible values of CMAKE_GENERATOR_PLATFORM (platform in multi-platform generators), CMAKE_SYSTEM_PROCESSOR (target CPU in single platform generators) and CMAKE_GENERATOR, and CMAKE_SYSTEM_PROCESSOR can take a range of values (from docs: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be checking There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For older versions of the VS CMake generator, the platform is part of the generator string. See
|
||
file(GLOB onnxruntime_common_src CONFIGURE_DEPENDS | ||
${onnxruntime_common_src_patterns} | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,7 @@ | |
# header name as input. The function will generate a .cpp file that includes the header and is used | ||
# to generate the precompiled header; this source file is added to the target's sources. | ||
function(target_precompiled_header target_name header_name) | ||
if (MSVC) | ||
|
||
if (MSVC AND CMAKE_VS_PLATFORM_TOOLSET) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PCHs should work under ninja, but the way it's built is currently broken (it writes a file named ${header_base_name}.cpp. Problem is that there are multiple pchs called pch.h in WinML, which when built in parallel leads to Ninja giving permission denied or internal compiler errors when trying to write pch.cpp at the same time). So this was already broken, but happened to work under msbuild. We should fix the repo to remove headers with duplicate names. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. curious - why can't headers with the same name exist in different folders? that seems like it should be supported. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could be supported, it's just that right now it writes pch.cpp to |
||
# The input precompiled header source (i.e. the '.h' file used for the precompiled header). | ||
set(pch_header_path ${header_name}) | ||
get_filename_component(header_base_name ${header_name} NAME_WE) | ||
|
@@ -14,14 +13,14 @@ function(target_precompiled_header target_name header_name) | |
set(pch_source_content "// THIS FILE IS GENERATED BY CMAKE\n#include \"${pch_header_path}\"") | ||
file(WRITE ${pch_source_path} ${pch_source_content}) | ||
set_source_files_properties(${pch_source_path} PROPERTIES COMPILE_FLAGS "/Yc${pch_header_path}") | ||
|
||
# The target's C++ sources use the precompiled header (/Yu). Source-level properties will | ||
# take precedence over target-level properties, so this will not change the generated source | ||
# take precedence over target-level properties, so this will not change the generated source | ||
# file's property to create the precompiled header (/Yc). | ||
target_compile_options(${target_name} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/Yu${header_name}>) | ||
|
||
# Append generated precompiled source to target's sources. | ||
target_sources(${target_name} PRIVATE ${pch_source_path}) | ||
endif(MSVC) | ||
endfunction() | ||
|
||
endif() | ||
endfunction() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -132,7 +132,7 @@ list(APPEND winml_adapter_files | |
${winml_adapter_dir}/WinMLAdapter.cpp | ||
${winml_adapter_dir}/WinMLAdapter.h | ||
${winml_adapter_dir}/ZeroCopyInputStreamWrapper.cpp | ||
${winml_adapter_dir}/ZeroCopyInputStreamWrapper.h | ||
${winml_adapter_dir}/ZeroCopyInputStreamWrapper.h | ||
) | ||
|
||
if (onnxruntime_USE_DML) | ||
|
@@ -159,6 +159,7 @@ add_dependencies(winml_adapter ${onnxruntime_EXTERNAL_DEPENDENCIES}) | |
target_precompiled_header(winml_adapter pch.h) | ||
|
||
# Includes | ||
target_include_directories(winml_adapter PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) # windows machine learning generated component headers | ||
target_include_directories(winml_adapter PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api) # windows machine learning generated component headers | ||
target_include_directories(winml_adapter PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api/comp_generated) # windows machine learning generated component headers | ||
target_include_directories(winml_adapter PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml/sdk/cppwinrt/include) # sdk cppwinrt headers | ||
|
@@ -181,7 +182,7 @@ add_dependencies(winml_adapter winml_api_native_internal) | |
# Link libraries | ||
target_link_libraries(winml_adapter PRIVATE wil) | ||
if (onnxruntime_USE_DML) | ||
target_link_libraries(winml_adapter PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/packages/DirectML.0.0.1/build/DirectML.targets) | ||
target_add_dml(winml_adapter) | ||
endif(onnxruntime_USE_DML) | ||
|
||
# add it to the onnxruntime shared library | ||
|
@@ -230,6 +231,7 @@ target_compile_definitions(winml_lib_image PRIVATE _SCL_SECURE_NO_WARNINGS) | |
target_precompiled_header(winml_lib_image pch.h) | ||
|
||
# Includes | ||
target_include_directories(winml_lib_image PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) # windows machine learning generated component headers | ||
target_include_directories(winml_lib_image PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api) # windows machine learning generated component headers | ||
target_include_directories(winml_lib_image PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api/comp_generated) # windows machine learning generated component headers | ||
target_include_directories(winml_lib_image PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml/sdk/cppwinrt/include) # sdk cppwinrt headers | ||
|
@@ -258,7 +260,7 @@ add_dependencies(winml_lib_image winml_api_native_internal) | |
# Link libraries | ||
target_link_libraries(winml_lib_image PRIVATE wil) | ||
if (onnxruntime_USE_DML) | ||
target_link_libraries(winml_lib_image PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/packages/DirectML.0.0.1/build/DirectML.targets) | ||
target_add_dml(winml_lib_image) | ||
endif(onnxruntime_USE_DML) | ||
|
||
|
||
|
@@ -360,7 +362,7 @@ add_dependencies(winml_lib_api winml_api_native_internal) | |
# Link libraries | ||
target_link_libraries(winml_lib_api PRIVATE wil) | ||
if (onnxruntime_USE_DML) | ||
target_link_libraries(winml_lib_api PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/packages/DirectML.0.0.1/build/DirectML.targets) | ||
target_add_dml(winml_lib_api) | ||
endif(onnxruntime_USE_DML) | ||
|
||
|
||
|
@@ -472,6 +474,7 @@ target_link_libraries(winml_dll PRIVATE winml_lib_api) | |
target_link_libraries(winml_dll PRIVATE winml_lib_image) | ||
target_link_libraries(winml_dll PRIVATE winml_lib_telemetry) | ||
target_link_libraries(winml_dll PRIVATE onecoreuap_apiset.lib) | ||
target_link_libraries(winml_dll PRIVATE delayimp.lib) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does this do? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Linking was failing due to missing a implementation of I don't know why it worked with msbuild, maybe it added delayimp.lib automatically? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you make sure this doesn't add dependencies on desktop-only binaries? We need to build for onecore-based SKUs as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll run msbuild and look at its linker command line to find out why it works there and not with ninja. If I find out that delayimp is really needed, how can I test in other platforms to make sure I didn't berak non-desktop builds? |
||
target_link_libraries(winml_dll PRIVATE ${DBGHELP}) | ||
|
||
# 1 of 3 projects that fail in link with 'failed to do memory mapped file I/O' (Only release) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ninja failed with ninja:
error: 'packages/DirectML.0.0.1/bin/x64/DirectML.lib', needed by 'onnxruntime.lib', missing and no known rule to make it
, given that it didn't know how to get DirectML.lib which was a dep of ORT.With msbuild it just happened to not check if it could satisfy all dependencies first and happened to run the RESTORE_PACKAGES target before building ORT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to pull down both x64 and x86 all the time (is that what this does?)? also, what about arm/arm64?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I'm declaring that this command will output x64/DirectML.lib and x86/DirectML.lib ; if any target depends on either of those, the package will be downloaded using Nuget. There's a single nuget package with both, no option to pull them separatly.
ARM is not supported, I was talking to Sheil about it last week. DML distributes a redist package with x86 and x64 DML, but this public redist package doesn't have ARM (seems like they didn't have a need for it and didn't want to build and maintain it if no customers are using it. We were not sure if that's the only reason, we can talk to the DML folks if we need an ARM redist package)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the intention was to have onnxruntime depend on onnxruntime_EXTERNAL_DEPENDENCIES, which implicitly includes the DML libs. This change looks fine too, and it's more explicit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's right, but it doesn't work with ninja. ORT links with DirectML.lib, which doesn't exist when doing a clean build because the nuget package isn't downloaded yet, and there is no rule on how to generate DirectML.lib, so it says
error: 'packages/DirectML.0.0.1/bin/x64/DirectML.lib', needed by 'onnxruntime.lib', missing and no known rule to make it
.Depending on onnxruntime_EXTERNAL_DEPENDENCIES will eventually pull DirectML.lib, but there's no way the build system knows about it before pulling and unpacking the package. It seems like msbuild doesn't validate that it can actually resolve everything before starting the build, so it worked before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I originally set this up, cmake actually had a similar problem. It barfed when trying to target_link_libraries the DirectML.targets file, because the nuget package hadn't been downloaded yet (and therefore the targets file didn't exist).
This was solved by adding an explicit step into build.py which invokes the RESTORE_PACKAGES step prior to running the "real" build. This ensures that when the build starts, the nuget package is already present.
Why doesn't that solution work in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh sure, that also works. I didn't realize RESTORE_PACKAGES was explicitly called in build.py.
I was running the ninja build "by hand" (calling cmake followed by cmake --build or configuring the cmake project in VS directly).
Is there a reason not to fix it the way I did?