Browse Source

ccmake: Check for curses more robustly before enabling

Compute a default for `BUILD_CursesDialog` by building a small test
project that uses curses.  Disable `ccmake` by default if it fails,
and do not search for Curses as part of the main build.  This avoids
creating FindCurses cache entries when we are not considering ccmake.

If `BUILD_CursesDialog` is enabled (e.g. by the user) then warn if
curses cannot be found.
Brad King 7 years ago
parent
commit
99bf77f49c
4 changed files with 95 additions and 12 deletions
  1. 14 12
      CMakeLists.txt
  2. 41 0
      Source/Checks/Curses.cmake
  3. 25 0
      Source/Checks/Curses/CMakeLists.txt
  4. 15 0
      Source/Checks/Curses/CheckCurses.c

+ 14 - 12
CMakeLists.txt

@@ -573,22 +573,24 @@ macro (CMAKE_BUILD_UTILITIES)
   #---------------------------------------------------------------------
   # Use curses?
   if (UNIX)
-    # there is a bug in the Syllable libraries which makes linking ccmake fail, Alex
-    if(NOT CMAKE_SYSTEM_NAME MATCHES syllable)
-      set(CURSES_NEED_NCURSES TRUE)
-      find_package(Curses QUIET)
-      if (CURSES_LIBRARY)
-        option(BUILD_CursesDialog "Build the CMake Curses Dialog ccmake" ON)
-      else ()
-        message("Curses libraries were not found. Curses GUI for CMake will not be built.")
-        set(BUILD_CursesDialog 0)
-      endif ()
-    else()
-      set(BUILD_CursesDialog 0)
+    if(NOT DEFINED BUILD_CursesDialog)
+      include(${CMake_SOURCE_DIR}/Source/Checks/Curses.cmake)
+      option(BUILD_CursesDialog "Build the CMake Curses Dialog ccmake" "${CMakeCheckCurses_COMPILED}")
     endif()
   else ()
     set(BUILD_CursesDialog 0)
   endif ()
+  if(BUILD_CursesDialog)
+    set(CURSES_NEED_NCURSES TRUE)
+    find_package(Curses)
+    if(NOT CURSES_FOUND)
+      message(WARNING
+        "'ccmake' will not be built because Curses was not found.\n"
+        "Turn off BUILD_CursesDialog to suppress this message."
+        )
+      set(BUILD_CursesDialog 0)
+    endif()
+  endif()
   if(BUILD_CursesDialog)
     if(NOT CMAKE_USE_SYSTEM_FORM)
       add_subdirectory(Source/CursesDialog/form)

+ 41 - 0
Source/Checks/Curses.cmake

@@ -0,0 +1,41 @@
+message(STATUS "Checking for curses support")
+
+# Try compiling a simple project using curses.
+# Pass in any cache entries that the user may have set.
+set(CMakeCheckCurses_ARGS "")
+foreach(v
+    CURSES_INCLUDE_PATH
+    CURSES_CURSES_LIBRARY
+    CURSES_NCURSES_LIBRARY
+    CURSES_EXTRA_LIBRARY
+    CURSES_FORM_LIBRARY
+    )
+  if(${v})
+    list(APPEND CMakeCheckCurses_ARGS -D${v}=${${v}})
+  endif()
+endforeach()
+file(REMOVE_RECURSE "${CMake_BINARY_DIR}/Source/Checks/Curses-build")
+try_compile(CMakeCheckCurses_COMPILED
+  ${CMake_BINARY_DIR}/Source/Checks/Curses-build
+  ${CMake_SOURCE_DIR}/Source/Checks/Curses
+  CheckCurses # project name
+  CheckCurses # target name
+  CMAKE_FLAGS
+    "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}"
+    ${CMakeCheckCurses_ARGS}
+  OUTPUT_VARIABLE CMakeCheckCurses_OUTPUT
+  )
+
+# Covnert result from cache entry to normal variable.
+set(CMakeCheckCurses_COMPILED "${CMakeCheckCurses_COMPILED}")
+unset(CMakeCheckCurses_COMPILED CACHE)
+
+if(CMakeCheckCurses_COMPILED)
+  message(STATUS "Checking for curses support - Success")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+    "Checking for curses support passed with the following output:\n${CMakeCheckCurses_OUTPUT}\n\n")
+else()
+  message(STATUS "Checking for curses support - Failed")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+    "Checking for curses support failed with the following output:\n${CMakeCheckCurses_OUTPUT}\n\n")
+endif()

+ 25 - 0
Source/Checks/Curses/CMakeLists.txt

@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.1)
+if(POLICY CMP0060)
+  cmake_policy(SET CMP0060 NEW)
+endif()
+project(CheckCurses C)
+
+set(CURSES_NEED_NCURSES TRUE)
+find_package(Curses)
+if(NOT CURSES_FOUND)
+  return()
+endif()
+include_directories(${CURSES_INCLUDE_DIRS})
+add_executable(CheckCurses CheckCurses.c)
+target_link_libraries(CheckCurses ${CURSES_LIBRARIES})
+
+foreach(h
+    CURSES_HAVE_CURSES_H
+    CURSES_HAVE_NCURSES_H
+    CURSES_HAVE_NCURSES_NCURSES_H
+    CURSES_HAVE_NCURSES_CURSES_H
+    )
+  if(${h})
+    target_compile_definitions(CheckCurses PRIVATE ${h})
+  endif()
+endforeach()

+ 15 - 0
Source/Checks/Curses/CheckCurses.c

@@ -0,0 +1,15 @@
+#if defined(CURSES_HAVE_NCURSES_H)
+#include <ncurses.h>
+#elif defined(CURSES_HAVE_NCURSES_NCURSES_H)
+#include <ncurses/ncurses.h>
+#elif defined(CURSES_HAVE_NCURSES_CURSES_H)
+#include <ncurses/curses.h>
+#else
+#include <curses.h>
+#endif
+
+int main()
+{
+  curses_version();
+  return 0;
+}