From 3c1b58565687351cfc00079a2df80035315939ea Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 23 Jul 2020 10:44:18 -0400 Subject: [PATCH] [enhancement] updated cmake checks (#581) * added header file checks * cmake cleanup and better use of checks * fixed bug in numerical_methods/CMake * add docs to cmake --- CMakeLists.txt | 26 +++++++++- client_server/CMakeLists.txt | 81 ++++++++++++++++---------------- numerical_methods/CMakeLists.txt | 10 ++-- sorting/CMakeLists.txt | 4 -- 4 files changed, 72 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index feaa34f7..6a70444e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ project(Algorithms_in_C DESCRIPTION "Set of algorithms implemented in C." ) +# Set compilation standards set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED YES) @@ -13,8 +14,12 @@ if(MSVC) # add_compile_options(/Za) endif(MSVC) +# check for math library +# addresses a bug when linking on OSX find_library(MATH_LIBRARY m) +# Optional flag - can be set by user +# Default "ON" option(USE_OPENMP "flag to use OpenMP for multithreading" ON) if(USE_OPENMP) find_package(OpenMP) @@ -25,6 +30,24 @@ if(USE_OPENMP) endif() endif() +## Check for some required header files +include(CheckIncludeFile) +include(CheckSymbolExists) +check_include_file(stdbool.h HAS_STDBOOL_H) +check_include_file(inttypes.h HAS_INTTYPES_H) +check_include_file(complex.h HAS_COMPLEX_H) +if(HAS_COMPLEX_H) + check_symbol_exists(complex complex.h HAS_COMPLEX_TYPE) +endif(HAS_COMPLEX_H) +if (NOT HAS_STDBOOL_H) + message(FATAL_ERROR "Missing required header: 'stdbool.h'") +endif() +if (NOT HAS_INTTYPES_H) + message(FATAL_ERROR "Missing required header: 'inttypes.h'") +endif() + +## Add subdirectories containing CMakeLists.txt +# to configure and compile files in the respective folders add_subdirectory(misc) add_subdirectory(sorting) add_subdirectory(graphics) @@ -35,6 +58,7 @@ add_subdirectory(project_euler) add_subdirectory(machine_learning) add_subdirectory(numerical_methods) +## Configure Doxygen documentation system cmake_policy(SET CMP0054 NEW) cmake_policy(SET CMP0057 NEW) find_package(Doxygen OPTIONAL_COMPONENTS dot dia) @@ -77,7 +101,7 @@ if(DOXYGEN_FOUND) ) endif() - +## Enable tool to generate binary distribution files set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) include(CPack) diff --git a/client_server/CMakeLists.txt b/client_server/CMakeLists.txt index 70d08ad8..66a6b043 100644 --- a/client_server/CMakeLists.txt +++ b/client_server/CMakeLists.txt @@ -1,45 +1,44 @@ -# include(CheckIncludeFile) -# check_include_file(arpa/inet.h ARPA_HEADERS) -# if(NOT ARPA_HEADERS) -# check_include_file(winsock2.h WINSOCK_HEADER) -# if(NOT WINSOCK_HEADER) -# message(FATAL_ERROR "socket headers not found in system.") -# endif() -# endif() +if(WIN32) + check_include_file(winsock2.h WINSOCK_HEADER) +else() + check_include_file(arpa/inet.h ARPA_HEADERS) +endif() -# check_include_file(unistd.h HAS_UNISTD) +if(ARPA_HEADERS OR WINSOCK_HEADER) + # If necessary, use the RELATIVE flag, otherwise each source file may be listed + # with full pathname. RELATIVE may makes it easier to extract an executable name + # automatically. + file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c ) + # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) + # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) + foreach( testsourcefile ${APP_SOURCES} ) + # I used a simple string replace, to cut off .cpp. + string( REPLACE ".c" "" testname ${testsourcefile} ) + add_executable( ${testname} ${testsourcefile} ) + + if(OpenMP_C_FOUND) + target_link_libraries(${testname} PRIVATE OpenMP::OpenMP_C) + endif() + if(MATH_LIBRARY) + target_link_libraries(${testname} PRIVATE ${MATH_LIBRARY}) + endif() + + # if(HAS_UNISTD) + # target_compile_definitions(${testname} PRIVATE HAS_UNISTD) + # endif() + # if(ARPA_HEADERS) + # target_compile_definitions(${testname} PRIVATE ARPA_HEADERS) + # else() + # target_compile_definitions(${testname} PRIVATE WINSOCK_HEADER) + # endif() -# If necessary, use the RELATIVE flag, otherwise each source file may be listed -# with full pathname. RELATIVE may makes it easier to extract an executable name -# automatically. -file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c ) -# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) -# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) -foreach( testsourcefile ${APP_SOURCES} ) - # I used a simple string replace, to cut off .cpp. - string( REPLACE ".c" "" testname ${testsourcefile} ) - add_executable( ${testname} ${testsourcefile} ) - - if(OpenMP_C_FOUND) - target_link_libraries(${testname} PRIVATE OpenMP::OpenMP_C) - endif() - if(MATH_LIBRARY) - target_link_libraries(${testname} PRIVATE ${MATH_LIBRARY}) - endif() - - if(HAS_UNISTD) - target_compile_definitions(${testname} PRIVATE HAS_UNISTD) - endif() - # if(ARPA_HEADERS) - # target_compile_definitions(${testname} PRIVATE ARPA_HEADERS) - # else() - # target_compile_definitions(${testname} PRIVATE WINSOCK_HEADER) - # endif() + if(WINSOCK_HEADER) + target_link_libraries(${testname} PRIVATE ws2_32) # link winsock library on windows + endif() - if(WIN32) - target_link_libraries(${testname} PRIVATE ws2_32) # link winsock library on windows - endif() + install(TARGETS ${testname} DESTINATION "bin/client_server") - install(TARGETS ${testname} DESTINATION "bin/client_server") - -endforeach( testsourcefile ${APP_SOURCES} ) + endforeach( testsourcefile ${APP_SOURCES} ) +else() + message(WARNING "socket headers not found in system.") +endif(ARPA_HEADERS OR WINSOCK_HEADER) diff --git a/numerical_methods/CMakeLists.txt b/numerical_methods/CMakeLists.txt index 4bc4f7af..5bfaafd1 100644 --- a/numerical_methods/CMakeLists.txt +++ b/numerical_methods/CMakeLists.txt @@ -5,11 +5,15 @@ file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c ) # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) -set (no_msvc "newton_raphson_root.c" "durand_kerner_roots.c") +# List of files that use complex.h and complex data type +set (NEED_COMPLEX + "newton_raphson_root.c" + "durand_kerner_roots.c" +) foreach( testsourcefile ${APP_SOURCES} ) - # Do not compile these files that use complex.h on MSVC - if ( ${testsourcefile} IN_LIST no_msvc AND MSVC) + # compile files that use complex.h only if available + if ( ${testsourcefile} IN_LIST NEED_COMPLEX AND NOT HAS_COMPLEX_TYPE) continue() endif() string( REPLACE ".c" "" testname ${testsourcefile} ) diff --git a/sorting/CMakeLists.txt b/sorting/CMakeLists.txt index e3ff0d66..2c9e74ec 100644 --- a/sorting/CMakeLists.txt +++ b/sorting/CMakeLists.txt @@ -1,7 +1,3 @@ -if(USE_OPENMP) - find_package(OpenMP) -endif() - # If necessary, use the RELATIVE flag, otherwise each source file may be listed # with full pathname. RELATIVE may makes it easier to extract an executable name # automatically.