[CMake] find_package(Threads) leads to CMake Error: TRY_RUN() invoked in cross-compiling mode
Steffen Dettmer
steffen.dettmer at gmail.com
Thu Aug 3 11:59:04 EDT 2017
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)
More information about the CMake
mailing list