sccn / liblsl

C++ lsl library for multi-modal time-synched data transmission over the local network
Other
114 stars 67 forks source link

LSL for Android (C++ project) #191

Closed VladimirR46 closed 1 year ago

VladimirR46 commented 1 year ago

Hello!

Our team wants to use an Samsung galaxy Tab S7 for a series of experiments. Our stimulus program is written in Qt Creator (c++ qt 6.5). The program compiles successfully and runs on an galaxy Tab with Android. The program is built for the processor architecture arm64-v8a. We want to add lsl to the program to send event markers. How can we do that?

Unfortunately, we do not have a development specialist for the Android platform. At this point I understand that we have the option to compile the library using Android Studio and get aar (.so) file for Java. And then, using (https://doc.qt.io/qt-6/android-3rdparty-libs.html) method use Java library in in our C++ code. (https://doc.qt.io/qt-6/qtcore-platform-androidnotifier-example.html) But I don't like this approach very much since it breaks Qt's single code base. (We also build this program for Windows and MacOS, no problem with these platforms!)

Can we somehow build a library (get a ".so" file) to use in a C++ project and connect it in cmake as:

find_package(LSL 1.13.0 REQUIRED
      HINTS ${LSL_INSTALL_ROOT}
      "${CMAKE_CURRENT_LIST_DIR}/../../LSL/liblsl/build/"
      "${CMAKE_CURRENT_LIST_DIR}/../../LSL/liblsl/build/install"
      PATH_SUFFIXES share/LSL
)

Thank you so much for any help!

cboulay commented 1 year ago

Given that you're using CMake and a C++ project, the easiest solution is to use something like CMake's FetchContent to pull in the liblsl repo and then just build it as part of your project.

liblsl's CMake script has an option to build a static library so you set that to ON after FetchContent_Declare but before FetchContent_MakeAvailable.

Then for your target binary you can do target_link_libraries(${MY_ANDROID_TARGET} LSL). That should be it.

Note, however, that the LSL build systems is untested on your target platform so it's possible that the cross-compiler toolchain will have some errors when trying to build liblsl.a. I've built it on ARM many times, and I've built it on Android in the past, but it's not something that's regularly tested.

P.S. - Why version 1.13.0?

VladimirR46 commented 1 year ago

Thanks for the quick response!

I created a simple test project for Windows using MinGW_64. In CMake I added:

include(FetchContent)

FetchContent_Declare(LSL
            GIT_REPOSITORY https://github.com/sccn/liblsl.git
            FIND_PACKAGE_ARGS
    )
set(LSL_BUILD_STATIC ON)
FetchContent_MakeAvailable(LSL)

. . . . .

target_link_libraries(TestApp PRIVATE Qt${QT_VERSION_MAJOR}::Widgets LSL)

But there is an error at the linking stage.

image

P.S. - 1.13.0 version - I just wrote this as an example =)

cboulay commented 1 year ago

Try lsl (lower case), or LSL::lsl. And if that fails, try lslobj lslboost.

VladimirR46 commented 1 year ago

Thank you so much!

If I use MSVC2019 64bit and target_link_libraries(TestApp PRIVATE Qt${QT_VERSION_MAJOR}::Widgets lsl) The project compiles successfully! If I use MinGW_64 I get some errors. But I think it doesn't matter because I managed to build it for Windows using MSVC.

But if I try to use "Android Qt 6.5.0 Clang arm64-v8a" I get the following errors:

image

cboulay commented 1 year ago

Try adding set(LSL_OPTIMIZATIONS OFF) after the line to set static library.

cboulay commented 1 year ago

Also, paging @tstenner .

VladimirR46 commented 1 year ago

Hello! Thank you for your reply!

Unfortunately set(LSL_OPTIMIZATIONS OFF) did not help. This option helped to solve one problem: ld: error: undefined symbol: lsl_library_info but not the problemld: error: undefined symbol: lsl::get_local_interfaces()

If I comment out the line if (multicast_interfaces.empty()) multicast_interfaces = get_local_interfaces(); in the api_config.cpp file, the project compiles successfully.

tstenner commented 1 year ago

The multicast enumeration code only works for api level 24 and later. There was a workaround for niche platforms (neither windows, macOS nor android < 24) that had a wrong function name and in three years nobody noticed it...

I don't know if you can see those here, but when you fork the repository there's a predefined Gitlab CI job to build Android libraries you can start for any branch and have it built on a build machine with everything preinstalled

VladimirR46 commented 1 year ago

Thank you all so much for your help!

The problem was that I installed the repository by mistake https://github.com/tstenner/liblsl.git

Now I use this code and it works!!!

include(FetchContent)

FetchContent_Declare(LSL
            GIT_REPOSITORY https://github.com/sccn/liblsl.git
            FIND_PACKAGE_ARGS
    )
set(LSL_BUILD_STATIC ON)
set(LSL_OPTIMIZATIONS OFF)
FetchContent_MakeAvailable(LSL)

Thank you!