Building native (static) Android libraries

1,411 views
Skip to first unread message

jan.ema...@gmail.com

unread,
Sep 7, 2016, 3:00:16 AM9/7/16
to discuss-webrtc
We are writing a native C++ Android library. For the video compression, network protocols we want to use WebRTC.

On the internet I read that it was possible to build WebRTC with GYP in such a way that it generates static .a. libraries (if I'm correct) like libjingle_peerconnection.a. But when following https://webrtc.org/native-code/android/ I don't see libraries (except third party and test) which I can include in our native C++ Android library project.

Is this possible and how to (incl libjingle)?

(We don't use Java.)
 

Christoffer Jansson

unread,
Sep 7, 2016, 8:26:22 AM9/7/16
to discuss-webrtc
Hi,

We recently migrated to GN as you can see in this discuss-webrtc PSA.

Have you tried using gn with additional argument is_component_build=false? Details in the iOS section (might need to add this to the Android page as well). Do note I've not tried this, just guessing based on the iOS instructions.

/Chris


--

---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/e03d4d29-214b-4707-a342-217afc0adb7b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
/Chris

jan.ema...@gmail.com

unread,
Sep 7, 2016, 9:36:38 AM9/7/16
to discuss-webrtc
Yes, I saw that GN is now used and understood that GYP don't work anymore.

I build also (besides the default debug) the release (which should be static) and another build with the option is_component_build=false. But none give the static libraries .a. They only generate .o files and .so. The .so files are for JNI usage I guess. The exports are like

000323a9 T Java_org_webrtc_PeerConnectionFactory_nativeCreatePeerConnectionFactory

instead of

00000001 T webrtc::CreatePeerConnectionFactory(talk_base::Thread*, talk_base::Thread*, webrtc::AudioDeviceModule*, cricket::WebRtcVideoEncoderFactory*, cricket::WebRtcVideoDecoderFactory*)

see also: https://groups.google.com/forum/#!searchin/discuss-webrtc/native$20android|sort:relevance/discuss-webrtc/TVjjgUSQlik/jPdeAn7xZW8J

To me it seems that the static .a libraries are not generated anymore. Or dynamic ones without the Java/JNI "decoration/prefix". I have no idea how to solve this or what I overlook?

(I still didn't figure out what PSA stands for)

Christoffer Jansson

unread,
Sep 8, 2016, 7:06:43 AM9/8/16
to discuss-webrtc, kjell...@google.com
+Henrik Kjellander do you have any input here?

PSA = Public service announcement

/Chris

--

---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--
/Chris

jan.ema...@gmail.com

unread,
Sep 8, 2016, 10:24:50 AM9/8/16
to discuss-webrtc, kjell...@google.com
Hi Chris,

Thanks, I will ask him directly and also posted it on the PSA post you gave.

Henrik Kjellander

unread,
Sep 12, 2016, 9:27:13 AM9/12/16
to discuss-webrtc, Patrik Höglund, Edward Lemur
+phoglund who has deeper knowledge about this

I tried a Release build for Android (which is static by default, Debug is no longer that not as I informed about here).
gn gen out/Default --args='is_debug=false target_os="android" target_cpu="arm"'
ninja -C out/Default libjingle_peerconnection_so

Then I get the following .so files:
$ find out/Default/ -name *.so
out/Default/lib.unstripped/libjingle_peerconnection_so.so
out/Default/libjingle_peerconnection_so.so

The latter is stripped, while the former contains all symbols:
$ nm -C out/Default/lib.unstripped/libjingle_peerconnection_so.so|grep CreatePeerConnectionFactory
0007193d T Java_org_webrtc_PeerConnectionFactory_nativeCreatePeerConnectionFactory
00044cb9 t webrtc::CreatePeerConnectionFactory(rtc::Thread*, rtc::Thread*, rtc::Thread*, webrtc::AudioDeviceModule*, cricket::WebRtcVideoEncoderFactory*, cricket::WebRtcVideoDecoderFactory*)
003b7580 r webrtc::CreatePeerConnectionFactory(rtc::Thread*, rtc::Thread*, rtc::Thread*, webrtc::AudioDeviceModule*, cricket::WebRtcVideoEncoderFactory*, cricket::WebRtcVideoDecoderFactory*)::__FUNCTION__

which I guess is what you were asking for?

Patrik Höglund

unread,
Sep 12, 2016, 10:04:29 AM9/12/16
to Henrik Kjellander, discuss-webrtc, Edward Lemur
Hi!

I don't think I know more than you do, but one thing that works is to change rtc_source_set to rtc_static_library. This produces a libjingle_peerconnection.a. I think the right way might be to not do that and simply depend on libjingle_peerconnection from your build target (run gn help source_set to learn more).

If you have a completely separate build system for your product and just want the .a file out of WebRTC, the above approach will work though.

/ P

jan.ema...@gmail.com

unread,
Sep 13, 2016, 5:49:23 AM9/13/16
to discuss-webrtc, kjell...@webrtc.org, ehmal...@webrtc.org
Hi!

@Henrik

That's nice to know. But as far as I can see not suitable for us so far my understanding now.

First:

What I did was reverted back to 8-aug and build using GYP. Then I get all the static libs (.a). But this is not the latest code and those are not generated with the latest GN build. And I'm lost in dependencies resulting in a lot of "undefined reference to"

second:

We use as testcode

rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> m_PeerConnectionFactory = webrtc::CreatePeerConnectionFactory();

which was working a few weeks back under Windows (VS2015). Now we are porting it to Android.

The constructor CreatePeerConnectionFactory() is in the static libary (.a) but not in the shared one (.so). To show the public exported functions which can be used, we use the command

/Release/lib.unstripped$ nm --defined-only -g -C libjingle_peerconnection_so.so | grep -i createpeerconnectionf

Then only the Java decorated function is left.

00071791 T Java_org_webrtc_PeerConnectionFactory_nativeCreatePeerConnectionFactory

While doing this for the static lib (.a) the constructor CreatePeerConnectionFactory() is there.

nm --defined-only -g -C libjingle_peerconnection.a | grep -i createpeerconnectionf

00000001 T webrtc::CreatePeerConnectionFactory(rtc::Thread*, rtc::Thread*, rtc::Thread*, webrtc::AudioDeviceModule*, cricket::WebRtcVideoEncoderFactory*, cricket::WebRtcVideoDecoderFactory*)
00000001 T webrtc::CreatePeerConnectionFactory()

So it seems that the .so is for the JNI and cannot be used in native code directly (without the JAVA and JNI), even with the unstripped version. The others functions are probably private and used by the JAVA decorated one but I don't know.

@Patrik

We are trying to see what we can do with that option.

phog...@webrtc.org

unread,
Sep 15, 2016, 4:40:36 AM9/15/16
to discuss-webrtc, kjell...@webrtc.org, ehmal...@webrtc.org
Hi!

Yeah, we don't really support making an .a out of libjingle_peerconnection, but we're going to try to implement it. We need to consult with the GN guys first.

Here are some things to try in the meantime:

- Add #define HACKHACKEXPORT  __attribute__ ((visibility ("default"))) somewhere suitable and add HACKHACKEXPORT to the declaration of CreatePeerConnectionFactory() (and elsewhere as needed).
- If you're still missing symbols, try changing the rtc_source_set template in webrtc/build/webrtc.gni to use static_library instead of source_set. This will make all dependencies of the peerconnection lib static libs as well.

The above is just workarounds and particularly the latter will cost in build time, but maybe that can unblock you while we figure this out.

/ P

Patrik Höglund

unread,
Sep 15, 2016, 9:31:27 AM9/15/16
to discuss-webrtc, Henrik Kjellander, Edward Lemur
Actually, changing webrtc.gni to build static libraries probably has no effect except make the build slower, so disregard that. The #define thing will probably solve your problem though.

Also, run gn help complete_static_lib; it could be interesting for you. Maybe try setting that on libjingle_peerconnection (after changing it to rtc_static_library), and see if you get an .a that's useful to you. Let us know how it goes.

/ P

--

---
You received this message because you are subscribed to a topic in the Google Groups "discuss-webrtc" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/discuss-webrtc/W5P7Glao2fs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to discuss-webrtc+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/dc19b374-4fc0-4b5c-ae56-844f7478c6ba%40googlegroups.com.

jan.ema...@gmail.com

unread,
Sep 20, 2016, 11:31:14 AM9/20/16
to discuss-webrtc, kjell...@webrtc.org, ehmal...@webrtc.org
Hi Patrik (and others)!

Thanks for you help! We changed the BUILD.gn in the src/webrtc/api by changing and adding

   rtc_static_library("libjingle_peerconnection") {
     complete_static_lib = true
     ...
 
  deps = [
    ...
    "../system_wrappers:field_trial_default",
    "../system_wrappers:metrics_default"
  ]


Then we got a static library of >300 MB. Until now we can work with only this library.

We don't use the .so file.

I hope that generating a static lib(s) become a feature in the future.
Enter code here...

Henrik Kjellander

unread,
Sep 22, 2016, 9:13:40 AM9/22/16
to discuss-webrtc, kjell...@webrtc.org, ehmal...@webrtc.org
I believe complete_static_lib will give you _everything_ bundled into the library (all dependencies), which is probably not what you want.

I think a mass conversion from source_set to static_library is the way to go. We've misunderstood the use of source_set which was initially promoted as "use wherever you can" with GN and converted most of our targets to that. I filed https://bugs.chromium.org/p/webrtc/issues/detail?id=6410 to track fixing this and started working on a CL.

Henrik Kjellander

unread,
Sep 23, 2016, 3:44:31 AM9/23/16
to discuss-webrtc, kjell...@webrtc.org, ehmal...@webrtc.org
I think https://crrev.com/b62dbbe985c643cf4ee28e4c73c75bb3ef5e4d54 should solve these problems, since it's essentially making most targets a static_library (as in GYP). Please confirm if this solves your problem.

Jason B

unread,
Sep 23, 2016, 8:47:35 PM9/23/16
to discuss-webrtc, kjell...@webrtc.org, ehmal...@webrtc.org
Henrik Kjellander, Thanks for the fast fix! I saw your pull request here: https://codereview.webrtc.org/2361623004/

I think you might have missed the base webrtc library itself, though. It's on line 243 of BUILD.ng in src/webrtc/ directory.

Here are some others I found; not sure which would be better as rtc_static_library 
webrtc\api\BUILD.gn:rtc_source_set("call_api") {
webrtc
\api\BUILD.gn:rtc_source_set("rtc_stats_api") {
webrtc
\audio\BUILD.gn:  rtc_source_set("audio_tests") {
webrtc
\base\BUILD.gn:rtc_source_set("gtest_prod") {
webrtc
\base\BUILD.gn:  rtc_source_set("rtc_base_tests_utils") {
webrtc
\BUILD.gn:  rtc_source_set("webrtc") {
webrtc
\BUILD.gn:  rtc_source_set("video_quality_test") {
webrtc
\call\BUILD.gn:  rtc_source_set("call_tests") {
webrtc
\call\BUILD.gn:  rtc_source_set("rtc_event_log_tests") {
webrtc
\media\BUILD.gn:  rtc_source_set("rtc_unittest_main") {
webrtc
\modules\audio_coding\BUILD.gn:  rtc_source_set("acm_receive_test") {
webrtc
\modules\audio_coding\BUILD.gn:  rtc_source_set("acm_send_test") {
webrtc
\modules\audio_coding\BUILD.gn:  rtc_source_set("neteq_test_support") {
webrtc
\modules\audio_coding\BUILD.gn:  rtc_source_set("neteq_quality_test_support") {
webrtc
\modules\audio_coding\BUILD.gn:  rtc_source_set("neteq_unittest_tools") {
webrtc
\modules\audio_coding\BUILD.gn:  rtc_source_set("neteq_test_tools") {
webrtc
\modules\audio_processing\BUILD.gn:  rtc_source_set("audioproc_test_utils") {
webrtc
\modules\BUILD.gn:  rtc_source_set("audio_network_adaptor_unittests") {
webrtc
\modules\BUILD.gn:    # rtc_source_set to solve name collision on bitrate_controller_unittest.cc.
webrtc
\modules\video_coding\BUILD.gn:  rtc_source_set("video_codecs_test_framework") {
webrtc
\stats\BUILD.gn:rtc_source_set("rtc_stats_test_utils") {
webrtc
\test\BUILD.gn:rtc_source_set("video_test_common") {
webrtc
\test\BUILD.gn:rtc_source_set("rtp_test_utils") {
webrtc
\test\BUILD.gn:rtc_source_set("field_trial") {
webrtc
\test\BUILD.gn:rtc_source_set("test_main") {
webrtc
\test\BUILD.gn:rtc_source_set("test_support") {
webrtc
\test\BUILD.gn:rtc_source_set("test_support_main") {
webrtc
\test\BUILD.gn:rtc_source_set("test_support_main_threaded_mac") {
webrtc
\test\BUILD.gn:rtc_source_set("test_common") {
webrtc
\test\BUILD.gn:rtc_source_set("test_renderer") {
webrtc
\video\BUILD.gn:  rtc_source_set("video_tests") {

Jason Boggess

unread,
Sep 23, 2016, 9:19:17 PM9/23/16
to discuss-webrtc, kjell...@webrtc.org, ehmal...@webrtc.org
Hmmm changing that causes the build to fail. Is there any way we can get webrtc.lib back as well?

--

---
You received this message because you are subscribed to a topic in the Google Groups "discuss-webrtc" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/discuss-webrtc/W5P7Glao2fs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to discuss-webrt...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/684de357-16dc-4dac-8289-7ae06cdb2485%40googlegroups.com.

Henrik Kjellander

unread,
Sep 27, 2016, 3:54:49 PM9/27/16
to discuss-webrtc, kjell...@webrtc.org, ehmal...@webrtc.org
Sorry, I was busy with other things. I was able to make the 'webrtc' target a static_library in https://codereview.webrtc.org/2372983002/ as well. It took an ugly hack though - see CL description for more info.

Jan Jansen

unread,
Sep 29, 2016, 8:08:37 AM9/29/16
to discuss...@googlegroups.com
@Henrik,

The big library was fine for use. We use that one. This avoids problems of the order of the libraries when linking. Without the complete_static_lib we got a much smaller lib (37Mb instaed of 300Mb). The export looks fine

00000001 T webrtc::CreatePeerConnectionFactory()

But we didn't use that one because we are very busy getting our library to work with webrtc and the big fat .a is enough for now. We have got some building problems of the .so but didn't look further at it. We don't use that one. (I guess the problems occurred because we added also two dependencies to the build.)

The part with the no_op_function.cc I don't understand and didn't look in detail to it.


To unsubscribe from this group and all its topics, send an email to discuss-webrtc+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/806757d8-70db-4dfd-90c5-9d62d2537f99%40googlegroups.com.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages