Navigation

    UBports Robot Logo

    UBports Forum

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    How to use pthread in Native App

    App Development
    compilation link linking thread
    3
    6
    251
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Arc676
      Arc676 last edited by

      Is it possible to use pthread with a native Ubuntu Touch app built using clickable and cmake? I'm trying to link to a C library I've already written that depends on pthread but adding pthread as a dependency in CMakeLists.txt doesn't link (either that or the library is missing?). Building for desktop with clickable 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!

      1 Reply Last reply Reply Quote 0
      • dobey
        dobey last edited by

        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 use find_package(Threads REQUIRED) and then use ${CMAKE_THREAD_LIBS_INIT} variable in the target_link_libraries() call as an additional library.

        1 Reply Last reply Reply Quote 0
        • Arc676
          Arc676 last edited by

          The source code can be found on GitLab or GitHub.

          Where exactly should ${CMAKE_THREAD_LIBS_INIT} go?

          dobey 1 Reply Last reply Reply Quote 0
          • dobey
            dobey @Arc676 last edited by

            @Arc676 OK. It looks like you have the find_package() and are using Threads::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).

            1 Reply Last reply Reply Quote 0
            • Arc676
              Arc676 last edited by

              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.

              1 Reply Last reply Reply Quote 0
              • N
                nanu-c last edited by

                If it's still relevant, you are missing

                set(THREADS_PTHREAD_ARG "2" CACHE STRING "Forcibly set by CMakeLists.txt." FORCE)
                

                or something equal.

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post