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

Put brotli on the FetchContent plan #107166

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

jkoritzinsky
Copy link
Member

Consume our brotli dependency through FetchContent like zlib-ng. Also, update the "system brotli" consumption to use CMake's PkgConfig support. This provides us with a few benefits:

  • We don't need to maintain a list of source files that we want to include from brotli.
  • Consuming system vs in-tree brotli becomes much more similar as we use the same properties to specify targets and include directories.
  • Using system brotli in NativeAOT comes easily when building against system brotli. No need for the nonportable.txt workaround as we have files on disk we can look for, just like zlib-ng.

Fixes #107020

Copy link
Member

Choose a reason for hiding this comment

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

We can keep custom code out of the vendor's directory (so it looks as close to the upstream as possible).

Copy link
Member Author

Choose a reason for hiding this comment

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

The Bazel file is from upstream.

@@ -47,6 +47,9 @@ The .NET Foundation licenses this file to you under the MIT license.
<NativeLibrary Condition="'$(IlcMultiModule)' == 'true'" Include="$(SharedLibrary)" />
<NativeLibrary Include="$(IlcSdkPath)$(StandaloneGCSupportName)$(LibrarySuffix)" />
<NativeLibrary Include="$(IlcSdkPath)zlibstatic$(LibFileExt)" />
<NativeLibrary Include="$(IlcSdkPath)brotlicommon$(LibFileExt)" />
<NativeLibrary Include="$(IlcSdkPath)brotlienc$(LibFileExt)" />
<NativeLibrary Include="$(IlcSdkPath)brotlidec$(LibFileExt)" />
Copy link
Member

Choose a reason for hiding this comment

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

When we build .NET with system brotli, we don't include broticommon:

if (CLR_CMAKE_USE_SYSTEM_BROTLI)
find_library(BROTLIDEC brotlidec REQUIRED)
find_library(BROTLIENC brotlienc REQUIRED)
list(APPEND ${NativeLibsExtra} ${BROTLIDEC} ${BROTLIENC})
endif ()

Copy link
Member Author

Choose a reason for hiding this comment

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

When building against system brotli, brotlicommon is a private dependency of the brotlienc and brotlidec shared libraries, so it can be omitted. When statically linking, we need to specify all three.

@@ -25,6 +25,8 @@ The .NET Foundation licenses this file to you under the MIT license.
<LinkerFlavor Condition="'$(LinkerFlavor)' == '' and '$(_targetOS)' == 'linux'">bfd</LinkerFlavor>
<IlcDefaultStackSize Condition="'$(IlcDefaultStackSize)' == '' and '$(_linuxLibcFlavor)' == 'musl'">1572864</IlcDefaultStackSize>
<UseSystemZlib Condition="'$(UseSystemZlib)' == '' and !Exists('$(IlcSdkPath)libz.a')">true</UseSystemZlib>
<!-- Use libbrotlicommon.a as the sentinel for the three brotli libs. -->
<UseSystemBrotli Condition="'$(UseSystemBrotli)' == '' and !Exists('$(IlcSdkPath)libbrotlicommon.a')">true</UseSystemBrotli>
Copy link
Member

Choose a reason for hiding this comment

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

Nice and simple! 👍

@tmds
Copy link
Member

tmds commented Aug 30, 2024

@jkoritzinsky let me know when the PR is "ready", and then I will locally backport it to 9.0 and do some .NET builds to verify it fixes #107020.

@@ -155,6 +157,14 @@ The .NET Foundation licenses this file to you under the MIT license.
<NativeLibrary Condition="'$(UseSystemZlib)' != 'true'" Include="$(IlcSdkPath)libz.a" />
</ItemGroup>

<!-- brotli must be added after System.IO.Compression.Native and brotlicommon must be added last, order matters. -->
Copy link
Member

Choose a reason for hiding this comment

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

Was there a reason to move this ItemGroup from line 171 to here? I suspect something about the ItemGroup in line 168 was causing trouble.

Copy link
Member Author

Choose a reason for hiding this comment

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

I had just added the itemgroup here initially before @agocke did the implementation that uses nonportable.txt. I didn't move it down when I merged in his changes as I just immediately reverted them (as my changes are a replacement for the nonportable.txt workflow).

a list of direct pinvokes otherwise the runtime will crash
-->
<ItemGroup Condition="'$(_IsLibraryMode)' == 'true'">
<DirectPInvokes Include="libSystem.Native" />
<DirectPInvokes Include="libSystem.IO.Compression.Native" />
<DirectPInvokes Include="libSystem.Security.Cryptography.Native.Android" />
<DirectPInvokes Include="libbrotlienc;libbrotlidec" />
Copy link
Member

Choose a reason for hiding this comment

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

Do we need a comment here to indicate that this brotli line needs to be after System.IO.Compression.Native? I am assuming order would also matter here but I might be wrong.

I'm curious - why did you need to add this line here and in AppleBuild.targets? For zlib-ng, we decided to continue using the system zlib-ng in mobile platforms and in wasm/wasi to ensure that we could benefit from quick security updates provided by the OS, as we would not be able to provide them ourselves in those platforms.

Shouldn't we do the same with brotli?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm curious - why did you need to add this line here and in AppleBuild.targets? For zlib-ng, we decided to continue using the system zlib-ng in mobile platforms and in wasm/wasi to ensure that we could benefit from quick security updates provided by the OS, as we would not be able to provide them ourselves in those platforms.

Shouldn't we do the same with brotli?

There is no system brotli for mobile platforms (even on Android) and wasm or wasi, so we can't use a system implementation.

@@ -1,39 +1,30 @@
# IMPORTANT: do not use add_compile_options(), add_definitions() or similar functions here since it will leak to the including projects
Copy link
Member

Choose a reason for hiding this comment

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

Please bring this line back 😄 I removed it when working on zlib-ng, then forgot about that warning and ended up adding an add_compile_options. It was really annoying to get this fixed in source build when my change flowed there.

)

addprefix(BROTLI_SOURCES "${CMAKE_CURRENT_LIST_DIR}/brotli" "${BROTLI_SOURCES_BASE}")
set(BROTLI_DISABLE_TESTS ON)
Copy link
Member

Choose a reason for hiding this comment

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

Don't forget to run all the exotic azp runs: runtime-community, runtime-extra-platforms, the nativeaot and wasm ones. They might capture some interesting error messages.

Copy link
Member Author

Choose a reason for hiding this comment

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

Once I have regular CI working I'll make sure to do so.

@@ -88,7 +88,7 @@

<!-- Handle system libraries -->
<UseSystemLibs Condition="'$(UseSystemLibs)' != ''">+$(UseSystemLibs)+</UseSystemLibs>
<InnerBuildArgs Condition="'$(PortableBuild)' != 'true'">$(InnerBuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_BROTLI=true</InnerBuildArgs>
<InnerBuildArgs Condition="$(UseSystemLibs.Contains('+brotli+'))">$(InnerBuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_BROTLI=true</InnerBuildArgs>
Copy link
Member

Choose a reason for hiding this comment

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

Where does UseSystemLibs acquire its value? Or rather, who is in charge of appending "brotli"? I mainly want to know if we're properly deciding to use system brotli in mobile platforms and wasm/wasi.

BTW, if you run runtime-community, I'd be curious to see if armv6 will give us trouble like with zlib-ng.

Copy link
Member Author

Choose a reason for hiding this comment

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

UseSystemLibs is used in source-build for our distro partners to build against system brotli.

I don't expect issues with armv6 like zlib-ng as brotli isn't accelerated like zlib-ng is on various platforms.

Copy link
Member

Choose a reason for hiding this comment

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

AFAIK, it's not set automatically anywhere. Even in source-build, we are manually passing it at build-time when we want to build the full .NET SDK for a platform. The only exception is for 9.0 (only) where we assume system brotli (#107225 ).

Copy link
Member

Choose a reason for hiding this comment

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

It would be nice if we can make the vmr default to the configuration that is preferred by most distro maintainers.

Copy link
Member

Choose a reason for hiding this comment

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

It would be nice if we can make the vmr default to the configuration that is preferred by most distro maintainers.

I've created an issue for this: dotnet/source-build#4625.

Comment on lines +10 to +11
find_package(PkgConfig REQUIRED)
pkg_check_modules(BROTLI REQUIRED brotlidec brotlienc brotlicommon)
Copy link
Member

Choose a reason for hiding this comment

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

I was looking for these two!

Why here and not in extra_libs like with zlib-ng?

Copy link
Member Author

Choose a reason for hiding this comment

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

I was having weird issues with it being in extra_libs, and using PUBLIC in the target_link_libraries and target_include_directories below got the values to propagate such that I didn't need to include brotli.cmake in any other place than here.

@carlossanlop
Copy link
Member

@akoeplinger @jkotas should we keep using the system brotli in mobile platforms and wasi/wasm like we did with zlib-ng? Why or why not?

@jkotas
Copy link
Member

jkotas commented Sep 13, 2024

should we keep using the system brotli in mobile platforms and wasi/wasm

Does the system brotli exist on these platforms? Do we use it today?

@carlossanlop
Copy link
Member

Does the system brotli exist on these platforms? Do we use it today?

I do not know if system brotli exists in those platforms but we do use it today with find_package, formerly located in extra_libs.cmake, but moved in this PR to here: #107166 (comment)

@jkotas
Copy link
Member

jkotas commented Sep 13, 2024

We do not set CLR_CMAKE_USE_SYSTEM_BROTLI to 1 anywhere by default (different from zlib).

I think that system brotli does not exist on those platforms and we should be doing what we have been doing so far ie. use our bundled one. There is no other option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

source-built NativeAOT doesn't work with system brotli
6 participants