diff --git a/CMakeLists.txt b/CMakeLists.txt index 9660fae527..91b7a06a5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,12 +54,7 @@ if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") endif() option(ENABLE_LIBINTL "enable libintl" ON) -if(MSVC) - add_definitions(-DDYNAMIC_ICONV) - option(ENABLE_LIBICONV "enable libiconv" OFF) -else() - option(ENABLE_LIBICONV "enable libiconv" ON) -endif() +option(ENABLE_LIBICONV "enable libiconv" ON) # Set default build type. if(NOT CMAKE_BUILD_TYPE) diff --git a/cmake/FindIconv.cmake b/cmake/FindIconv.cmake index f3a54e9d6f..1d0164dae9 100644 --- a/cmake/FindIconv.cmake +++ b/cmake/FindIconv.cmake @@ -8,7 +8,7 @@ include(LibFindMacros) find_path(ICONV_INCLUDE_DIR NAMES iconv.h) -find_library(ICONV_LIBRARY NAMES iconv) +find_library(ICONV_LIBRARY NAMES iconv libiconv) set(Iconv_PROCESS_INCLUDES ICONV_INCLUDE_DIR) if(ICONV_LIBRARY) diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 65c3c6bbb9..bdedce8076 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -457,8 +457,6 @@ if(WIN32) COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/Qt5Widgets.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/winpty.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/ - COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/libiconv-2.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/ - COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/platforms/qwindows.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/platforms/ ) add_dependencies(nvim_runtime_deps external_blobs) diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index adb3d73293..4e115b068f 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -45,8 +45,10 @@ option(USE_BUNDLED_LUA "Use the bundled version of lua." OFF) if(USE_BUNDLED AND MSVC) option(USE_BUNDLED_GETTEXT "Use the bundled version of gettext." ON) + option(USE_BUNDLED_LIBICONV "Use the bundled version of libiconv." ON) else() option(USE_BUNDLED_GETTEXT "Use the bundled version of gettext." OFF) + option(USE_BUNDLED_LIBICONV "Use the bundled version of libiconv." OFF) endif() option(USE_EXISTING_SRC_DIR "Skip download of deps sources in case of existing source directory." OFF) @@ -173,6 +175,9 @@ set(GETTEXT_X86_SHA256 b7d8fe2d038950bc0447d664db614ebfc3100a1ba962a959d78e41bc7 set(GETTEXT_X86_64_URL https://github.com/mlocati/gettext-iconv-windows/releases/download/v0.19.8.1-v1.15/gettext0.19.8.1-iconv1.15-shared-64.zip) set(GETTEXT_X86_64_SHA256 c8ed2897438efc0a511892c2b38b623ef0c9092aced2acbd3f3daf2f12ba70b4) +set(LIBICONV_URL https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.15.tar.gz) +set(LIBICONV_SHA256 ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178) + if(USE_BUNDLED_UNIBILIUM) include(BuildUnibilium) endif() @@ -221,6 +226,10 @@ if(USE_BUNDLED_GETTEXT) include(BuildGettext) endif() +if(USE_BUNDLED_LIBICONV) + include(BuildLibiconv) +endif() + include(GetBinaryDeps) if(WIN32) diff --git a/third-party/cmake/BuildLibiconv.cmake b/third-party/cmake/BuildLibiconv.cmake new file mode 100644 index 0000000000..dc3d8fe4c3 --- /dev/null +++ b/third-party/cmake/BuildLibiconv.cmake @@ -0,0 +1,31 @@ +if(MSVC) + + ExternalProject_Add(libiconv + PREFIX ${DEPS_BUILD_DIR} + URL ${LIBICONV_URL} + DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/libiconv + DOWNLOAD_COMMAND ${CMAKE_COMMAND} + -DPREFIX=${DEPS_BUILD_DIR} + -DDOWNLOAD_DIR=${DEPS_DOWNLOAD_DIR}/libiconv + -DURL=${LIBICONV_URL} + -DEXPECTED_SHA256=${LIBICONV_SHA256} + -DTARGET=libiconv + -DUSE_EXISTING_SRC_DIR=${USE_EXISTING_SRC_DIR} + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DownloadAndExtractFile.cmake + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/LibiconvCMakeLists.txt + ${DEPS_BUILD_DIR}/src/libiconv/CMakeLists.txt + COMMAND ${CMAKE_COMMAND} ${DEPS_BUILD_DIR}/src/libiconv + -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} + # Pass toolchain + -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_GENERATOR=${CMAKE_GENERATOR} + BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${CMAKE_BUILD_TYPE} + INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${CMAKE_BUILD_TYPE}) + +else() + message(FATAL_ERROR "Trying to build libiconv in an unsupported system ${CMAKE_SYSTEM_NAME}/${CMAKE_C_COMPILER_ID}") +endif() + +list(APPEND THIRD_PARTY_DEPS libiconv) diff --git a/third-party/cmake/LibiconvCMakeLists.txt b/third-party/cmake/LibiconvCMakeLists.txt new file mode 100644 index 0000000000..561dee84b2 --- /dev/null +++ b/third-party/cmake/LibiconvCMakeLists.txt @@ -0,0 +1,94 @@ +cmake_minimum_required(VERSION 2.8.7) +project(libiconv C) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/srclib + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/srclib + ${CMAKE_CURRENT_SOURCE_DIR}/build-aux/snippet) + +configure_file(config.h.in config.h) +file(READ "${CMAKE_CURRENT_BINARY_DIR}/config.h" CONFIG_CONTENT) +string(REPLACE "#undef EILSEQ" "" CONFIG_CONTENT "${CONFIG_CONTENT}") +string(REPLACE "#undef HAVE_MBRTOWC" "#define HAVE_MBRTOWC 1" CONFIG_CONTENT "${CONFIG_CONTENT}") +string(REPLACE "#undef HAVE_MBSINIT" "#define HAVE_MBSINIT 1" CONFIG_CONTENT "${CONFIG_CONTENT}") +string(REPLACE "#undef HAVE_WCRTOMB" "#define HAVE_WCRTOMB 1" CONFIG_CONTENT "${CONFIG_CONTENT}") +string(REPLACE "#undef HAVE_DECL___ARGV" "#define HAVE_DECL___ARGV 1" CONFIG_CONTENT "${CONFIG_CONTENT}") +string(REPLACE "#undef HAVE_WORKING_O_NOFOLLOW" "#define HAVE_WORKING_O_NOFOLLOW 0" CONFIG_CONTENT "${CONFIG_CONTENT}") +string(REPLACE "#undef ICONV_CONST" "#define ICONV_CONST const" CONFIG_CONTENT "${CONFIG_CONTENT}") +string(REPLACE "#undef WORDS_LITTLEENDIAN" "#define WORDS_LITTLEENDIAN 1" CONFIG_CONTENT "${CONFIG_CONTENT}") +string(REPLACE "#undef HAVE_DECL_STRERROR_R" "#define HAVE_DECL_STRERROR_R 0" CONFIG_CONTENT "${CONFIG_CONTENT}") +string(REPLACE "#undef mode_t" "#define mode_t int" CONFIG_CONTENT "${CONFIG_CONTENT}") +string(REPLACE "#undef ssize_t" "#include \n#define ssize_t SSIZE_T" CONFIG_CONTENT "${CONFIG_CONTENT}") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/config.h" "${CONFIG_CONTENT}") + +set(BROKEN_WCHAR_H 0) +set(HAVE_VISIBILITY 0) +set(HAVE_WCHAR_T 1) +set(USE_MBSTATE_T 0) +configure_file(libcharset/include/localcharset.h.build.in localcharset.h) +configure_file(include/iconv.h.build.in iconv.h) + +add_definitions(-DLIBDIR -D_CRT_SECURE_NO_WARNINGS) + +add_library(libcharset libcharset/lib/localcharset.c) + +add_library(libiconv lib/iconv.c) +target_link_libraries(libiconv libcharset) + +add_executable(iconv src/iconv.c srclib/progname.c srclib/getprogname.c + srclib/safe-read.c srclib/uniwidth/width.c srclib/error.c srclib/xmalloc.c + srclib/basename-lgpl.c) +target_link_libraries(iconv libiconv) + +set(HEADER_TEMPLATES_PATH "srclib") +set(HEADER_TEMPLATES_ABS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_TEMPLATES_PATH}") +file(GLOB_RECURSE HEADER_TEMPLATES "${HEADER_TEMPLATES_ABS_PATH}/*.in.h") +foreach(HEADER_TEMPLATE IN LISTS HEADER_TEMPLATES) + file(READ ${HEADER_TEMPLATE} HEADER_CONTENT) + string(REPLACE "/* The definition of _GL_ARG_NONNULL is copied here. */" "#include \"arg-nonnull.h\"" HEADER_CONTENT "${HEADER_CONTENT}") + string(REPLACE "/* The definition of _GL_WARN_ON_USE is copied here. */" "#include \"warn-on-use.h\"" HEADER_CONTENT "${HEADER_CONTENT}") + string(REPLACE "/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */" "#include \"c++defs.h\"" HEADER_CONTENT "${HEADER_CONTENT}") + string(REPLACE "@GNULIB_LSTAT@" "1" HEADER_CONTENT "${HEADER_CONTENT}") + string(REPLACE "@GNULIB_SIGACTION@" "1" HEADER_CONTENT "${HEADER_CONTENT}") + string(REPLACE "@GNULIB_SIGPROCMASK@" "1" HEADER_CONTENT "${HEADER_CONTENT}") + string(REPLACE "@HAVE_ISWCNTRL@" "1" HEADER_CONTENT "${HEADER_CONTENT}") + string(REPLACE "@HAVE_WCTYPE_T@" "1" HEADER_CONTENT "${HEADER_CONTENT}") + string(REPLACE "@PRAGMA_COLUMNS@" "" HEADER_CONTENT "${HEADER_CONTENT}") + + string(REGEX REPLACE "^${HEADER_TEMPLATES_ABS_PATH}/" "" HEADER_PATH "${HEADER_TEMPLATE}") + string(REPLACE ".in" "" HEADER_PATH ${HEADER_PATH}) + string(REPLACE "_" "/" HEADER_PATH ${HEADER_PATH}) + # find_file will create a cache entry for the variable + # SYSTEM_HEADER, so reset it before each call + set(SYSTEM_HEADER "SYSTEM_HEADER-NOTFOUND") + find_file(SYSTEM_HEADER ${HEADER_PATH} PATHS "${LIBICONV_INCLUDE_DIRS}") + if(SYSTEM_HEADER) + # Gnulib uses #include_next to extend system header files, + # but MSVC doesn't support it, so a regular include directive + # with a relative path is used instead + string(REGEX REPLACE ".*/(.*/${HEADER_PATH})" "../\\1" + INCLUDE_PATH "${SYSTEM_HEADER}") + string(REGEX REPLACE "@INCLUDE_NEXT[^@]*@ @NEXT_[^@\n]+@" + "include <${INCLUDE_PATH}>" HEADER_CONTENT "${HEADER_CONTENT}") + endif() + + # Default any remaining template variables to 0 + string(REGEX REPLACE "@[^@\n]+@" "0" HEADER_CONTENT "${HEADER_CONTENT}") + + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${HEADER_TEMPLATES_PATH}/${HEADER_PATH}" "${HEADER_CONTENT}") +endforeach() + +include(GNUInstallDirs) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/iconv.h + ${CMAKE_CURRENT_BINARY_DIR}/localcharset.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +install(TARGETS libcharset libiconv iconv + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})