ndhc/CMakeLists.txt
Nicholas J. Kain b8bffa16c5 Build without -fno-strict-overflow.
I only built with this flag to mitigate accidental UB.  Now that
UBSan exists, there's no point as UBSan does better and actually
allows offending code to be located and fixed easily.
2020-11-25 04:44:26 -05:00

226 lines
7.4 KiB
CMake

cmake_minimum_required(VERSION 3.3)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
else()
cmake_policy(VERSION 3.12)
endif()
project (ndhc DESCRIPTION "dhcp4 client" LANGUAGES C)
####################################
# Computes the realtionship between two version strings. A version
# string is a number delineated by '.'s such as 1.3.2 and 0.99.9.1.
# You can feed version strings with different number of dot versions,
# and the shorter version number will be padded with zeros: 9.2 <
# 9.2.1 will actually compare 9.2.0 < 9.2.1.
#
# Input: a_in - value, not variable
# b_in - value, not variable
# result_out - variable with value:
# -1 : a_in < b_in
# 0 : a_in == b_in
# 1 : a_in > b_in
#
# Written by James Bigler.
MACRO(COMPARE_VERSION_STRINGS a_in b_in result_out)
# Since SEPARATE_ARGUMENTS using ' ' as the separation token,
# replace '.' with ' ' to allow easy tokenization of the string.
STRING(REPLACE "." " " a ${a_in})
STRING(REPLACE "." " " b ${b_in})
SEPARATE_ARGUMENTS(a)
SEPARATE_ARGUMENTS(b)
# Check the size of each list to see if they are equal.
LIST(LENGTH a a_length)
LIST(LENGTH b b_length)
# Pad the shorter list with zeros.
# Note that range needs to be one less than the length as the for
# loop is inclusive (silly CMake).
IF(a_length LESS b_length)
# a is shorter
SET(shorter a)
MATH(EXPR range "${b_length} - 1")
MATH(EXPR pad_range "${b_length} - ${a_length} - 1")
ELSE(a_length LESS b_length)
# b is shorter
SET(shorter b)
MATH(EXPR range "${a_length} - 1")
MATH(EXPR pad_range "${a_length} - ${b_length} - 1")
ENDIF(a_length LESS b_length)
# PAD out if we need to
IF(NOT pad_range LESS 0)
FOREACH(pad RANGE ${pad_range})
# Since shorter is an alias for b, we need to get to it by by dereferencing shorter.
LIST(APPEND ${shorter} 0)
ENDFOREACH(pad RANGE ${pad_range})
ENDIF(NOT pad_range LESS 0)
SET(result 0)
FOREACH(index RANGE ${range})
IF(result EQUAL 0)
# Only continue to compare things as long as they are equal
LIST(GET a ${index} a_version)
LIST(GET b ${index} b_version)
# LESS
IF(a_version LESS b_version)
SET(result -1)
ENDIF(a_version LESS b_version)
# GREATER
IF(a_version GREATER b_version)
SET(result 1)
ENDIF(a_version GREATER b_version)
ENDIF(result EQUAL 0)
ENDFOREACH(index)
# Copy out the return result
SET(${result_out} ${result})
ENDMACRO(COMPARE_VERSION_STRINGS)
####################################
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -pedantic -Wall -Wextra -Wimplicit-fallthrough=0 -Wformat=2 -Wformat-nonliteral -Wformat-security -Wshadow -Wpointer-arith -Wmissing-prototypes -Wunused-const-variable=0 -Wcast-qual -Wsign-conversion -D_GNU_SOURCE -DNK_USE_CAPABILITY -Wno-discarded-qualifiers")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -fno-rtti -pedantic -Wall -Wextra -Wimplicit-fallthrough=0 -Wformat-security -Wshadow -Wpointer-arith -Wmissing-prototypes -Wunused-const-variable=0 -Wcast-qual -Wsign-conversion -D_GNU_SOURCE -DNK_USE_CAPABILITY")
if (WIN32)
set(OSNAME "Win32")
else()
execute_process(
COMMAND uname
COMMAND tr "\n" " "
COMMAND sed "s/ //"
OUTPUT_VARIABLE OSNAME
)
endif()
if (NOT (${OSNAME} STREQUAL "Linux"))
message("ndhc requires Linux. Patches are welcome. Consult README.")
return()
endif()
if (${OSNAME} STREQUAL "Linux")
execute_process(
COMMAND uname -r
COMMAND tr "\n" " "
COMMAND sed "s/ //"
OUTPUT_VARIABLE LINUX_VERSION
)
COMPARE_VERSION_STRINGS(${LINUX_VERSION} "3.5" LINUX_HAS_NO_NEW_PRIVS)
if (NOT ${LINUX_HAS_NO_NEW_PRIVS} LESS 0)
message("ncmlib: Enabling use of prctl SET_NO_NEW_PRIVS.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNK_USE_NO_NEW_PRIVS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNK_USE_NO_NEW_PRIVS")
else()
message("ncmlib: prctl SET_NO_NEW_PRIVS not available.")
endif()
COMPARE_VERSION_STRINGS(${LINUX_VERSION} "3.17" LINUX_HAS_GETRANDOM_SYSCALL)
if (NOT ${LINUX_HAS_GETRANDOM_SYSCALL} LESS 0)
message("ncmlib: Enabling use of getrandom syscall.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNK_USE_GETRANDOM_SYSCALL")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNK_USE_GETRANDOM_SYSCALL")
else()
message("ncmlib: getrandom syscall not available.")
endif()
endif()
if (NOT CMAKE_CROSSCOMPILING)
set(GLIBC_DETECT_TEST_C
"
#include <stdio.h>
int main(int argc, char *argv[]) {
printf(\"%d.%d\", __GLIBC__, __GLIBC_MINOR__);
return 0;
}
")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/detect/glibc.c "${GLIBC_DETECT_TEST_C}\n")
try_run(GLIBC_DETECTION GLIBC_COMPILE
${CMAKE_CURRENT_BINARY_DIR}/detect ${CMAKE_CURRENT_BINARY_DIR}/detect/glibc.c
RUN_OUTPUT_VARIABLE GLIBC_VERSION)
if (GLIBC_VERSION AND GLIBC_COMPILE)
message("glibc version detected as ${GLIBC_VERSION}")
COMPARE_VERSION_STRINGS(${GLIBC_VERSION} "2.17" GLIBC_MUST_LINK_RT)
if (${GLIBC_MUST_LINK_RT} LESS 0)
message("glibc <2.17 detected; linking against librt.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lrt")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lrt")
endif()
else()
message("Could not detect glibc version.")
endif()
endif()
if ("$ENV{CROSSCOMPILE_MACHINENAME}" STREQUAL "")
execute_process(
COMMAND uname -m
COMMAND tr "\n" " "
COMMAND sed "s/ //"
OUTPUT_VARIABLE MACHINENAME
)
else()
message("skipped machine detection; MACHINENAME is '$ENV{CROSSCOMPILE_MACHINENAME}'")
set(MACHINENAME $ENV{CROSSCOMPILE_MACHINENAME})
endif()
add_executable(ndhc "")
find_program(RAGEL ragel)
set(RAGEL_PRINT_COMMENT "Compiling Ragel state machine: FILE")
file(GLOB_RECURSE RAGEL_FILES
"src/ifchd-parse.rl"
"src/cfg.rl"
)
foreach(RAGEL_FILE ${RAGEL_FILES})
string(REGEX REPLACE "^[^/]*[/]" "" RAGEL_FILE_BASE ${RAGEL_FILE})
string(REGEX REPLACE ${RAGEL_FILE_BASE} "" RAGEL_FILE_PATH ${RAGEL_FILE})
string(REGEX REPLACE "[.]rl$" ".c" RAGEL_FILE_C ${RAGEL_FILE_BASE})
string(REGEX REPLACE "FILE$" ${RAGEL_FILE_BASE} RAGEL_COMMENT ${RAGEL_PRINT_COMMENT})
set(RAGEL_FILE_C_OUT ${CMAKE_CURRENT_BINARY_DIR}/${RAGEL_FILE_C})
list(APPEND RAGEL_C_FILES ${RAGEL_FILE_C_OUT})
add_custom_command(
OUTPUT ${RAGEL_FILE_C_OUT}
COMMAND ${RAGEL} -T0 ${RAGEL_ERRFMT_ARG} -o ${RAGEL_FILE_C_OUT} ${RAGEL_FILE_BASE}
MAIN_DEPENDENCY ${RAGEL_FILE}
WORKING_DIRECTORY ${RAGEL_FILE_PATH}
COMMENT ${RAGEL_COMMENT}
VERBATIM
)
set_property(SOURCE ${RAGEL_FILE_C_OUT} APPEND PROPERTY GENERATED TRUE)
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set_property(SOURCE ${RAGEL_FILE_C_OUT} APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-unused-const-variable")
endif()
set_source_files_properties(${RAGEL_FILE_C_OUT} PROPERTIES GENERATED true)
target_sources(ndhc PRIVATE ${RAGEL_FILE_C_OUT})
endforeach(RAGEL_FILE)
add_custom_target(ndhc_ragel DEPENDS ${RAGEL_C_FILES})
add_dependencies(ndhc ndhc_ragel)
target_sources(ndhc PRIVATE
"src/lib/io.c"
"src/lib/hwrng.c"
"src/lib/random.c"
"src/lib/privs.c"
${RAGEL_C_FILES}
"src/arp.c"
"src/ifchd.c"
"src/netlink.c"
"src/sockd.c"
"src/dhcp.c"
"src/ifset.c"
"src/nl.c"
"src/state.c"
"src/duiaid.c"
"src/leasefile.c"
"src/options.c"
"src/sys.c"
"src/ifchange.c"
"src/ndhc.c"
"src/rfkill.c"
)
target_include_directories(ndhc PRIVATE
"${PROJECT_SOURCE_DIR}/src"
)