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

Provide a way to specify Android API Level in default android triplet #41895

Open
Deishelon opened this issue Nov 1, 2024 · 4 comments
Open
Assignees
Labels
category:question This issue is a question

Comments

@Deishelon
Copy link
Contributor

Describe the bug
Say you are building for Android, vcpkg provides an out of the box triplets for Android (great!),
However, from what I can see there is no way to set API Level.

Each NDK version has it's own 'min' API level, which is what NDK will be using, unless user specifies another value.

With NDK CMake this is done via ANDROID_PLATFORM variable.
Documentation: https://developer.android.com/ndk/guides/cmake#android_platform

For example, for NDK 28 (found in ~/Android/Sdk/ndk/28.0.12433566/meta/platforms.json):

  "min": 21,
  "max": 35,

So, by default if you are using NDK 28 with vcpkg and compiling for Android, you will default to 21 API level.

But there are some cases, where you want to change the API level to a higher number.

For example, building openssl with API level 21 will result in an error:

../src/nssl-3.3.2-515f0a0017.clean/providers/implementations/rands/seeding/rand_unix.c:360:9: error: 'getentropy' is unavailable: introduced in Android 28

So, a function getentropy is not there on 21 but there on 28.
Hence, you need to tell NDK to compile for android-28.

I didn't find an obvious way to pass my parameter but to copy the official triplet, and use overlay with exact same content, but additional argument like so:
Image

The highlighted bit is what I've added to the copied official triplet.

So, suggestion, can we have a way to pass additional args (such as ANDROID_PLATFORM) to triplet?
This would avoid users to copy the official triplets modify/add a tiny bit and use overlay.

If it helps, we are using vcpkg via CMake, eg:

.....
include(${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
@dg0yt
Copy link
Contributor

dg0yt commented Nov 1, 2024

In the triplet file, set VCPKG_CMAKE_SYSTEM_VERSION.

@dg0yt
Copy link
Contributor

dg0yt commented Nov 1, 2024

The API level changes the ABI of the binary artifacts. Thus using a modified triplet is the right way to ensure unambiguous ABI hashes for vcpkg's binary caching.

@Deishelon
Copy link
Contributor Author

Yup, adding set(VCPKG_CMAKE_SYSTEM_VERSION "android-28") into the overlay triplet instead of -DANDROID_PLATFORM=android-28 (as shown in the issue) also works.

Is there any difference why go for one or another? Both seem to do the same thing, unless VCPKG_CMAKE_SYSTEM_VERSION is better for vcpkg internals somehow?

Yup, it make sense from hashes/caches of vcpkg POV, but from user POV, if you need to alter ANDROID_PLATFORM you have to go custom triplet route. Is this something we can improve ?

@dg0yt
Copy link
Contributor

dg0yt commented Nov 1, 2024

Actually I suggest:

set(VCPKG_CMAKE_SYSTEM_VERSION 28)

It is important to understand that the triplet has a central role in ensuring a consistent install tree with regard to binary compatibility. Customizing the file is a reasonable thing with regard to API level.

It is useful to understand that vcpkg uses two modes of CMake when building ports.
https://learn.microsoft.com/en-us/vcpkg/contributing/maintainer-guide#portfiles-are-run-in-script-mode

In script mode, the usual variables from toolchains and project() are not available. Some cmake variables variables will control how vcpkg configure CMake projects and toolchains. The triplet file is the key file to control script mode variable. VCPKG_CMAKE_SYSTEM_VERSION is such a variable. So setting this variable to ensure consistent information in script mode and in project mode.

There is a command line option which allows to inject variables into script mode: --cmake-args. I sometimes uses it to quickly test different API levels with the default android triplet. But I wouldn't recommend it for daily use due to ABI hashing.

@Cheney-W Cheney-W added the category:question This issue is a question label Nov 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category:question This issue is a question
Projects
None yet
Development

No branches or pull requests

3 participants