Hi,

I tried to fix linux (p)thread usage on a proprietary, somewhat
complex (300-400 cmake files, ca 30.000 lines) cmake project. We
have CMAKE_TOOLCHAIN_FILEs for the cross compiling platforms.
These set(CMAKE_SYSTEM_NAME Linux),
CMAKE_C_FLAGS(....-D_REENTRANT... CACHE STRING "" FORCE)) and so
on.

I like to see -pthread on gcc (g++4 and g++5) and if needed
-lphtread. I now spent almost two days without success and hope I
can get a bit help here.

I learned that someone is supposed to use

  find_package(Threads REQUIRED)

instead of specifying CMAKE_C_FLAGS. This works fine for a
minimal CMakeLists.txt example (cmake version 3.6.2):

  cmake_minimum_required(VERSION 3.6)
  project(phello C CXX)

  set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
  set(THREADS_PREFER_PTHREAD_FLAG TRUE)
  find_package(Threads REQUIRED)

  add_executable(phello phello.c)
  target_link_libraries(phello Threads::Threads)

but the same fails when cross compiling:

  -- 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
/local/users/sdettmer/work/cmake-toolchain-1.4/threadtest/b2/TryRunResults.cmake
  -- Check if compiler accepts -pthread - no
  -- Found Threads: TRUE
  -- Configuring incomplete, errors occurred!
  See also 
"/local/users/sdettmer/work/cmake-toolchain-1.4/threadtest/b2/CMakeFiles/CMakeOutput.log".
  See also 
"/local/users/sdettmer/work/cmake-toolchain-1.4/threadtest/b2/CMakeFiles/CMakeError.log".

and then no Makefile as expected:

  $ make
  make: *** No targets specified and no makefile found.  Stop.

If then I run cmake again without any change:

  -- Configuring done
  -- Generating done
  -- Build files have been written to:
/local/users/sdettmer/work/cmake-toolchain-1.4/threadtest/b2

suddenly no error and then it even works:

  $ make VERBOSE=1
  [...]
  /opt/xyzcross/x86-linux2/bin/powerpc-linux-gnu-gcc \
  --sysroot=/opt/xyzcross/1.2.0.0/sysroots/xyz/sysroot \
  -L/opt/xyzcross/1.2.0.0/sysroots/sysroot/lib \
  -L/opt/xyzcross/1.2.0.0/sysroots/sysroot/usr/lib \
  CMakeFiles/phello.dir/phello.c.o  -o phello -pthread

a behavior I don't understand. I think this is incorrect. I think,
first, cmake should not TRY_RUN when crosscompiling,
second, running cmake again should not generate different results.

What do I wrong?
How can I get it working correctly on first run?


In CMakeFiles/CMakeError.log I see that linking fails without
-pthread (undefined reference to `pthread_create') and then works
when using -pthread, so actually looks like expected when
assuming find_package(Threads) tries to check first whether
-pthread is needed at all and then if it is working. However, the
second run may treated as error:

  Determining if compiler accepts -pthread returned
PLEASE_FILL_OUT-FAILED_TO_RUN instead of 2. The compiler had the
following output:
  Change Dir: 
/local/users/sdettmer/work/cmake-toolchain-1.4/threadtest/b2/CMakeFiles/CMakeTmp

  Run Build Command:"/usr/bin/make" "cmTC_47cd8/fast"
  /usr/bin/make -f CMakeFiles/cmTC_47cd8.dir/build.make
CMakeFiles/cmTC_47cd8.dir/build
  make[1]: Entering directory
'/srv/local/sdettmer/work/cmake-toolchain-1.4/threadtest/b2/CMakeFiles/CMakeTmp'
  Building C object CMakeFiles/cmTC_47cd8.dir/CheckForPthreads.c.o
  /opt/xyzcross/x86-linux2/bin/powerpc-linux-gnu-gcc --sysroot=...
   -o CMakeFiles/cmTC_47cd8.dir/CheckForPthreads.c.o   -c
/usr/local/share/cmake-3.6/Modules/CheckForPthreads.c

  Linking C executable cmTC_47cd8
  /usr/local/bin/cmake -E cmake_link_script
CMakeFiles/cmTC_47cd8.dir/link.txt --verbose=1

  /opt/xyzcross/x86-linux2/bin/powerpc-linux-gnu-gcc  [...]
    CMakeFiles/cmTC_47cd8.dir/CheckForP
     threads.c.o  -o cmTC_47cd8 -pthread

  make[1]: Leaving directory
'/srv/local/sdettmer/work/cmake-toolchain-1.4/threadtest/b2/CMakeFiles/CMakeTmp'

(blank lines + line wraps added by me)

If I copy the mentioned gcc command to a shell and change only
the file name (CheckForPthreads does not exist anymore, so I use
an own pthread_create() main test), it works as expected, no
output to console but

  $ file cmTC_47cd8
  cmTC_47cd8: ELF 32-bit MSB executable, PowerPC or cisco 4500,
     version 1 (SYSV), dynamically linked,
     interpreter /lib/ld.so.1, for GNU/Linux 2.6.10, not stripped

so compiler seems to work fine.

What does "-pthread returned PLEASE_FILL_OUT-FAILED_TO_RUN
instead of 2." mean? That I'm supposed to run the test binary on
target and put the result in a CMakeFiles.txt variable?

Any hints appreciated,
Steffen

TryRunResults.cmake:
# This file was generated by CMake because it detected TRY_RUN() commands
# in crosscompiling mode. It will be overwritten by the next CMake run.
# Copy it to a safe location, set the variables to appropriate values
# and use it then to preset the CMake cache (using -C).


# THREADS_PTHREAD_ARG
#    indicates whether the executable would have been able to run on its
#    target platform. If so, set THREADS_PTHREAD_ARG to
#    the exit code (in many cases 0 for success), otherwise enter
"FAILED_TO_RUN".
# The THREADS_HAVE_PTHREAD_ARG variable holds the build result for
this TRY_RUN().
#
# Source file   : /usr/local/share/cmake-3.6/Modules/CheckForPthreads.c
# Executable    :
/local/users/sdettmer/work/cmake-toolchain-1.4/threadtest/b2/CMakeFiles/cmTC_47cd8-THREADS_PTHREAD_
ARG
# Run arguments :
#    Called from: [3]   /usr/local/share/cmake-3.6/Modules/FindThreads.cmake
#                 [2]   /usr/local/share/cmake-3.6/Modules/FindThreads.cmake
#                 [1]
/local/users/sdettmer/work/cmake-toolchain-1.4/threadtest/CMakeLists.txt

set( THREADS_PTHREAD_ARG
     "PLEASE_FILL_OUT-FAILED_TO_RUN"
     CACHE STRING "Result from TRY_RUN" FORCE)
-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake

Reply via email to