Skip to content

capnproto: add lite_mode option #26282

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

mologie
Copy link
Contributor

@mologie mologie commented Jan 1, 2025

Summary

Changes to recipe: capnproto/all

Motivation

Cap'n Proto's build scripts provide a "lite mode" build option, where only libkj and a subset of libcapnp (no reflection) is built. This PR exposes it via a Conan option, so that lite mode can be used by Conan packages that do not depend on full functionality and need to be small or more portable (e.g. for old Androids).

Details

The changes to enable lite mode are minimal: This merely modified the value of --enable-reflection/CAPNP_LITE, and updates the components list depending on the option value.

Users can use Cap'n Proto like so to compile schema files in their CMakeLists, while using a stripped-down version of Cap'n Proto in their application (cross-)build.

self.requires("capnproto/1.1.0", options={"lite_mode": True})
self.tool_requires("capnproto/1.1.0")

Tested on macOS 15.2 and cross-compiled to Android with NDK r27 and iOS 18.


@mologie
Copy link
Contributor Author

mologie commented Jan 1, 2025

Hi maintainers, when you get a chance, please also check out PR #23787 from last April; it is relevant to the same project that got me to create this PR. I'd have all customized recipes upstreamed once that one is merged too. Thanks!

@mologie mologie force-pushed the capnproto-lite-mode branch from 1651fdf to 4949ba4 Compare January 2, 2025 13:02
@mologie
Copy link
Contributor Author

mologie commented Jan 2, 2025

kj-test is built in lite mode too, which is now reflected in the recipe

Copy link
Member

@memsharded memsharded left a comment

Choose a reason for hiding this comment

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

When tested with conan create -o &:lite_mode=True I am getting link errors, at least in Windows:

kj.lib(mutex.obj) : error LNK2019: unresolved external symbol "class kj::MonotonicClock const & __cdecl kj::systemPreciseMonotonicClock(void)" (?systemPrecis eMonotonicClock@kj@@YAAEBVMonotonicClock@1@XZ) referenced in function "public: void __cdecl kj::_::Mutex::wait(class kj::_::Mutex::Predicate &,class kj::Mayb e<class kj::Quantity<__int64,class kj::_::NanosecondLabel> >,class kj::NoopSourceLocation)" (?wait@Mutex@_@kj@@QEAAXAEAVPredicate@123@V?$Maybe@V?$Quantity@_J VNanosecondLabel@_@kj@@@kj@@@3@VNoopSourceLocation@3@@Z) [C:\Users\conanws\conan-center-index\recipes\capnproto\all\test_package\build\msvc-194-x86_64- 14-release\addressbook.vcxproj]
C:\Users\conanws\conan-center-index\recipes\capnproto\all\test_package\build\msvc-194-x86_64-14-release\Release\addressbook.exe : fatal error LNK1120:
1 unresolved externals [C:\Users\conanws\conan-center-index\recipes\capnproto\all\test_package\build\msvc-194-x86_64-14-release\addressbook.vcxproj]

I'll try to test it in Linux too.

@memsharded
Copy link
Member

memsharded commented Mar 5, 2025

It seems it is also failing in Linux:

$ conan create . --version=1.1.0 -o "&:lite_mode=True"
...

======== Testing the package: Executing test ========
capnproto/1.1.0 (test package): Running test()
capnproto/1.1.0 (test package): RUN: ./addressbook
240

capnproto/1.1.0 (test package): RUN: capnp id
/bin/sh: 1: capnp: not found

ERROR: capnproto/1.1.0 (test package): Error in test() method, line 36
        self.run("capnp id")
        ConanException: Error 127 while executing

ConanCenter CI doesn't test all optional options values. It is necessary to test them manually on the user side.
Please make sure to test that new option thoroughly. Many thanks for your contribution!

UPDATE:

Tested on macOS 15.2 and cross-compiled to Android with NDK r27 and iOS 18.

Sorry I hadn't seen that. That would be some reasonable testing, many thanks. Unfortunately, I don't have a Mac here to test in that configuration and try to compare what could be the differences, I'll try to investigate a bit further in Windows and Linux.

@mologie
Copy link
Contributor Author

mologie commented Mar 5, 2025

Hi @memsharded, thanks for looking into this!

It seems it is also failing in Linux: [...]

It is be normal for the standard test to fail in lite mode because the capnp binary is not produced there (the option is simple invalid/incompatible with the given test).

[...] Unfortunately, I don't have a Mac here to test in that configuration and try to compare what could be the differences, I'll try to investigate a bit further in Windows and Linux.

After submitting this PR, originally for Android and macOS, it was also integrated in internal company tooling that is automatically built for Ubuntu 24.04, and works as expected there.

If you'd like I can extend this by a specific lite mode test, which would compile a library to call some basic function of libkj or libcapnp, which is all there is when lite mode is on.

I'm merging/reverting your libtool suggestion, thanks, did not know that was best practice here and will keep it in mind for future work.

Cap'n Proto's lite mode disables all reflection and I/O features, so
that a lean library for encoding and decoding messages remains. This
especially is required for targeting Android with API level 21,
because libkj-async requires API level 23 or later for sigtimedwait.

It may be necessary to additionally add a tool_requires("capnproto")
when using lite mode, just like when cross-compiling, so that capnpc
is available to the lite build of libcapnp and libkj.
@mologie mologie force-pushed the capnproto-lite-mode branch from 4949ba4 to 89b416e Compare March 5, 2025 18:48
@memsharded
Copy link
Member

From the capnproto code:

All programs built
    against the library MUST be compiled with -DCAPNP_LITE=1

I have tried adding CAPNP_LITE=1 as cpp_info.defines without success.

Yes, it is possible that only the test_package code is failing for the lite binary then? In that case, adding some provision into the test_package to avoid the failure would be great. Still a bit confused because they were different failure modes, in Windows it was a linking error (missing symbol), in Linux is like it failed to find the executable/shared lib?

@mologie
Copy link
Contributor Author

mologie commented Mar 5, 2025

Sure, I will extend the tests tomorrow to account for the lite mode option, that should clear the path to validate this automatically in the future.

It's 11pm here though, so I'll hit the sheets for now :) Thanks again!

Regarding your question for the linker error: It's expected also to see kj/capnp lite mode to miss some symbols as that excludes a good amount of source files from the libraries. Windows and macOS have strict linking to resolve every symbol at link time, whereas on Linux it would have failed at runtime.

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

Successfully merging this pull request may close these issues.

2 participants