-
Notifications
You must be signed in to change notification settings - Fork 70
/
Herc22_Userland.cmake
901 lines (702 loc) · 35.3 KB
/
Herc22_Userland.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
# Herc22_Userland.cmake - perform Userland tests to build Hercules
#[[ Copyright 2017 by Stephen Orso.
Distributed under the Boost Software License, Version 1.0.
See accompanying file BOOST_LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
]]
#[[
This file checks for all required and optional target system components
used when building Hercules. If any required component is missing,
the build cannot proceed. If an optional component is missang and is
specifically requested in a build option, say Regina Rexx, the build
cannot proceed.
The tests are not as simple as yes-no, though. If a preferred header
or function is not available, a Hercules-internal substitute might do.
The logic to trigger substitution through preprocessor macros is here;
Hercules code must adapt to the missing function/header by testing
preprocessor variables.
If an optional component is missing from the target system and is
not specifically requested by a build option, the capability enabled
by the component is not included in Hercules.
]]
message( "Checking for required public headers" )
herc_Check_Include_Files( ctype.h FAIL )
herc_Check_Include_files( dlfcn.h FAIL )
herc_Check_Include_Files( errno.h FAIL )
herc_Check_Include_Files( fcntl.h FAIL )
herc_Check_Include_Files( limits.h FAIL )
herc_Check_Include_Files( setjmp.h FAIL )
herc_Check_Include_Files( stdarg.h FAIL )
herc_Check_Include_Files( stdio.h FAIL )
herc_Check_Include_Files( stdlib.h FAIL )
herc_Check_Include_Files( stddef.h FAIL )
herc_Check_Include_Files( string.h FAIL )
herc_Check_Include_Files( sched.h FAIL )
herc_Check_Include_Files( time.h FAIL )
herc_Check_Include_Files( sys/ioctl.h FAIL )
herc_Check_Include_Files( sys/stat.h FAIL )
herc_Check_Include_Files( sys/time.h FAIL )
herc_Check_Include_Files( sys/types.h FAIL )
herc_Check_Include_Files( sys/mman.h FAIL )
herc_Check_Include_Files( sys/resource.h FAIL )
herc_Check_Include_Files( sys/utsname.h FAIL )
herc_Check_Include_Files( sys/wait.h FAIL )
herc_Check_Include_Files( pwd.h FAIL )
herc_Check_Include_Files( unistd.h FAIL )
herc_Check_Include_Files( math.h FAIL )
# Apple macOS is and is not UNIX-like. More or less a POSIX userland,
# but a different ABI, a different executable/library format, and some
# APIs not available on POSIX. Definitely not GNU/Linux. Hercules
# needs only a few tests, and we do them here because the rest of the
# UNIX-like tests are appropriate for Apple macOS.
if( APPLE )
# Header mach-o/dyld.h defines the function call to determine whether
# _NS_
# to get the executable path name. Hercules can run without the
# system call.
# CMake does not seem to like hyphens in #cmakedefine statements.
# So we need to define a more suitable macro for config.h. Hence
# the if/set following the test. Besides, if the header is absent,
# the API function it exposes will be absent too.
herc_Check_Include_Files( mach-o/dyld.h OK )
if( HAVE_MACH-O_DYLD_H )
set( HAVE_MACH_O_DYLD_H 1 )
herc_Check_Function_Exists( _NSGetExecutablePath OK )
endif( )
endif( )
# definitions in assert.h are used only when compiled under Microsoft,
# in only one module, hatomic.h, and it is assumed to exist under
# Microsoft. So there is no need (for the moment) to test for it here.
# Function strsignal helpful but not required. If it does not exist, we
# need signal.h so that Hercules can compile its own version in strsignal.c.
# But because signal.h is required by dbgtrace.h and the build fails without
# it, strsignal is really optional for the build.
herc_Check_Function_Exists( strsignal OK )
# Needed by a "BREAK_INTO_DEBUGGER" macro, defined in dbgtrace.h and
# referenced in hthreads.c and ptrace.c. This is worth a further look.
# And if the macro is changed, the test above for strsignal needs
# to be augmented such that if strsignal does not exist, signal.h
# remains mandatory.
herc_Check_Include_Files( signal.h FAIL )
# See if we have the declarations and structure members needed to
# create a sigabend handler.
herc_Check_Struct_Member( sigaction sa_sigaction signal.h OK )
herc_Check_Symbol_Exists( SIGUSR1 signal.h OK )
herc_Check_Symbol_Exists( SIGUSR2 signal.h OK )
herc_Check_Symbol_Exists( SIGPIPE signal.h OK )
herc_Check_Symbol_Exists( SIGBUS signal.h OK )
if( NOT ( HAVE_SIGACTION_SA_SIGACT
AND HAVE_SIGUSR1
AND HAVE_SIGUSR2
AND HAVE_SIGPIPE
AND HAVE_SIGBUS )
)
set( NO_SIGABEND_HANDLER 1 )
endif( )
# sys/sysctl requires a type definition available in a number of headers.
# We pick stddef, and we know it exists. It is used only on Apple and
# FreeBSD, and is not required on other systems. For the moment, we shall
# mark it optional.
herc_Check_Include_Files( "stddef.h;sys/sysctl.h" OK )
# sys/sockio.h must be explicitly included on Solaris; it is included by
# ioctl.h on BSD systems. Do the test here so the config.h macro can be
# defined.
herc_Check_Include_Files( sys/sockio.h OK )
# Check for public header variables defined by libtool use in the
# autotools build.
herc_Check_Include_Files( dirent.h FAIL )
# Check networking public headers, which are *required* to build Hercules.
#
# On OS X 10.3, sys/types.h apparently must be included before sys/socket.h
#
# On other Darwin and BSD-based systems except FreeBSD 11 (and 12?),
# sys/socket.h must be included before net/if.h, net/route.h, and
# netinet/in.h. It is not clear if sys/types.h and/or sys/socket.h are
# needed for net/tcp.h or netinet/tcp.h.
#
# So for the sake of simplicity and robustness, all network headers are
# tested by including sys/types.h and, if present on the system,
# sys/socket.h before the header under test.
#
# It is also not clear if Hercules needs net/route.h
#
set( prereq_Headers sys/types.h )
herc_Check_Include_Files( "${prereq_Headers};sys/socket.h" FAIL )
if ( ${HAVE_SYS_SOCKET_H} )
set( prereq_Headers ${prereq_Headers} sys/socket.h )
endif( )
herc_Check_Include_Files( "${prereq_Headers};netinet/in.h" FAIL )
herc_Check_Include_Files( "${prereq_Headers};net/if.h" FAIL )
herc_Check_Include_Files( "${prereq_Headers};netdb.h" FAIL )
# It is not clear whether Hercules needs route.h.
herc_Check_Include_Files( "${prereq_Headers};net/route.h" OK )
# tcp.h might be found in either net or netinet. If it's not in netinet,
# we will test net and let that issue the failure message.
herc_Check_Include_Files( "${prereq_Headers};netinet/tcp.h" OK )
if ( HAVE_NETINET_TCP_H )
else( )
herc_Check_Include_Files( "${prereq_Headers};net/tcp.h" FAIL )
endif( )
herc_Check_Include_Files( "${prereq_Headers};arpa/inet.h" FAIL )
# Header linux/if_tun.h is needed (based on tests below) only for hercifc.
# So Hercules will build without it, but hercifc will not on Linux systems.
# On BSD systems, again based on configure.ac, linux/if_tun.h is not
# required (hint: not many linux directories on a BSD system), and
# net/if.h (tested above and required) will be enough.
if( BUILD_HERCIFC AND ( CMAKE_SYSTEM_NAME MATCHES "Linux" ) )
herc_Check_Include_Files( "linux/if_tun.h" OK )
if( NOT HAVE_LINUX_IF_TUN_H )
herc_Save_Error( "Header \"linux/if_tun.h\" is needed to build hercifc on Linux" )
endif( )
endif( )
# Now that we have a complete set of headers for networking, check for
# networking structures and members. Note that the variable prereq_Headers
# used above for public header tests is also used here. If the header
# is not required and does not exist, then any identifiers in the header
# do not exist...and should not be required either.
if( ${HAVE_NETINET_IN_H} )
herc_Check_Struct_Member( in_addr s_addr "${prereq_Headers};netinet/in.h" FAIL )
herc_Check_Struct_Member( sockaddr_in sin_len "${prereq_Headers};netinet/in.h" OK )
endif( )
# Hercules htypes.h will typedef in_addr_t to unsigned int if it is not
# defined, so if missing, Hercules can build. It should be defined # in
# netinet/in.h, a required header.
set( CMAKE_EXTRA_INCLUDE_FILES "${prereq_Headers};netinet/in.h" )
check_type_size( in_addr_t IN_ADDR_T )
unset( CMAKE_EXTRA_INCLUDE_FILES )
# socklen_t should be defined in sys/socket.h, one of the headers in
# ${prereq_Headers}. If sys/socket.h is missing, and therefore socklen_t
# is missing, Hercules will define socklen_t as unsigned int.
set( CMAKE_EXTRA_INCLUDE_FILES "${prereq_Headers}" )
check_type_size( socklen_t SOCKLEN_T )
unset( CMAKE_EXTRA_INCLUDE_FILES )
# In configure.ac, much work is done testing for IPV6 headers. Sadly,
# this work is wasted. Only hifr.h includes IPV6 headers, and here's
# a summary:
# linux/ipv6.h - included only if it exists and if IPV6 and
# HAVE_IN6_IFREQ_IFR6_ADDR are defined.
# netinet6/in6_var.h - included only if it exists and if IPV6 and
# HAVE_IN6_IFREQ_IFR6_ADDR are defined.
# Unfortunately for all of the above, HAVE_IN6_IFREQ_IFR6_ADDR is
# *NEVER* defined. On Linux systems, HAVE_STRUCT_IN6_IFREQ_IFR6_ADDR
# is defined (note the addition of "STRUCT" in the macro). On BSD
# systems (including Apple??), HAVE_STRUCT_IN6_IFREQ_IFR_IFRU_IFRU_FLAGS
# is defined.
# And nowhere in Hercules is there an attempt to deal with the naming
# differences (IFR6 versus IFRU) between Linux and BSD IPV6
# implementations.
# If HAVE_IN6_IFREQ_IFR6_ADDR is not defined, then hifr.h defines its
# own IPV6 networking structures (not many are needed) and uses the
# Linux convention to do so. Because Hercules works without the IPV6
# headers, we will not code any of things in configure.ac into CMake.
# "Fixing" this would likely mean breaking stuff that now works. This
# should be fixed, but not here and not now; I am thinking CMake build
# for Hercules V3 or later. See Hercules issue #223. See configure.ac
# line 724 and following (as of commit 1428eee).
# (https://github.com/hercules-390/hyperion/blob/1428eee3844f1445a6ed80b10da4d81bbc7f4840/configure.ac)
# Test for TCP/IP keepalive support. Either SO_KEEPALIVE or TCP_KEEPALIVE
# indicate basic support. If any of TCP_KEEPIDLE, TCP_KEEPINTVL, or
# TCP_KEEPCNT are present, then partial keepalive is supported by the
# target, and if all three present, the the target supports full keepalive.
# The following tests still make use of ${prereq_Headers} in addition to
# those specifically required for each macro. The TCP_KEEP* macros are
# defined in tcp.h, a required header, whereever that happens to be.
if( HAVE_NETINET_TCP_H )
set( keepalive_Headers ${prereq_Headers} netinet/tcp.h )
elseif( HAVE_NET_TCP_H )
set( keepalive_Headers ${prereq_Headers} net/tcp.h )
endif( )
herc_Check_Symbol_Exists( SO_KEEPALIVE "${prereq_Headers}" OK )
if( NOT HAVE_DECL_SO_KEEPALIVE )
herc_Check_Symbol_Exists( TCP_KEEPALIVE "${keepalive_Headers}" OK )
endif( )
if( HAVE_DECL_SO_KEEPALIVE OR HAVE_DECL_TCP_KEEPALIVE )
set( HAVE_BASIC_KEEPALIVE 1 )
herc_Check_Symbol_Exists( TCP_KEEPIDLE "${keepalive_Headers}" OK )
herc_Check_Symbol_Exists( TCP_KEEPINTVL "${keepalive_Headers}" OK )
herc_Check_Symbol_Exists( TCP_KEEPCNT "${keepalive_Headers}" OK )
if( HAVE_DECL_TCP_KEEPIDLE # If any of the three, partial support
OR HAVE_DECL_TCP_KEEPINTVL
OR HAVE_DECL_TCP_KEEPCNT )
set( HAVE_PARTIAL_KEEPALIVE 1 ) # All of the three, full support
if( HAVE_DECL_TCP_KEEPIDLE
AND HAVE_DECL_TCP_KEEPINTVL
AND HAVE_DECL_TCP_KEEPCNT )
set( HAVE_FULL_KEEPALIVE 1 )
endif( )
endif( )
endif( )
# Sundry networking macros.
herc_Check_Symbol_Exists( IFNAMSIZ "${prereq_Headers};net/if.h" OK )
# The following IOCTL values SIOC* are used for CTC support only.
# Linux systems define IOCTL values as constants in linux/sockios.h
# (note the plural), which is included by sys/ioctl.h.
# BSD systems define IOCTL values as constants in sys/sockio.h (note the
# singular), which is included by sys/ioctl.h.
# Solaris systems also define IOCTL values as constants in sys/sockio.h
# (singular, just like BSD), and it must be included explicitly.
# For BSD systems, the Hercules autotools tests never detected the SIOC*
# macros and so the corresponding functionality was never built in the
# Hercules. And as a result, functionality enabled by these macros has
# not received much use on BSD.
# IOCTL values are used in hostopts.h to get and/or set interface options
# in the CTC modules ctc_ptp.c, hercifc.c, and tuntap.c.
# So we shall check for the existence of linux/sockios.h as a tell-tale
# for a Linux-based SIOC* implementation and sys/sockio.h as a tell-tale
# for a BSD or Solaris-based SIOC* implementation. If neither exist,
# then none of the values will be defined. If sys/sockio.h exists, we
# will include it in the build. This allows builds on Solaris without
# having to test for the Solaris target.
# For compatibilty with the autotools build, if this is a BSD-style
# SIOC* macro definition set, the tests are skipped and config.h will
# reflect an absence of this capability. Someone with CTC experience
# (me perhaps, once I buy a modified Delorean?) can test the BSD stuff.
set( SIOC_headers "" )
herc_Check_Include_Files( "${prereq_Headers};linux/sockios.h" OK )
if( HAVE_LINUX_SOCKIOS_H )
set( SIOC_headers "${prereq_Headers};sys/ioctl.h" )
else( )
herc_Check_Include_Files( "${prereq_Headers};sys/sockio.h" OK )
if( HAVE_SYS_SOCKIO_H )
set( SIOC_headers "${prereq_Headers};sys/ioctl.h;sys/sockio.h" )
endif( )
endif( )
if( (NOT ("${SIOC_headers}" STREQUAL ""))
AND ("${HAVE_LINUX_SOCKIOS_H}")
)
herc_Check_Symbol_Exists( SIOCSIFNETMASK "${SIOC_headers}" OK )
herc_Check_Symbol_Exists( SIOCSIFBRDADDR "${SIOC_headers}" OK )
herc_Check_Symbol_Exists( SIOCSIFHWADDR "${SIOC_headers}" OK )
herc_Check_Symbol_Exists( SIOCGIFHWADDR "${SIOC_headers}" OK )
herc_Check_Symbol_Exists( SIOCADDRT "${SIOC_headers}" OK )
herc_Check_Symbol_Exists( SIOCDELRT "${SIOC_headers}" OK )
herc_Check_Symbol_Exists( SIOCDIFADDR "${SIOC_headers}" OK )
endif( )
unset( SIOC_headers )
# On Windows, fthreads may be used in lieu of pthreads. So pthread.h is
# potentially optional on Windows but not otherwise. If pthreads is to be
# used on Windows and is allowed, we will issue any message about a missing
# pthread.h there. Otherwise, its absence fails the build.
set( CMAKE_THREADS_PREFER_PTHREAD 1)
set( THREADS_PREFER_PTHREAD_FLAG 1)
find_package( Threads REQUIRED )
set( herc_Threads_Target "Threads::Threads" )
if( WIN32 )
herc_Check_Include_Files( pthread.h OK )
else( )
if( NOT CMAKE_USE_PTHREADS_INIT )
herc_Save_Error( "Unable to use pthreads on this target. Hercules requires pthreads on non-Windows systems." )
endif( )
herc_Check_Include_Files( pthread.h FAIL )
endif( )
set( CMAKE_EXTRA_INCLUDE_FILES "sys/types.h" )
check_type_size( pthread_t SIZEOF_PTHREAD_T )
unset( CMAKE_EXTRA_INCLUDE_FILES )
# At least one of the following integer type headers must exist.
# Hercules file hstdint.h tests first for stdint.h, then inttypes.h,
# then unistd.h. Because inttypes.h normally includes stdint.h, one
# would think that the test order should be inttypes.h, stdint.h, and
# then unistd.h.
# Especially because unistd.h is included unconditionally for all
# non-Windows builds in hstdinc.h.
herc_Check_Include_Files( inttypes.h OK )
if( ${HAVE_INTTYPES_H} )
else( )
herc_Check_Include_Files( stdint.h OK )
if( ${HAVE_STDINT_H} )
else( )
if( ${HAVE_UNISTD_H} ) # Required, tested earlier.
else( )
herc_Save_Error( "Neither stdint.h, inttypes.h, nor unistd.h found. At least one is required" )
endif( )
endif( )
endif( )
# Test for stdbool.h. Its presence or absence needs to be recorded
# for correct expansion of the SoftFloat-3a headers included in ieee.c.
# Hercules will build without stdbool.h, but Hercules will not work
# when it is built without knowing about stdbool.h and SoftFloat-3a
# is built with it.
herc_Check_Include_Files( stdbool.h OK )
# check for functions and libraries required to build Hercules. CMake
# caching complicates this in two ways:
# - If a function is not included in the c runtime library, the cached
# result must be removed before testing another library. Otherwise
# CMake uses the cached result instead of testing the second library.
# - If a function is found in another library, we must cache the name of
# the other library, lest on a subsequent build the cached "function
# present result be seen without knowing that another library is needed
# to generate that result.
message( "Checking for required functions and libraries" )
# The following functions should be in the basic c Runtime library.
herc_Check_Function_Exists( getopt_long FAIL )
herc_Check_Function_Exists( strerror_r FAIL )
# The following function is not used in Hercules.
# herc_Check_Function_Exists( sys_siglist FAIL )
herc_Check_Function_Exists( sleep FAIL )
herc_Check_Function_Exists( usleep FAIL )
herc_Check_Function_Exists( nanosleep FAIL )
herc_Check_Function_Exists( strtok_r FAIL )
herc_Check_Function_Exists( gettimeofday FAIL )
herc_Check_Function_Exists( getpgrp FAIL )
herc_Check_Function_Exists( getlogin FAIL )
herc_Check_Function_Exists( getlogin_r FAIL )
herc_Check_Function_Exists( realpath FAIL )
herc_Check_Function_Exists( fsync FAIL )
herc_Check_Function_Exists( ftruncate FAIL )
herc_Check_Function_Exists( fork FAIL )
herc_Check_Function_Exists( sysconf FAIL )
# The following functions are used in Hercules without guarding. When
# built by configure.ac, libtool autotools code tested for these functions.
# We test for them here just for completeness. Because there is no
# guarding, there is no need for config.h macros.
herc_Check_Function_Exists( memcpy FAIL )
herc_Check_Function_Exists( strchr FAIL )
herc_Check_Function_Exists( strcmp FAIL )
herc_Check_Function_Exists( strrchr FAIL )
# dlerror is part of libdl on some systems, notably Linux, and part of
# the standard C runtime on others, notably BSD. CMake handles the
# different locations of libdl, and we will use that to test for dlerror.
set( CMAKE_REQUIRED_LIBRARIES "${CMAKE_DL_LIBS}" )
herc_Check_Function_Exists( dlerror FAIL )
set( CMAKE_REQUIRED_LIBRARIES "" )
# Pipe is required for non-Windows builds, and not required on Windows.
# On Windows, socketpair() is used in its place. Hercules does not
# check HAVE_PIPE; it is assumed to exist. So the build fails without it.
if( NOT WIN32 )
herc_Check_Function_Exists( pipe FAIL )
endif( )
# Function fseeko() and ftello() use off_t for the file offset or returned
# value respectively, instead of the long type used in fseek/ftell. It
# would surprise me to find a system with large file support, without
# fseeko, and with long defined as less than sizeof(off_t) bytes. But
# one never knows.
herc_Check_Function_Exists( fseeko OK )
if( NOT HAVE_FSEEKO )
if( SIZEOF_OFF_T GREATER "${SIZEOF_LONG}" )
herc_Save_Error( "Native large file support provided but fseeko missing and sizeof(long)=${SIZEOF_LONG}, less than sizeof(off_t)=${SIZEOF_OFF_T}")
endif( )
endif( )
# On many systems, inet_aton is found in the basic c runtime. On others
# (e.g., SunOS, Solaris) it is included in libnsl. For Windows, it does
# not exist...but on Windows the lack is OK because w23util.c includes a
# substitute inet_aton. However, w32util.c does not provide a copy of
# inet_ntoa, which is used far more often in Hercules and for which there
# is no guarding in the code. So the following is more about seeing
# whether libnsl is needed.
if( NOT WIN32 )
set( CMAKE_REQUIRED_LIBRARIES ${link_libnsl} )
herc_Check_Function_Exists( inet_aton OK )
if( NOT HAVE_INET_ATON )
unset( HAVE_INET_ATON CACHE )
set( CMAKE_REQUIRED_LIBRARIES "${name_libnsl}" )
herc_Check_Function_Exists( inet_aton FAIL )
if( HAVE_INET_ATON )
set( link_libnsl "${name_libnsl}" CACHE INTERNAL "include nameserver lookup functions" )
endif( )
endif( NOT HAVE_INET_ATON )
herc_Check_Function_Exists( inet_ntoa FAIL )
set( CMAKE_REQUIRED_LIBRARIES "" )
endif( NOT WIN32 )
# On some (?) systems, gethostbyname is found in the basic c runtime.
# On others (e.g., SunOS, Solaris) it is included in libnsl. For Windows,
# it does not exist...but on Windows the lack is OK because w23util.c
# includes a substitute gethostbyname.
# Noteworthy also is the fact that gethostbyname is deprecated and replaced
# by getnameinfo.
if( NOT WIN32 )
set( CMAKE_REQUIRED_LIBRARIES ${link_libnsl} )
herc_Check_Function_Exists( gethostbyname OK )
if( NOT HAVE_GETHOSTBYNAME )
unset( HAVE_GETHOSTBYNAME CACHE )
set( CMAKE_REQUIRED_LIBRARIES "${name_libnsl}" )
herc_Check_Function_Exists( gethostbyname FAIL )
if( HAVE_GETHOSTBYNAME )
set( link_libnsl "${name_libnsl}" CACHE INTERNAL "" FORCE )
endif( )
endif( NOT HAVE_GETHOSTBYNAME )
set( CMAKE_REQUIRED_LIBRARIES "" )
endif( NOT WIN32 )
# The following tests for memory allocation functions needs to be reviewed
# along with the hmalloc.h file in Hercules. The current configure.ac
# code sets the variables but never establishes any of them as "must-have."
# So we shall do the same for the moment. Given that valloc has been
# deprecated for eons of computer years and pvalloc is a GNU extension,
# this is worth persuing. It would be interesting to see what would happen
# if none of the functions were defined.
herc_Check_Function_Exists( mlock OK )
herc_Check_Function_Exists( mlockall OK )
herc_Check_Function_Exists( pvalloc OK )
herc_Check_Function_Exists( valloc OK )
herc_Check_Function_Exists( posix_memalign OK )
# The following function is only needed on Windows
if( WIN32 )
herc_Check_Function_Exists( InitializeCriticalSectionAndSpinCount FAIL )
endif ( WIN32 )
# Prior to version 2.17 of glibc, clock_gettime() was included in the rt
# library. See https://sourceware.org/ml/libc-announce/2012/msg00001.html
# for the December 2012 announcement of glibc 2.17; the second to the
# last bullet documents the move. So if glibc is older than 2.17, we
# need to include rt. Note that rather than testing version numbers,
# we will just test for clock_gettime(), first without rt, then with.
# (The legacy build configure.ac always included rt if it existed on the
# target system.)
set( CMAKE_REQUIRED_LIBRARIES ${link_librt} )
herc_Check_Function_Exists( clock_gettime OK )
if( NOT HAVE_CLOCK_GETTIME )
unset( HAVE_CLOCK_GETTIME CACHE )
set( CMAKE_REQUIRED_LIBRARIES "${name_librt}" )
herc_Check_Function_Exists( clock_gettime FAIL)
if( HAVE_CLOCK_GETTIME )
set( link_librt ${name_librt} CACHE INTERNAL "include POSIX real time extensions" )
endif( HAVE_CLOCK_GETTIME )
endif( NOT HAVE_CLOCK_GETTIME )
set( CMAKE_REQUIRED_LIBRARIES "" )
# The function sched_yield is required; its absence will fail the build.
# If not part of the basic c runtime, it can be found in librt, the
# POSIX Real-time Extensions library (Solaris, SunOS). And if librt
# contains sched_yield, it may also contain fdatasync. If the fdatasync
# function is missing, Hercules will use fsync instead.
set( CMAKE_REQUIRED_LIBRARIES ${link_librt} )
herc_Check_Function_Exists( sched_yield OK )
herc_Check_Function_Exists( fdatasync OK )
if( NOT HAVE_SCHED_YIELD )
unset( HAVE_SCHED_YIELD CACHE )
set( CMAKE_REQUIRED_LIBRARIES "${name_librt}" )
herc_Check_Function_Exists( sched_yield FAIL)
if( HAVE_SCHED_YIELD )
set( link_librt ${name_librt} CACHE INTERNAL "include POSIX real time extensions" )
if( NOT HAVE_FDATASYNC )
unset( HAVE_FDATASYNC CACHE )
herc_Check_Function_Exists( fdatasync OK )
endif( NOT HAVE_FDATASYNC )
endif( HAVE_SCHED_YIELD )
endif( NOT HAVE_SCHED_YIELD )
set( CMAKE_REQUIRED_LIBRARIES "" )
# For OS X 10.6 autoconf defines HAVE_FDATASYNC even though there is
# no function prototype declared for fdatasync() and unistd.h contains
# define _POSIX_SYNCHRONIZED_IO (-1) which indicates that fdatasync is
# not supported. So to decide whether fdatasync really can be used, we
# create a new symbol HAVE_FDATASYNC_SUPPORTED which is defined only if
# HAVE_FDATASYNC is defined and _POSIX_SYNCHRONIZED_IO is not negative.
# A better test for the above is to just use check_prototype_definition.
# And this could be an error in autoconf, not a problem with OS X 10.6
# header files. Lacking an OS X 10.6 system, there is no way to tell.
if( HAVE_FDATASYNC )
check_prototype_definition(fdatasync
"int fdatasync( int fd )"
"NULL"
unistd.h
WORKING_FDATASYNC )
if( NOT WORKING_FDATASYNC )
unset( HAVE_FDATASYNC CACHE )
endif( )
endif( )
# The functions pow() and floor() are either in the basic c runtime library
# or in the libm library. If a cached result used the math library, be sure
# it is included on the retest.
set( CMAKE_REQUIRED_LIBRARIES ${link_libm} )
herc_Check_Function_Exists( pow OK )
if( NOT HAVE_POW )
unset( HAVE_POW CACHE )
set( CMAKE_REQUIRED_LIBRARIES "${name_libm}" )
herc_Check_Function_Exists( pow FAIL)
if( HAVE_POW )
set( link_libm "${name_libm}" CACHE INTERNAL "include math library" )
herc_Check_Function_Exists( floor FAIL)
herc_Check_Function_Exists( ldexp FAIL )
endif( )
endif( NOT HAVE_POW )
set( CMAKE_REQUIRED_LIBRARIES "" )
# If none of the following five functions are defined, then the build needs
# NO_SETUID defined. If the first two functions (setresuid, getresuid) are
# are avaiable, that's enough. If those two are missing, then the next
# three (setreuid, geteuid, getuid) are needed. And if they are missing,
# Setuid suppport is disabled in Hercules, but the build continues.
# (* so this should really be in CMakeHercCheckOptional.cmake )
herc_Check_Function_Exists( setresuid OK )
herc_Check_Function_Exists( getresuid OK )
if( NOT (HAVE_SETRESUID AND HAVE_GETRESUID) )
herc_Check_Function_Exists( setreuid OK )
herc_Check_Function_Exists( geteuid OK )
herc_Check_Function_Exists( getuid OK )
if( NOT (HAVE_SETREUID AND HAVE_GETEUID AND HAVE_GETUID) )
set( NO_SETUID 1 )
endif( )
endif( )
# In Linux and BSD, connect() is defined in libc and no additional link
# libraries are needed. In Solaris, the socket library is needed.
set( CMAKE_REQUIRED_LIBRARIES ${link_libsocket} )
herc_Check_Function_Exists( connect OK )
if( NOT HAVE_CONNECT )
unset( HAVE_CONNECT CACHE )
set( CMAKE_REQUIRED_LIBRARIES "${name_libsocket}" )
herc_Check_Function_Exists( connect FAIL )
if( HAVE_CONNECT )
set( link_libsocket "${name_libsocket}" CACHE INTERNAL "include socket library" )
endif( )
endif( NOT HAVE_CONNECT )
set( CMAKE_REQUIRED_LIBRARIES "" )
# In Linux and BSD, socketpair() is defined in libc and no additional
# link libraries are needed. In Solaris, the socket library is needed.
set( CMAKE_REQUIRED_LIBRARIES ${link_libsocket} )
herc_Check_Function_Exists( socketpair OK )
if( NOT HAVE_SOCKETPAIR )
unset( HAVE_SOCKETPAIR CACHE )
set( CMAKE_REQUIRED_LIBRARIES "${name_libsocket}" )
herc_Check_Function_Exists( socketpair FAIL )
if( HAVE_CONNECT )
set( link_libsocket "${name_libsocket}" CACHE INTERNAL "include socket library" )
endif( )
endif( NOT HAVE_SOCKETPAIR )
set( CMAKE_REQUIRED_LIBRARIES "" )
# See if optreset is required to use getopt. Optreset is normally
# needed for BSD systems and not for Linux systems. If required, optreset
# is declared extern int in unistd.h.
herc_Check_Symbol_Exists( optreset unistd.h OK )
if( HAVE_DECL_OPTRESET )
set( NEED_GETOPT_OPTRESET 1)
endif( )
# Any of the following four types, if not defined, are typedef'd in htypes.h
# to unsigned versions of the underlying type. They can be found on BSD
# systems in sys/types.h and on Windows systems in winsock.h. So we need
# to see if they exist so that htypes.h does not try to define them if
# they do exist. They appear to be synonyms for uint8_t etc in C99, so
# that might be a better long-term solution to this.
set( CMAKE_EXTRA_INCLUDE_FILES "sys/types.h" )
check_type_size( u_char U_CHAR )
check_type_size( u_short U_SHORT )
check_type_size( u_int U_INT )
check_type_size( u_long U_LONG )
unset( CMAKE_EXTRA_INCLUDE_FILES )
# The following test is used as a telltale for systems that use u_intn_t
# instead of uintn_t. The Hercules header htypes.h will define integer
# based on the above four tests and the next test. Note that in
# configure.ac, if the following type exists, then u_int is presumed to
# exist as well. I suspect this is an error in configure.ac.
check_type_size( u_int8_t U_INT8_T )
message( "Checking for optional headers and libraries." )
herc_Check_Include_Files( assert.h OK )
# The following functions exist in some distributions and not in others.
# If the target system does not have them, Hercules includes its own
# copy of the functions.
herc_Check_Function_Exists( memrchr OK ) # found in Linux
herc_Check_Function_Exists( strlcpy OK ) # found in BSD
herc_Check_Function_Exists( strlcat OK ) # found in BSD
# If we have the header byteswap.h, then we will use it. If not,
# hbyteswp.h will be included instead. And if we are able to determine
# that the target is 32-bit or 64-bit Intel, we will use asm to perform
# two-byte and four-byte swaps (on MSVC this is done using intrinsics;
# see hbyteswp.h for details.
# Unfortunately, CMake does not provide and easy-to-use primitive for
# determining the target platform. So for the moment, if byteswap.h
# is not provided by the host system, we shall disable assembler byte
# swapping in hbyteswp.h.
herc_Check_Include_Files( byteswap.h OK )
if( NOT HAVE_BYTESWAP_H )
string( TOUPPER "${CMAKE_SYSTEM_PROCESSOR}" uland_proc )
if( NOT ( "${uland_proc}" IN_LIST herc_Intel ) )
set( NO_ASM_BYTESWAP 1 )
endif( )
unset( uland_proc )
endif( )
# Header malloc.h has been deprecated, and its content moved to stdlib.h.
# However, some Linux systems in their infinite wisdom (sorry for being
# snarky) retain the header and use it to define extensions to the scope
# of memory management functions. Other distros, notably FreeBSD,
# include an #error directive telling you to include stdlib.h instead.
# I guess that moves from deprecated to being spit upon. So...The BSD
# approach causes the test to fail, which is fine. If a Linux system
# has malloc.h, then we will include it in Hercules, but I will bet that
# Hercules does not use the Linux extensions.
herc_Check_Include_Files( malloc.h OK )
# termios.h, scandir, and alphasort, if avaiable, enable UNIX shell tab
# key handling. If any are missing, no tab key handling. Old versions
# of Solaris (pre 2.9, SunOS 5.9) lack these routines. Header presence
# generates code in hconsole.c to put the console in character-by-
# character mode, and function presence generates code in fillfnam.c to
# scan directories when the tab key is pressed. Termios.h also enables
# one-character command shortcuts on the CUI panel (after Esc).
# And while we are at it, we test the scandir prototype to see if the
# directory entry arrays passed to the filter and comparison functions
# are passed as const.
# Currently, hostopts.h assumes that only Windows includes const in the
# scandir function prototype. However, FreeBSD 11 and Debian 8.6 also
# include const. (I suspect all modern BSD and Linux systems include
# const in the prototype.)
# Code changes are needed in Hercules to replace the currentt target
# OS-based test, so that shall happen in V3.
herc_Check_Include_Files( termios.h OK )
herc_Check_Function_Exists( scandir OK )
herc_Check_Function_Exists( alphasort OK )
check_prototype_definition( scandir
"int scandir(const char *dirp,
struct dirent ***namelist,
int (*filter)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **));"
"NULL"
"dirent.h"
CONST_IN_SCANDIR_PROTOTYPE )
# Headers and declarations for real tape devices. On some systems (BSD?)
# sys/param.h must be included before sys/mount.h. Header sys/mtio.h and
# MTEWARN are used only for SCSI tape utility routines (scsiutil.c)
herc_Check_Include_Files( sys/param.h OK )
if( HAVE_SYS_PARAM_H )
set( CMAKE_EXTRA_INCLUDE_FILES sys/param.h )
endif( )
herc_Check_Include_Files( sys/mount.h OK )
unset( CMAKE_EXTRA_INCLUDE_FILES )
herc_Check_Include_Files( sys/mtio.h OK )
herc_Check_Symbol_Exists( MTEWARN sys/mtio.h OK)
# Headers for shared device server routines (shared.c)
herc_Check_Include_Files( sys/un.h OK )
# See if Open Object Rexx is installed. Open Object Rexx will be
# included in the Hercules build if avaiable and not excluded by user
# option. Hercules does not require Open Object Rexx to build correctly.
# The HAVE_ varibles created by these tests are not used by the build and
# need not be included in config.h
# The configure.ac script tested for both public headers, so we shall too.
herc_Check_Include_Files( oorexxapi.h OK )
herc_Check_Include_Files( rexx.h OK )
# See if Regina Rexx is installed. Apparently the header rexxsaa.h
# has the potential to be installed in a "normal" directory or in a
# regina subdirectory; one presumes the latter location simplifies
# concurrent installation of Open Object Rexx and Regina Rexx. Regina
# Rexx will be included in the Hercules build if avaiable and not
# excluded by user option. Hercules does not require Regina Rexx
# to build correctly.
herc_Check_Include_Files( regina/rexxsaa.h OK )
if( NOT HAVE_REGINA_REXXSAA_H )
herc_Check_Include_Files( rexxsaa.h OK )
endif( )
# Check for regular expression support as indicated by regex.h.
# Hercules does not require regular expression support to build.
# If regular expression support is present, the Automatic Operator
# functions will be included.
herc_Check_Include_Files( regex.h OK )
# See if sys/capability.h and the corresponding library cap exist.
# If they do, then Hercules can be built with support for fine-grained
# capabilities. Header prctl.h enables some additional control
# over capabilities and is a libc-based wrapper for the system call of
# the same name. Both Capabilities and prctl are Linux-only
# implementations of POSIX 1003.1e.
# Hercules code only checks for the headers; the functions and libraries
# are assumed to exist. And if the library does not exist, we assume
# that there is no point to including the headers either, so we unset
# the HAVE_SYS_CAPABILITY_H variable too. This makes sense for FreeBSD
# where the header exists but does something different from the Linux
# version.
herc_Check_Include_Files( sys/capability.h OK )
if( HAVE_SYS_CAPABILITY_H )
check_library_exists( cap cap_set_proc "" HAVE_CAP )
if( HAVE_CAP )
set( link_libcap ${name_libcap} CACHE INTERNAL "include POSIX 1003.1e capabilities" )
herc_Check_Include_Files( sys/prctl.h OK )
else( )
unset( HAVE_SYS_CAPABILITY_H )
endif( )
endif( )
# Miscelaneous probes of the target userland
herc_Check_Symbol_Exists( LOGIN_NAME_MAX "unistd.h" OK )
herc_Check_Symbol_Exists( _SC_NPROCESSORS_CONF "unistd.h" OK )
herc_Check_Symbol_Exists( _SC_NPROCESSORS_ONLN "unistd.h" OK )
return ( )