1

I a CMake project, I am trying to test for availability of pthread_setname_np(). As for the headers, this function prototype only seems to be exposed if I #define _GNU_SOURCE first.

Probably for this reason, simply doing

CHECK_FUNCTION_EXISTS(pthread_setname_np HAVE_PTHREAD_SETNAME_NP)

will not detect the function even though it is present. The documentation mentions CMAKE_REQUIRED_DEFINITIONS but I am not sure how to use it (nor if it is the right way at all).

How can I get CMake to correctly detect the presence of this function?

user149408
  • 5,385
  • 4
  • 33
  • 69

2 Answers2

2

This eventually worked for me (at least on Ubuntu 18.04, currently running CI for others):

list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
list(APPEND CMAKE_REQUIRED_LIBRARIES pthread)
CHECK_SYMBOL_EXISTS(pthread_setname_np pthread.h HAVE_PTHREAD_SETNAME_NP)
list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)

Important: make sure you have a clean build environment, with no leftovers from previous builds. For cmake4eclipse, this means:

  • Go to Project > Properties > C/C++ Build > CMake and check Force CMake to run with each build. (You can clear that option again after your first successful build.)
  • Clean your project.

Appending the pthread library proved necessary for me, otherwise it would not detect the function. The library name seems to be pthreads on some systems (at least I see CMake testing for both); these systems may need further tweaks to detect the function.

CHECK_FUNCTION_EXISTS instead of CHECK_SYMBOL_EXISTS would have worked as well (I have tried both successfully).

user149408
  • 5,385
  • 4
  • 33
  • 69
1

Yes, CMAKE_REQUIRED_DEFINITIONS is a correct way to test for this function. Here's an example of its use:

set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
CHECK_FUNCTION_EXISTS(pthread_setname_np HAVE_PTHREAD_SETNAME_NP)
unset(CMAKE_REQUIRED_DEFINITIONS)

You also probably want to read this: What does “#define _GNU_SOURCE” imply?

arrowd
  • 33,231
  • 8
  • 79
  • 110
  • Thanks, you’re getting an upvote for this. Alas, it still doesn’t work—CMake does not find the function, despite it being defined in the header file. Could that have to do with the need to define `_GNU_SOURCE` **before** including the header (as an answer to your linked question points out)? – user149408 Mar 25 '19 at 12:06
  • That's right - you have to define `_GNU_SOURCE` in both cases: when you testing for `pthread_setname_np` function and when you're using it within your code. Instead of defining it before including the header, you can also do `add_definitions(-D_GNU_SOURCE)` in CMakeLists.txt – arrowd Mar 25 '19 at 12:10
  • CMake still isn’t picking it up and `config.h` does not define `HAVE_PTHREAD_SETNAME_NP`. Same with `add_definitions`, or with the approach described in https://stackoverflow.com/q/13541788/2703209 (without touching `CMAKE_REQUIRED_LIBRARIES` as I don’t think I need any extra here). – user149408 Mar 25 '19 at 12:24
  • 1
    Take a look at logs located somewhere in your build directory. Specifically, `CMakeFiles/` dir. – arrowd Mar 25 '19 at 13:19
  • Thanks, that provided the hints I needed. Will post a new answer. – user149408 Mar 25 '19 at 23:05
  • I get: `CMake Error at threadpool/CMakeLists.txt:14 (CHECK_FUNCTION_EXISTS): Unknown CMake command "CHECK_FUNCTION_EXISTS".` – Carlo Wood Feb 17 '22 at 13:36