xref: /freebsd/contrib/nvi/CMakeLists.txt (revision aa1a8ff2d6dbc51ef058f46f3db5a8bb77967145)
1cmake_minimum_required(VERSION 3.9)
2
3get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
4if(is_multi_config)
5    set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING
6        "Semicolon separated list of supported configuration types")
7    mark_as_advanced(CMAKE_CONFIGURATION_TYPES)
8elseif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS)
9    message(WARNING "No CMAKE_BUILD_TYPE is selected")
10endif()
11
12project(nvi2 C)
13
14include(CheckIncludeFiles)
15include(CheckFunctionExists)
16include(CheckSymbolExists)
17include(CheckStructHasMember)
18include(CheckCSourceCompiles)
19include(CheckCCompilerFlag)
20
21mark_as_advanced(CMAKE_INSTALL_PREFIX)
22
23option(USE_WIDECHAR "Enable wide character support" ON)
24option(USE_ICONV "Enable iconv support" ON)
25
26check_c_compiler_flag(-fcolor-diagnostics USE_FCOLOR_DIAGNOSTICS)
27if(USE_FCOLOR_DIAGNOSTICS)
28    add_compile_options(-fcolor-diagnostics)
29endif()
30
31add_compile_options($<$<CONFIG:Debug>:-Wall>)
32add_compile_options($<$<CONFIG:Debug>:-Wno-parentheses>)
33add_compile_options($<$<CONFIG:Debug>:-Wno-uninitialized>)
34add_compile_options($<$<CONFIG:Debug>:-Wmissing-prototypes>)
35if (NOT APPLE)
36    add_compile_options($<$<CONFIG:Debug>:-Wsystem-headers>)
37endif()
38add_compile_options($<$<CONFIG:Release>:-Wuninitialized>)
39add_compile_options($<$<CONFIG:Release>:-Wno-dangling-else>)
40add_compile_options(-Wno-string-compare)
41add_compile_options(-Wstack-protector -fstack-protector)
42add_compile_options(-Wstrict-aliasing -fstrict-aliasing)
43
44include_directories(${CMAKE_CURRENT_BINARY_DIR})
45
46set(MAIN_PROTOS
47    cl/extern.h common/extern.h ex/extern.h vi/extern.h
48    common/options_def.h ex/ex_def.h ex/version.h)
49
50set(CL_SRCS
51    cl/cl_funcs.c cl/cl_main.c cl/cl_read.c cl/cl_screen.c cl/cl_term.c)
52
53set(COMMON_SRCS
54    common/conv.c common/cut.c common/delete.c common/encoding.c common/exf.c
55    common/key.c common/line.c common/log.c common/main.c common/mark.c
56    common/msg.c common/options.c common/options_f.c common/put.c
57    common/recover.c common/screen.c common/search.c common/seq.c
58    common/util.c)
59
60set(EX_SRCS
61    ex/ex.c ex/ex_abbrev.c ex/ex_append.c ex/ex_args.c ex/ex_argv.c ex/ex_at.c
62    ex/ex_bang.c ex/ex_cd.c ex/ex_cmd.c ex/ex_cscope.c ex/ex_delete.c
63    ex/ex_display.c ex/ex_edit.c ex/ex_equal.c ex/ex_file.c ex/ex_filter.c
64    ex/ex_global.c ex/ex_init.c ex/ex_join.c ex/ex_map.c ex/ex_mark.c
65    ex/ex_mkexrc.c ex/ex_move.c ex/ex_open.c ex/ex_preserve.c ex/ex_print.c
66    ex/ex_put.c ex/ex_quit.c ex/ex_read.c ex/ex_screen.c ex/ex_script.c
67    ex/ex_set.c ex/ex_shell.c ex/ex_shift.c ex/ex_source.c ex/ex_stop.c
68    ex/ex_subst.c ex/ex_tag.c ex/ex_txt.c ex/ex_undo.c ex/ex_usage.c
69    ex/ex_util.c ex/ex_version.c ex/ex_visual.c ex/ex_write.c ex/ex_yank.c
70    ex/ex_z.c)
71
72set(VI_SRCS
73    vi/getc.c vi/v_at.c vi/v_ch.c vi/v_cmd.c vi/v_delete.c vi/v_ex.c
74    vi/v_increment.c vi/v_init.c vi/v_itxt.c vi/v_left.c vi/v_mark.c
75    vi/v_match.c vi/v_paragraph.c vi/v_put.c vi/v_redraw.c vi/v_replace.c
76    vi/v_right.c vi/v_screen.c vi/v_scroll.c vi/v_search.c vi/v_section.c
77    vi/v_sentence.c vi/v_status.c vi/v_txt.c vi/v_ulcase.c vi/v_undo.c
78    vi/v_util.c vi/v_word.c vi/v_xchar.c vi/v_yank.c vi/v_z.c vi/v_zexit.c
79    vi/vi.c vi/vs_line.c vi/vs_msg.c vi/vs_refresh.c vi/vs_relative.c
80    vi/vs_smap.c vi/vs_split.c)
81
82set(REGEX_SRCS
83    regex/regcomp.c regex/regerror.c regex/regexec.c regex/regfree.c)
84
85# commands to generate the public headers
86set(extract_protos sed -n 's/^ \\* PUBLIC: \\\(.*\\\)/\\1/p')
87set(extract_version sed -n
88    's/^.*version \\\([^\)]*\)\\\).*/\#define VI_VERSION \\\"\\1\\\"/p')
89
90add_custom_command(OUTPUT cl/extern.h
91                   COMMAND ${extract_protos} ${CL_SRCS} > cl/extern.h
92                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
93                   DEPENDS ${CL_SRCS})
94add_custom_command(OUTPUT common/extern.h
95                   COMMAND ${extract_protos} ${COMMON_SRCS} > common/extern.h
96                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
97                   DEPENDS ${COMMON_SRCS})
98add_custom_command(OUTPUT ex/extern.h
99                   COMMAND ${extract_protos} ${EX_SRCS} > ex/extern.h
100                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
101                   DEPENDS ${EX_SRCS})
102add_custom_command(OUTPUT vi/extern.h
103                   COMMAND ${extract_protos} ${VI_SRCS} > vi/extern.h
104                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
105                   DEPENDS ${VI_SRCS})
106add_custom_command(OUTPUT common/options_def.h
107                   COMMAND awk -f common/options.awk
108                           common/options.c > common/options_def.h
109                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
110                   DEPENDS common/options.c)
111add_custom_command(OUTPUT ex/ex_def.h
112                   COMMAND awk -f ex/ex.awk ex/ex_cmd.c > ex/ex_def.h
113                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
114                   DEPENDS ex/ex_cmd.c)
115add_custom_command(OUTPUT ex/version.h
116                   COMMAND ${extract_version} README > ex/version.h
117                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
118                   DEPENDS README)
119
120add_executable(nvi)
121target_sources(nvi PRIVATE ${MAIN_PROTOS} ${CL_SRCS} ${COMMON_SRCS}
122                           ${EX_SRCS} ${VI_SRCS})
123target_compile_definitions(nvi PRIVATE $<$<CONFIG:Debug>:DEBUG>
124                                       $<$<CONFIG:Debug>:COMLOG>)
125
126check_function_exists(openpty UTIL_IN_LIBC)
127if(NOT UTIL_IN_LIBC)
128    find_library(UTIL_LIBRARY util)
129    target_link_libraries(nvi PRIVATE ${UTIL_LIBRARY})
130endif()
131
132check_function_exists(__b64_ntop RESOLV_IN_LIBC)
133if(NOT RESOLV_IN_LIBC)
134    find_library(RESOLV_LIBRARY resolv)
135    target_link_libraries(nvi PRIVATE ${RESOLV_LIBRARY})
136endif()
137
138check_symbol_exists(asprintf "stdio.h" ASPRINTF_IN_STDIO_H)
139if(NOT ASPRINTF_IN_STDIO_H)
140    target_compile_definitions(nvi PRIVATE _GNU_SOURCE)
141endif()
142
143if(USE_WIDECHAR)
144    find_library(CURSES_LIBRARY NAMES ncursesw cursesw curses HINTS /usr/lib)
145    find_library(TERMINFO_LIBRARY NAMES tinfow terminfo HINTS /usr/lib)
146
147    # link to the wchar_t awared BSD libregex.a
148    add_library(regex STATIC)
149    target_sources(regex PRIVATE ${REGEX_SRCS})
150    target_include_directories(regex PUBLIC regex)
151    target_compile_definitions(regex PUBLIC __REGEX_PRIVATE)
152    # The macro _XOPEN_SOURCE_EXTENDED is needed to get the waddnwstr()
153    # definition on at least FreeBSD and recent macOS.
154    target_compile_definitions(nvi PRIVATE _XOPEN_SOURCE_EXTENDED)
155    target_link_libraries(nvi PRIVATE regex)
156else()
157    find_library(CURSES_LIBRARY NAMES ncurses curses HINTS /usr/lib)
158    find_library(TERMINFO_LIBRARY NAMES tinfo terminfo HINTS /usr/lib)
159    target_compile_options(nvi PRIVATE -Wno-pointer-sign)
160endif()
161
162target_link_libraries(nvi PRIVATE ${CURSES_LIBRARY})
163if(TERMINFO_LIBRARY)
164    target_link_libraries(nvi PRIVATE ${TERMINFO_LIBRARY})
165endif()
166
167if(USE_ICONV)
168    check_function_exists(iconv ICONV_IN_LIBC)
169    if(NOT ICONV_IN_LIBC)
170        find_path(ICONV_INCLUDE_DIR iconv.h)
171        find_library(ICONV_LIBRARY iconv)
172    endif()
173
174    # detect the prototype of iconv(3)
175    set(CMAKE_C_FLAGS_BACKUP "${CMAKE_C_FLAGS}")
176    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
177    set(CMAKE_REQUIRED_INCLUDES "${ICONV_INCLUDE_DIR}")
178    set(CMAKE_REQUIRED_LIBRARIES "${ICONV_LIBRARY}")
179    check_c_source_compiles("
180    #include <iconv.h>
181    int main() {
182        iconv_t conv = 0;
183        char* in = 0;
184        size_t ilen = 0;
185        char* out = 0;
186        size_t olen = 0;
187        iconv(conv, &in, &ilen, &out, &olen);
188        return 0;
189    }
190    " ICONV_TRADITIONAL)
191    set(CMAKE_REQUIRED_INCLUDES)
192    set(CMAKE_REQUIRED_LIBRARIES)
193    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_BACKUP}")
194
195    target_include_directories(nvi PRIVATE ${ICONV_INCLUDE_DIR})
196    target_link_libraries(nvi PRIVATE ${ICONV_LIBRARY})
197endif()
198
199check_function_exists(getprogname GETPROGNAME_IN_LIBC)
200check_function_exists(strlcpy STRLCPY_IN_LIBC)
201if(NOT GETPROGNAME_IN_LIBC OR NOT STRLCPY_IN_LIBC)
202    find_package(PkgConfig REQUIRED)
203    pkg_check_modules(LIBBSD libbsd-overlay)
204    add_definitions(${LIBBSD_CFLAGS})
205    target_link_libraries(nvi PRIVATE ${LIBBSD_LIBRARIES})
206endif()
207
208check_function_exists(dbopen DBOPEN_IN_LIBC)
209if(NOT DBOPEN_IN_LIBC)
210    target_link_libraries(nvi PRIVATE db1)
211endif()
212if (APPLE)
213    # Avoid using an incompatible db.h installed to /usr/local (since this is
214    # part of the default search path on macOS)
215    set(DB_H_GUESS "${CMAKE_OSX_SYSROOT}/usr/include/db.h")
216    if (NOT EXISTS ${DB_H_GUESS})
217        message(FATAL_ERROR "Could not find db.h at the expected path (${DB_H_GUESS}).")
218    endif()
219    add_definitions("-DDB_H_ABS_PATH=<${DB_H_GUESS}>")
220else()
221    find_path(DB_INCLUDE_DIR db.h PATH_SUFFIXES db1)
222    target_include_directories(nvi PRIVATE ${DB_INCLUDE_DIR})
223endif()
224
225check_include_files(libutil.h HAVE_LIBUTIL_H)
226check_include_files(ncurses.h HAVE_NCURSES_H)
227check_include_files(ncursesw/ncurses.h HAVE_NCURSESW_NCURSES_H)
228check_include_files(pty.h HAVE_PTY_H)
229check_include_files(term.h HAVE_TERM_H)
230check_struct_has_member("struct dirent" d_namlen dirent.h HAVE_DIRENT_D_NAMLEN LANGUAGE C)
231check_struct_has_member("struct stat" st_mtimespec
232    "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC LANGUAGE C)
233check_struct_has_member("struct stat" st_mtim
234    "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM LANGUAGE C)
235
236configure_file(files/config.h.in config.h)
237
238set(vi_cv_path_preserve /var/tmp/vi.recover/)
239if(APPLE)
240    set(vi_cv_path_msgcat /usr/local/share/vi/catalog/)
241else()
242    set(vi_cv_path_msgcat /usr/share/vi/catalog/)
243endif()
244
245configure_file(files/pathnames.h.in pathnames.h)
246configure_file(files/recover.in recover @ONLY)
247