-
Notifications
You must be signed in to change notification settings - Fork 4.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
[runtime] Infrastructure to build runtime components using NativeAOT #98565
Changes from 54 commits
663184e
d16749d
ca01640
2ad4c85
44ce176
6aad355
eb56ef6
225d05b
19d17ac
c03b37e
730dd07
472ee21
51f56b1
b6c637c
80c706d
1f6a9f7
26c33ab
f6dcfe8
b94c67a
4c7793b
ce900f1
37edeaf
a24dc46
748a84d
d77776e
e7eca1f
4149bea
11c9d90
f664970
70bc9c7
0f776cc
66f4b53
c32f8ac
556d0b5
fd04a07
f6dd13f
b06ddeb
533f183
211d683
70db261
f9b52d5
c3b231d
014a674
0c96465
bf6c499
44ba2cc
3184d6d
3835325
4b04029
77d9899
5a4be9a
7ecdca0
238ee10
d7a57b8
bf5652f
0e05f17
481a77a
de1114b
0d21d2e
7c409be
2b0850a
6dad61e
e075acd
ce1c1c7
7eff8e6
182df7a
8eb8e36
dd50ff0
bdc85a0
6aae973
003af6a
edbbe84
adc9314
3a5353b
c7b6751
a07ecaa
0cc4db4
0f90a93
0a582c2
937a173
0e3bed5
19724f1
0958981
f55ebcc
b97c391
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 |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Infrastructure to import a native aot compiled library into a native build | ||
|
||
# ## Implementation details used by libraryName-config.cmake find_package configuration | ||
# ## files. Consumers don't need to do this directly. | ||
|
||
# add_imported_nativeaot_library(targetName symbolPrefix [NAMESPACE namespace]) | ||
# | ||
# adds a target targetName that can be used to reference a NativeAOTed library. symbolPrefix should | ||
# be the ALLCAPS prefix of the variables that define the mode and paths for the library. They are | ||
# typically set in the artifacts/obj/targetName/targetName.cmake fragment which should be included | ||
# before calling this function. | ||
function(add_imported_nativeaot_library targetNameIn symbolPrefix) | ||
cmake_parse_arguments(PARSE_ARGV 2 "add_imported_opt" "" "NAMESPACE" "") | ||
message(TRACE "${symbolPrefix}_MODE is ${${symbolPrefix}_MODE}") | ||
set(targetName "${add_imported_opt_NAMESPACE}${targetNameIn}") | ||
message(TRACE "Adding target ${targetName}") | ||
|
||
if("${${symbolPrefix}_MODE}" STREQUAL "SHARED") | ||
set(libName "${${symbolPrefix}_NAME}") # typically same as targetName | ||
set(libPath "${${symbolPrefix}_LIBPATH}") # typically /.../artifacts/bin/<libName>/<config>/<rid>/publish | ||
set(libFilename "${libName}${${symbolPrefix}_EXT}") # <libName>.dll, <libName>.so or <libName>.dylib | ||
set(libFullPath "${libPath}/${libFilename}") | ||
|
||
if(CLR_CMAKE_HOST_WIN32) | ||
set(libPdbFullPath "${libPath}/${libName}.pdb") | ||
endif() | ||
|
||
# windows import library | ||
set(libImpLibFullPath "${${symbolPrefix}_IMPLIBPATH}") # typically /.../artifacts/bin/<libName>/<config>/<rid>/native/<libName>.lib | ||
|
||
set(copy_target_name "${targetNameIn}_copy_imported_library") | ||
|
||
add_imported_library_clr(${targetName} COPY_TARGET ${copy_target_name} IMPORTED_LOCATION "${libFullPath}") | ||
set_property(TARGET ${targetName} PROPERTY CLR_IMPORTED_NATIVEAOT_LIBRARY 1) | ||
|
||
if("${CLR_CMAKE_HOST_WIN32}") | ||
set_property(TARGET ${targetName} PROPERTY IMPORTED_IMPLIB "${libImpLibFullPath}") | ||
endif() | ||
|
||
set(libIncludePath "${${symbolPrefix}_INCLUDE}") | ||
target_include_directories(${targetName} INTERFACE "${libIncludePath}") | ||
else() | ||
message(FATAL_ERROR "${symbolPrefix}_MODE must be SHARED") | ||
endif() | ||
endfunction() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<Project> | ||
<Import Project="..\..\..\Directory.Build.props" /> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Native runtime component libraries using NativeAOT | ||
|
||
This directory contains managed libraries that will be compiled using NativeAOT and can be used in runtime components. | ||
|
||
## Using existing libraries | ||
|
||
In a `CMakeLists.txt` add | ||
|
||
``` cmake | ||
find_nativeaot_library(libWhatever REQUIRED) | ||
``` | ||
|
||
This will look for a cmake fragment file in | ||
`artifacts/obj/cmake/find_package/libWhatever-config.cmake` that will import some variables from | ||
`artifacts/obj/libWhatever/libWhatever.cmake` and defines a new `libWhatever::libWhatever` that can | ||
be used as a dependency in `target_link_libraries()` or in a `install_clr()` command. | ||
|
||
|
||
## Adding a new managed library | ||
|
||
Add a new subdirectory to `src/native/managed` for your library with a `src` and `inc` subdirectories: | ||
|
||
``` console | ||
$ mkdir -p libMyNewLibrary/src libMyNewLibrary/inc | ||
$ dotnet new classlib -n libMyNewLibrary -o libMyNewLibrary/src | ||
``` | ||
|
||
In `src/native/managed/compile-native.proj`, add | ||
`src/native/managed/libMyNewLibrary/src/libMyNewLibrary.csproj` to the `NativeLibsProjectsToBuild` | ||
item group. | ||
|
||
In `src/native/managed/libMyNewLibrary/src/libMyNewLibrary.csproj`: | ||
1. Near the top, add `<Import Project="..\..\native-library.props" />` | ||
2. Near the bottom, add `<Import Project="..\..\native-library.targets" />` | ||
lambdageek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The following is recommended: | ||
|
||
1. The project should be called `libXXXX` - currently the infrastructure expects a `lib` prefix on all platforms. | ||
2. The project should just have a single `EntryPoints.cs` that has a `static class` that provides | ||
`[UnmanagedCallersOnly]` API entrypoints. The bulk of the code should be imported using | ||
`ProjectReference` from another managed class library project. That managed project can be | ||
tested using normal managed unit tests, consumed in other managed libraries, etc. | ||
3. The `inc` directory if it exists will be added to the include path of any cmake targets that | ||
depend on the native library. Typically the directory should contain a `libMyNewLibrary.h` header | ||
file with a C declaration for each entrypoint. If you want ot have more include directories, add | ||
them all to the `NativeLibraryCmakeFragmentIncludePath` item. In that case `inc` won't be added | ||
by default. | ||
|
||
Limitations: | ||
|
||
Currently only shared library output is supported. In principle static linking is possible, but the | ||
infrastructure is not finished yet. Additionally, mixing Debug/Release configurations with static | ||
linking will not be supported on Windows. |
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. How do you feel about inlining these templates in MSBuild (to reduce number of moving parts)? It's just something which we considered in part infra work. e.g. in cmake we need to use the config.in template files, it is a natural fit in that world. In MSBuild, what comes natural is to write bunch of lines from targets directly somewhere under obj/ directory; without introducing some external template system. 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. @am11 an earlier version of this PR used 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. An alternative (to avoid external template and intermediate file writes) is to include |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# This is a Config-style package configuration file for cmake's find_package command for ${libArtifactName} | ||
set(CMAKE_FRAGMENT_PATH "${libArtifactConfigFragment}") | ||
|
||
include("`${CLR_ENG_NATIVE_DIR}/import-nativeaot-library.cmake") | ||
|
||
include("`${CMAKE_FRAGMENT_PATH}") | ||
|
||
# adds a ${libArtifactName}::${libArtifactName} target | ||
add_imported_nativeaot_library("${libArtifactName}" "${libCmakeName}" NAMESPACE "${libArtifactName}::") | ||
|
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.
I think in the future, I'd almost rather have a "CMake module" file produced for the NativeAOT libraries instead of hard-coding it all here. I opened an issue related to this in DNNE a while back, AaronRobinsonMSFT/DNNE#185.
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.
yea, this could be a separate NuGet. it should be possible to generate a cmake config, a rust crate, etc just by hooking something up after NativeAOT's publish target.
right now the cmake config isn't entirely self-contained most obviously it depends on eng/native/configureplatform.cmake but probably also some other of our variables are leaking in. But maybe it's possible to refactor it.
Also I didn't do multi-config generator support, which maybe people care about.