liblzma: Silence warnings in --enable-small build.
[xz.git] / cmake / tuklib_cpucores.cmake
blobe5e9c34d7fec9c17a82aedf459a293e83af6dd46
1 # SPDX-License-Identifier: 0BSD
3 #############################################################################
5 # tuklib_cpucores.cmake - see tuklib_cpucores.m4 for description and comments
7 # Author: Lasse Collin
9 #############################################################################
11 include("${CMAKE_CURRENT_LIST_DIR}/tuklib_common.cmake")
12 include(CheckCSourceCompiles)
13 include(CheckIncludeFile)
15 function(tuklib_cpucores_internal_check)
16     if(WIN32 OR CYGWIN)
17         # Nothing to do, the tuklib_cpucores.c handles it.
18         set(TUKLIB_CPUCORES_DEFINITIONS "" CACHE INTERNAL "")
19         return()
20     endif()
22     # glibc-based systems (GNU/Linux and GNU/kFreeBSD) have
23     # sched_getaffinity(). The CPU_COUNT() macro was added in glibc 2.9.
24     # glibc 2.9 is old enough that if someone uses the code on older glibc,
25     # the fallback to sysconf() should be good enough.
26     #
27     # NOTE: This required that _GNU_SOURCE is defined. We assume that whatever
28     #       feature test macros the caller wants to use are already set in
29     #       CMAKE_REQUIRED_DEFINES and in the target defines.
30     check_c_source_compiles("
31             #include <sched.h>
32             int main(void)
33             {
34                 cpu_set_t cpu_mask;
35                 sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask);
36                 return CPU_COUNT(&cpu_mask);
37             }
38         "
39         TUKLIB_CPUCORES_SCHED_GETAFFINITY)
40     if(TUKLIB_CPUCORES_SCHED_GETAFFINITY)
41         set(TUKLIB_CPUCORES_DEFINITIONS
42             "TUKLIB_CPUCORES_SCHED_GETAFFINITY"
43             CACHE INTERNAL "")
44         return()
45     endif()
47     # FreeBSD has both cpuset and sysctl. Look for cpuset first because
48     # it's a better approach.
49     #
50     # This test would match on GNU/kFreeBSD too but it would require
51     # -lfreebsd-glue when linking and thus in the current form this would
52     # fail on GNU/kFreeBSD. The above test for sched_getaffinity() matches
53     # on GNU/kFreeBSD so the test below should never run on that OS.
54     check_c_source_compiles("
55             #include <sys/param.h>
56             #include <sys/cpuset.h>
57             int main(void)
58             {
59                 cpuset_t set;
60                 cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
61                                    sizeof(set), &set);
62                 return 0;
63             }
64         "
65         TUKLIB_CPUCORES_CPUSET)
66     if(TUKLIB_CPUCORES_CPUSET)
67         set(TUKLIB_CPUCORES_DEFINITIONS "HAVE_PARAM_H;TUKLIB_CPUCORES_CPUSET"
68             CACHE INTERNAL "")
69         return()
70     endif()
72     # On OS/2, both sysconf() and sysctl() pass the tests in this file,
73     # but only sysctl() works. On QNX it's the opposite: only sysconf() works
74     # (although it assumes that _POSIX_SOURCE, _XOPEN_SOURCE, and
75     # _POSIX_C_SOURCE are undefined or alternatively _QNX_SOURCE is defined).
76     #
77     # We test sysctl() first and intentionally break the sysctl() test on QNX
78     # so that sysctl() is never used on QNX.
79     check_include_file(sys/param.h HAVE_SYS_PARAM_H)
80     if(HAVE_SYS_PARAM_H)
81         list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_PARAM_H)
82     endif()
83     check_c_source_compiles("
84             #ifdef __QNX__
85             compile error
86             #endif
87             #ifdef HAVE_SYS_PARAM_H
88             #   include <sys/param.h>
89             #endif
90             #include <sys/sysctl.h>
91             int main(void)
92             {
93             #ifdef HW_NCPUONLINE
94                 /* This is preferred on OpenBSD, see tuklib_cpucores.c. */
95                 int name[2] = { CTL_HW, HW_NCPUONLINE };
96             #else
97                 int name[2] = { CTL_HW, HW_NCPU };
98             #endif
99                 int cpus;
100                 size_t cpus_size = sizeof(cpus);
101                 sysctl(name, 2, &cpus, &cpus_size, NULL, 0);
102                 return 0;
103             }
104         "
105         TUKLIB_CPUCORES_SYSCTL)
106     if(TUKLIB_CPUCORES_SYSCTL)
107         if(HAVE_SYS_PARAM_H)
108             set(TUKLIB_CPUCORES_DEFINITIONS
109                 "HAVE_PARAM_H;TUKLIB_CPUCORES_SYSCTL"
110                 CACHE INTERNAL "")
111         else()
112             set(TUKLIB_CPUCORES_DEFINITIONS
113                 "TUKLIB_CPUCORES_SYSCTL"
114                 CACHE INTERNAL "")
115         endif()
116         return()
117     endif()
119     # Many platforms support sysconf().
120     check_c_source_compiles("
121             #include <unistd.h>
122             int main(void)
123             {
124                 long i;
125             #ifdef _SC_NPROCESSORS_ONLN
126                 /* Many systems using sysconf() */
127                 i = sysconf(_SC_NPROCESSORS_ONLN);
128             #else
129                 /* IRIX */
130                 i = sysconf(_SC_NPROC_ONLN);
131             #endif
132                 return 0;
133             }
134         "
135         TUKLIB_CPUCORES_SYSCONF)
136     if(TUKLIB_CPUCORES_SYSCONF)
137         set(TUKLIB_CPUCORES_DEFINITIONS "TUKLIB_CPUCORES_SYSCONF"
138             CACHE INTERNAL "")
139         return()
140     endif()
142     # HP-UX
143     check_c_source_compiles("
144             #include <sys/param.h>
145             #include <sys/pstat.h>
146             int main(void)
147             {
148                 struct pst_dynamic pst;
149                 pstat_getdynamic(&pst, sizeof(pst), 1, 0);
150                 (void)pst.psd_proc_cnt;
151                 return 0;
152             }
153         "
154         TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
155     if(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
156         set(TUKLIB_CPUCORES_DEFINITIONS "TUKLIB_CPUCORES_PSTAT_GETDYNAMIC"
157             CACHE INTERNAL "")
158         return()
159     endif()
160 endfunction()
162 function(tuklib_cpucores TARGET_OR_ALL)
163     if(NOT DEFINED TUKLIB_CPUCORES_FOUND)
164         message(STATUS
165                 "Checking how to detect the number of available CPU cores")
166         tuklib_cpucores_internal_check()
168         if(DEFINED TUKLIB_CPUCORES_DEFINITIONS)
169             set(TUKLIB_CPUCORES_FOUND 1 CACHE INTERNAL "")
170         else()
171             set(TUKLIB_CPUCORES_FOUND 0 CACHE INTERNAL "")
172             message(WARNING
173                     "No method to detect the number of CPU cores was found")
174         endif()
175     endif()
177     if(TUKLIB_CPUCORES_FOUND)
178         tuklib_add_definitions("${TARGET_OR_ALL}"
179                                "${TUKLIB_CPUCORES_DEFINITIONS}")
180     endif()
181 endfunction()