How to use pthread in Native App
-
Is it possible to use
pthread
with a native Ubuntu Touch app built usingclickable
andcmake
? I'm trying to link to a C library I've already written that depends onpthread
but addingpthread
as a dependency inCMakeLists.txt
doesn't link (either that or the library is missing?). Building for desktop withclickable desktop
compiles successfully but then the module fails to load with the error message:file:///path/to/project/build/tmp/qml/Main.qml:29 Type ChatView unavailable file:///path/to/project/build/tmp/qml/ChatView.qml:19 plugin cannot be loaded for module "SockTalkFrontend": Cannot load library /path/to/project/build/tmp/lib/x86_64-linux-gnu/SockTalkFrontend/libSockTalkFrontend.so: (/path/to/project/build/tmp/lib/x86_64-linux-gnu/SockTalkFrontend/libSockTalkFrontend.so: undefined symbol: _ZTINSt6thread6_StateE)
If I recompile the library on the device and then build for mobile (
armhf
) it yields the following error:-- Looking for pthread.h -- Looking for pthread.h - found -- Looking for pthread_create -- Looking for pthread_create - not found -- Check if compiler accepts -pthread CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following cache variables appropriately: THREADS_PTHREAD_ARG (advanced) For details see /path/to/project//build/TryRunResults.cmake -- Check if compiler accepts -pthread - no -- Found Threads: TRUE -- Configuring incomplete, errors occurred!
Build logs (
CMakeError.log
) :Determining if the pthread_create exist failed with the following output: Change Dir: /path/to/project/build/CMakeFiles/CMakeTmp Run Build Command:"/usr/bin/make" "cmTC_802c3/fast" /usr/bin/make -f CMakeFiles/cmTC_802c3.dir/build.make CMakeFiles/cmTC_802c3.dir/build make[1]: Entering directory '/path/to/project/build/CMakeFiles/CMakeTmp' Building C object CMakeFiles/cmTC_802c3.dir/CheckSymbolExists.c.o /usr/bin/arm-linux-gnueabihf-gcc -o CMakeFiles/cmTC_802c3.dir/CheckSymbolExists.c.o -c /path/to/project/build/CMakeFiles/CMakeTmp/CheckSymbolExists.c Linking C executable cmTC_802c3 /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_802c3.dir/link.txt --verbose=1 /usr/bin/arm-linux-gnueabihf-gcc CMakeFiles/cmTC_802c3.dir/CheckSymbolExists.c.o -o cmTC_802c3 -rdynamic CMakeFiles/cmTC_802c3.dir/CheckSymbolExists.c.o: In function `main': CheckSymbolExists.c:(.text+0xe): undefined reference to `pthread_create' CheckSymbolExists.c:(.text+0x12): undefined reference to `pthread_create' collect2: error: ld returned 1 exit status CMakeFiles/cmTC_802c3.dir/build.make:97: recipe for target 'cmTC_802c3' failed make[1]: *** [cmTC_802c3] Error 1 make[1]: Leaving directory '/path/to/project/build/CMakeFiles/CMakeTmp' Makefile:126: recipe for target 'cmTC_802c3/fast' failed make: *** [cmTC_802c3/fast] Error 2 File /path/to/project/build/CMakeFiles/CMakeTmp/CheckSymbolExists.c: /* */ #include <pthread.h> int main(int argc, char** argv) { (void)argv; #ifndef pthread_create return ((int*)(&pthread_create))[argc]; #else (void)argc; return 0; #endif } Determining if compiler accepts -pthread returned PLEASE_FILL_OUT-FAILED_TO_RUN instead of 2. The compiler had the following output: Change Dir: /path/to/project/build/CMakeFiles/CMakeTmp Run Build Command:"/usr/bin/make" "cmTC_1d99c/fast" /usr/bin/make -f CMakeFiles/cmTC_1d99c.dir/build.make CMakeFiles/cmTC_1d99c.dir/build make[1]: Entering directory '/path/to/project/build/CMakeFiles/CMakeTmp' Building C object CMakeFiles/cmTC_1d99c.dir/CheckForPthreads.c.o /usr/bin/arm-linux-gnueabihf-gcc -o CMakeFiles/cmTC_1d99c.dir/CheckForPthreads.c.o -c /usr/share/cmake-3.5/Modules/CheckForPthreads.c Linking C executable cmTC_1d99c /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_1d99c.dir/link.txt --verbose=1 /usr/bin/arm-linux-gnueabihf-gcc CMakeFiles/cmTC_1d99c.dir/CheckForPthreads.c.o -o cmTC_1d99c -rdynamic -pthread make[1]: Leaving directory '/path/to/project/build/CMakeFiles/CMakeTmp'
I would prefer not to have to rewrite the library, but I'm open to adapting the thread type if necessary. Thanks!
-
I would need to see the source and cmake files to give you an accurate answer, but first thing I would say is that you shouldn't just put
pthread
in the compiler flags or target libraries commands in cmake. Instead you should usefind_package(Threads REQUIRED)
and then use${CMAKE_THREAD_LIBS_INIT}
variable in thetarget_link_libraries()
call as an additional library. -
-
@Arc676 OK. It looks like you have the
find_package()
and are usingThreads::Threads
there already, so that should work.But it looks like you're using a static binary which you've included in the git repo? And you're calling
target_link_libraries()
multiple times. You should only call it once for each target, and list all the libraries you're linking against in the arguments, I think (you can place each argument on a separate line so it's easier to read). -
Yes, the library is a static library included in the repository (compiled with
-fPIC
). The README in the linked repository includes a link to the repository for just the library.I changed the Makefile to have
set(CMAKE_AUTOMOC ON) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) include_directories(${CMAKE_SOURCE_DIR}/plugins/SockTalkFrontend/lib) link_directories(${CMAKE_SOURCE_DIR}/plugins/SockTalkFrontend/lib) add_library(${PLUGIN} MODULE ${SRC}) target_link_libraries(${PLUGIN} ${CMAKE_SOURCE_DIR}/plugins/SockTalkFrontend/lib/libsocktalk.a Threads::Threads) set_target_properties(${PLUGIN} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN}) qt5_use_modules(${PLUGIN} Qml Quick DBus)
But it didn't change the outcome. Thanks for the tip of linking multiple libraries in the same call though.
-
If it's still relevant, you are missing
set(THREADS_PTHREAD_ARG "2" CACHE STRING "Forcibly set by CMakeLists.txt." FORCE)
or something equal.