OpenMP on Android
-
wrote on 26 May 2023, 21:03 last edited by
Hello, I have a few source files from a past project that include OpenMP commands and that I've integrated into a Qt project. The OPENMP defines in CMakeList.txt work well and the program compiles and runs fine on Windows. But it crashes on Android, complaining of a missing library (libomp).
I can see the OpenMP libraries in the Android SDK sysroots so it must be possible to use it, but my attempts to add parameters to cmake have not succeeded in getting the app to work on Android. Removing the OpenMP directives from the code allows the program to work though, so the issue is clearly related to the missing OpenMP library. I could rewrite the code to use QtConcurrent instead, but that would be a lot of work.
What do I need to change in my cmakelist.txt file to make this work? This is what I have now:
find_package(OpenMP) if (OPENMP_FOUND) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") endif()
Qt 6.5.1
Android SDK Version 9 (33 - Tiramisu)
Android NDK 25.2.9519653
arm64-v8 CPU architecture
Samsung Galaxy Tab S8 tablet
QtCreator 10.0.1 on Windows 11 -
@JoeCFD Thanks for putting me on the right track, I've gotten it to work by cheating a bit.
I copied the libomp.so file from the sysroot for my Android image from the Android SDK to my project folder and added the following to my CmakeList.txt file:
set_target_properties(sim PROPERTIES QT_ANDROID_EXTRA_LIBS /dev/projects/srm/libomp.so )
The file gets packaged and the app works fine now. But of course this only works for this particular version of Android and for this processor architecture. The right way to do this would be to use the right sysroot for this library automatically based on the build settings. How would that be done? I am new to both Android development and cmake...
wrote on 27 May 2023, 00:16 last edited by CharlesV@CharlesV Found it! This is fixed by adding libomp.so to the target_link_libraries. But instead of "libomp.so", we use "omp" only.
So adding these few lines resolved the problem:
if(ANDROID) target_link_libraries(${PROJECT_NAME} PUBLIC omp) endif()
It's not clear to me why this doesn't need to be done for the Windows build, or why the settings of the Windows build don't work for the Android build, and I would like to understand that.
Anyhow, thanks again @JoeCFD for putting me on the right track.
-
Hello, I have a few source files from a past project that include OpenMP commands and that I've integrated into a Qt project. The OPENMP defines in CMakeList.txt work well and the program compiles and runs fine on Windows. But it crashes on Android, complaining of a missing library (libomp).
I can see the OpenMP libraries in the Android SDK sysroots so it must be possible to use it, but my attempts to add parameters to cmake have not succeeded in getting the app to work on Android. Removing the OpenMP directives from the code allows the program to work though, so the issue is clearly related to the missing OpenMP library. I could rewrite the code to use QtConcurrent instead, but that would be a lot of work.
What do I need to change in my cmakelist.txt file to make this work? This is what I have now:
find_package(OpenMP) if (OPENMP_FOUND) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") endif()
Qt 6.5.1
Android SDK Version 9 (33 - Tiramisu)
Android NDK 25.2.9519653
arm64-v8 CPU architecture
Samsung Galaxy Tab S8 tablet
QtCreator 10.0.1 on Windows 11 -
@CharlesV How did you build your project with libomp for Android? I guess you must have the version of libomp for Android. Maybe try to wrap this libomp in your project for Android as well.
wrote on 26 May 2023, 23:01 last edited by@JoeCFD Full cmakelist.txt below. It compiles without any error, deploys, but crashes on startup with the following error message:
AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library "libomp.so" not found: needed by /data/app/~~XVQV_hRH8p1w6P0YVl11XA==/org.qtproject.example.sim-q28CPqunzRadBurJEbIpCA==/lib/arm64/libsim_arm64-v8a.so in namespace classloader-namespace E
CMakeList.txt
cmake_minimum_required(VERSION 3.14) project(sim VERSION 0.1 LANGUAGES CXX) #set(CMAKE_PREFIX_PATH "/qt/6.5.0/mingw_64/lib/cmake/Qt6") set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(OpenMP) if (OPENMP_FOUND) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") endif() find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Quick) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS 3DCore 3DInput 3DLogic 3DQuick 3DQuickExtras 3DRender Core Gui Qml Quick) set(PROJECT_SOURCES main.cpp ... ) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) qt_add_executable(sim MANUAL_FINALIZATION ${PROJECT_SOURCES} ) # Define target properties for Android with Qt 6 as: # set_property(TARGET sim APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR # ${CMAKE_CURRENT_SOURCE_DIR}/android) # For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation else() if(ANDROID) add_library(sim SHARED ${PROJECT_SOURCES} ) # Define properties for Android with Qt 5 after find_package() calls as: # set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") else() add_executable(sim ${PROJECT_SOURCES} ) endif() endif() target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/render ${CMAKE_CURRENT_SOURCE_DIR}/model) # Settings for h3 library compilation if(ANDROID) set(BUILD_SHARED_LIBS OFF) else() set(BUILD_SHARED_LIBS ON) endif() set(BUILD_TESTING OFF) add_subdirectory(h3) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/h3/src/h3lib/include) if(ANDROID) target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/h3/lib/libh3.a) else() target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/h3/bin/libh3.dll) endif() target_link_libraries(sim PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick PUBLIC Qt::3DCore Qt::3DInput Qt::3DLogic Qt::3DQuick Qt::3DQuickExtras Qt::3DRender Qt::Core Qt::Gui Qt::Qml Qt::Quick ) set_target_properties(sim PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE ) install(TARGETS sim BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) if(QT_VERSION_MAJOR EQUAL 6) qt_import_qml_plugins(sim) qt_finalize_executable(sim) endif()
-
@JoeCFD Full cmakelist.txt below. It compiles without any error, deploys, but crashes on startup with the following error message:
AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library "libomp.so" not found: needed by /data/app/~~XVQV_hRH8p1w6P0YVl11XA==/org.qtproject.example.sim-q28CPqunzRadBurJEbIpCA==/lib/arm64/libsim_arm64-v8a.so in namespace classloader-namespace E
CMakeList.txt
cmake_minimum_required(VERSION 3.14) project(sim VERSION 0.1 LANGUAGES CXX) #set(CMAKE_PREFIX_PATH "/qt/6.5.0/mingw_64/lib/cmake/Qt6") set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(OpenMP) if (OPENMP_FOUND) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") endif() find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Quick) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS 3DCore 3DInput 3DLogic 3DQuick 3DQuickExtras 3DRender Core Gui Qml Quick) set(PROJECT_SOURCES main.cpp ... ) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) qt_add_executable(sim MANUAL_FINALIZATION ${PROJECT_SOURCES} ) # Define target properties for Android with Qt 6 as: # set_property(TARGET sim APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR # ${CMAKE_CURRENT_SOURCE_DIR}/android) # For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation else() if(ANDROID) add_library(sim SHARED ${PROJECT_SOURCES} ) # Define properties for Android with Qt 5 after find_package() calls as: # set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") else() add_executable(sim ${PROJECT_SOURCES} ) endif() endif() target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/render ${CMAKE_CURRENT_SOURCE_DIR}/model) # Settings for h3 library compilation if(ANDROID) set(BUILD_SHARED_LIBS OFF) else() set(BUILD_SHARED_LIBS ON) endif() set(BUILD_TESTING OFF) add_subdirectory(h3) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/h3/src/h3lib/include) if(ANDROID) target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/h3/lib/libh3.a) else() target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/h3/bin/libh3.dll) endif() target_link_libraries(sim PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick PUBLIC Qt::3DCore Qt::3DInput Qt::3DLogic Qt::3DQuick Qt::3DQuickExtras Qt::3DRender Qt::Core Qt::Gui Qt::Qml Qt::Quick ) set_target_properties(sim PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE ) install(TARGETS sim BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) if(QT_VERSION_MAJOR EQUAL 6) qt_import_qml_plugins(sim) qt_finalize_executable(sim) endif()
wrote on 26 May 2023, 23:15 last edited by JoeCFD@CharlesV
in qmake.pro file I have to add for example libspdlog.so to ANDROID_EXTRA_LIBS
ANDROID_EXTRA_LIBS += $$PWD/../../thirdparties/spdlog/lib/libspdlog.soTry to find out how to add libs to ANDROID_EXTRA_LIBS in cmake file. Then pack libomp.so into your project. It is not packed and therefore, your code can not find it.
If you can find a static one, then no problem after build.libomp is an extra lib and you have to add it by yourself. Qt libs are added automatically. You can check which libs are included in your apk.
https://doc.qt.io/qt-6/cmake-target-property-qt-android-extra-libs.html
-
@CharlesV
in qmake.pro file I have to add for example libspdlog.so to ANDROID_EXTRA_LIBS
ANDROID_EXTRA_LIBS += $$PWD/../../thirdparties/spdlog/lib/libspdlog.soTry to find out how to add libs to ANDROID_EXTRA_LIBS in cmake file. Then pack libomp.so into your project. It is not packed and therefore, your code can not find it.
If you can find a static one, then no problem after build.libomp is an extra lib and you have to add it by yourself. Qt libs are added automatically. You can check which libs are included in your apk.
https://doc.qt.io/qt-6/cmake-target-property-qt-android-extra-libs.html
wrote on 27 May 2023, 00:08 last edited by@JoeCFD Thanks for putting me on the right track, I've gotten it to work by cheating a bit.
I copied the libomp.so file from the sysroot for my Android image from the Android SDK to my project folder and added the following to my CmakeList.txt file:
set_target_properties(sim PROPERTIES QT_ANDROID_EXTRA_LIBS /dev/projects/srm/libomp.so )
The file gets packaged and the app works fine now. But of course this only works for this particular version of Android and for this processor architecture. The right way to do this would be to use the right sysroot for this library automatically based on the build settings. How would that be done? I am new to both Android development and cmake...
-
@JoeCFD Thanks for putting me on the right track, I've gotten it to work by cheating a bit.
I copied the libomp.so file from the sysroot for my Android image from the Android SDK to my project folder and added the following to my CmakeList.txt file:
set_target_properties(sim PROPERTIES QT_ANDROID_EXTRA_LIBS /dev/projects/srm/libomp.so )
The file gets packaged and the app works fine now. But of course this only works for this particular version of Android and for this processor architecture. The right way to do this would be to use the right sysroot for this library automatically based on the build settings. How would that be done? I am new to both Android development and cmake...
wrote on 27 May 2023, 00:16 last edited by CharlesV@CharlesV Found it! This is fixed by adding libomp.so to the target_link_libraries. But instead of "libomp.so", we use "omp" only.
So adding these few lines resolved the problem:
if(ANDROID) target_link_libraries(${PROJECT_NAME} PUBLIC omp) endif()
It's not clear to me why this doesn't need to be done for the Windows build, or why the settings of the Windows build don't work for the Android build, and I would like to understand that.
Anyhow, thanks again @JoeCFD for putting me on the right track.
-
-
@CharlesV Found it! This is fixed by adding libomp.so to the target_link_libraries. But instead of "libomp.so", we use "omp" only.
So adding these few lines resolved the problem:
if(ANDROID) target_link_libraries(${PROJECT_NAME} PUBLIC omp) endif()
It's not clear to me why this doesn't need to be done for the Windows build, or why the settings of the Windows build don't work for the Android build, and I would like to understand that.
Anyhow, thanks again @JoeCFD for putting me on the right track.
wrote on 28 May 2023, 18:41 last edited by JoeCFD@CharlesV good you found it out. This is a lib in the system path on all platforms. The setting is not done with lib name directly on Android. You may try the same setting on Windows and it may work on Windows as well.
I learned something as well. Thanks.
1/7