From 4ae7acd152497560491322dd42087f6ddcf7c3a4 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Sun, 10 Apr 2016 23:49:23 -0300 Subject: [PATCH] Add luv as a third party dependency Luv is a simple lua binding to libuv, which is now used by neovim lua client. The bundled luv installation a bit different from other dependencies in that it is installed two times: - The "BuildLuv.cmake" script downloads and installs a static version of luv using its normal cmake build script. This static version will be used later. - Luv default rockspec is replaced with the alternate under the "rockspecs" directory(the alternate rockspec plays nicer with neovim build system) - The alternate rockspec is used to build/install the lua module and make it available to lua scripts. --- third-party/CMakeLists.txt | 8 +++ third-party/cmake/BuildLuarocks.cmake | 8 +++ third-party/cmake/BuildLuv.cmake | 90 +++++++++++++++++++++++++++ third-party/cmake/PatchLuv.cmake | 29 +++++++++ 4 files changed, 135 insertions(+) create mode 100644 third-party/cmake/BuildLuv.cmake create mode 100644 third-party/cmake/PatchLuv.cmake diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index 6f5a5f44dc..f584815499 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -21,6 +21,7 @@ option(USE_BUNDLED_LIBUV "Use the bundled libuv." ${USE_BUNDLED}) option(USE_BUNDLED_MSGPACK "Use the bundled msgpack." ${USE_BUNDLED}) option(USE_BUNDLED_LUAJIT "Use the bundled version of luajit." ${USE_BUNDLED}) option(USE_BUNDLED_LUAROCKS "Use the bundled version of luarocks." ${USE_BUNDLED}) +option(USE_BUNDLED_LUV "Use the bundled version of luv." ${USE_BUNDLED}) #XXX(tarruda): Lua is only used for debugging the functional test client, no # build it unless explicitly requested option(USE_BUNDLED_LUA "Use the bundled version of lua." OFF) @@ -100,6 +101,9 @@ set(LIBVTERM_SHA256 1a4272be91d9614dc183a503786df83b6584e4afaab7feaaa5409f841afb set(JEMALLOC_URL https://github.com/jemalloc/jemalloc/releases/download/4.0.2/jemalloc-4.0.2.tar.bz2) set(JEMALLOC_SHA256 0d8a9c8a98adb6983e0ccb521d45d9db1656ef3e71d0b14fb333f2c8138f4611) + +set(LUV_URL https://github.com/luvit/luv/archive/146f1ce4c08c3b67f604c9ee1e124b1cf5c15cf3.tar.gz) +set(LUV_SHA256 3d537f8eb9fa5adb146a083eae22af886aee324ec268e2aa0fa75f2f1c52ca7a) if(USE_BUNDLED_UNIBILIUM) include(BuildUnibilium) @@ -137,6 +141,10 @@ if(USE_BUNDLED_JEMALLOC) include(BuildJeMalloc) endif() +if(USE_BUNDLED_LUV) + include(BuildLuv) +endif() + add_custom_target(clean-shared-libraries COMMAND ${CMAKE_COMMAND} -DREMOVE_FILE_GLOB=${DEPS_INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}*${CMAKE_SHARED_LIBRARY_SUFFIX}* diff --git a/third-party/cmake/BuildLuarocks.cmake b/third-party/cmake/BuildLuarocks.cmake index a6126af789..8181fa5ece 100644 --- a/third-party/cmake/BuildLuarocks.cmake +++ b/third-party/cmake/BuildLuarocks.cmake @@ -128,6 +128,14 @@ if(USE_BUNDLED_BUSTED) add_custom_target(luacheck DEPENDS ${HOSTDEPS_BIN_DIR}/luacheck) + add_custom_command(OUTPUT ${HOSTDEPS_LIB_DIR}/luarocks/rocks/luv + COMMAND ${LUAROCKS_BINARY} + ARGS make ${LUAROCKS_BUILDARGS} LIBUV_DIR=${HOSTDEPS_INSTALL_DIR} CFLAGS='-O0 -g3 -fPIC' + WORKING_DIRECTORY ${DEPS_BUILD_DIR}/src/luv + DEPENDS luacheck luv-static) + add_custom_target(luv + DEPENDS ${HOSTDEPS_LIB_DIR}/luarocks/rocks/luv) + add_custom_command(OUTPUT ${HOSTDEPS_LIB_DIR}/luarocks/rocks/nvim-client COMMAND ${LUAROCKS_BINARY} ARGS build https://raw.githubusercontent.com/neovim/lua-client/0.0.1-14/nvim-client-0.0.1-14.rockspec ${LUAROCKS_BUILDARGS} LIBUV_DIR=${HOSTDEPS_INSTALL_DIR} diff --git a/third-party/cmake/BuildLuv.cmake b/third-party/cmake/BuildLuv.cmake new file mode 100644 index 0000000000..3060590bce --- /dev/null +++ b/third-party/cmake/BuildLuv.cmake @@ -0,0 +1,90 @@ +include(CMakeParseArguments) + +# BuildLuv(PATCH_COMMAND ... CONFIGURE_COMMAND ... BUILD_COMMAND ... INSTALL_COMMAND ...) +# Reusable function to build luv, wraps ExternalProject_Add. +# Failing to pass a command argument will result in no command being run +function(BuildLuv) + cmake_parse_arguments(_luv + "" + "" + "PATCH_COMMAND;CONFIGURE_COMMAND;BUILD_COMMAND;INSTALL_COMMAND" + ${ARGN}) + + if(NOT _luv_CONFIGURE_COMMAND AND NOT _luv_BUILD_COMMAND + AND NOT _luv_INSTALL_COMMAND) + message(FATAL_ERROR "Must pass at least one of CONFIGURE_COMMAND, BUILD_COMMAND, INSTALL_COMMAND") + endif() + + ExternalProject_Add(luv-static + PREFIX ${DEPS_BUILD_DIR} + URL ${LUV_URL} + DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/luv + DOWNLOAD_COMMAND ${CMAKE_COMMAND} + -DPREFIX=${DEPS_BUILD_DIR} + -DDOWNLOAD_DIR=${DEPS_DOWNLOAD_DIR}/luv + -DURL=${LUV_URL} + -DEXPECTED_SHA256=${LUV_SHA256} + -DTARGET=luv + -DUSE_EXISTING_SRC_DIR=${USE_EXISTING_SRC_DIR} + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DownloadAndExtractFile.cmake + PATCH_COMMAND "${_luv_PATCH_COMMAND}" + CONFIGURE_COMMAND "${_luv_CONFIGURE_COMMAND}" + BUILD_COMMAND "${_luv_BUILD_COMMAND}" + INSTALL_COMMAND "${_luv_INSTALL_COMMAND}") +endfunction() + +set(LUV_SRC_DIR ${DEPS_BUILD_DIR}/src/luv) +set(LUV_INCLUDE_FLAGS + "-I${DEPS_INSTALL_DIR}/include -I${DEPS_INSTALL_DIR}/include/luajit-2.0") + +set(LUV_PATCH_COMMAND + ${CMAKE_COMMAND} -DLUV_SRC_DIR=${LUV_SRC_DIR} + -P ${PROJECT_SOURCE_DIR}/cmake/PatchLuv.cmake) + +set(LUV_CONFIGURE_COMMAND_COMMON + ${CMAKE_COMMAND} ${LUV_SRC_DIR} + -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} + -DLUA_BUILD_TYPE=System + -DWITH_SHARED_LIBUV=ON + -DBUILD_SHARED_LIBS=OFF + -DBUILD_MODULE=OFF) + +if(MINGW AND CMAKE_CROSSCOMPILING) + get_filename_component(TOOLCHAIN ${CMAKE_TOOLCHAIN_FILE} REALPATH) + set(LUV_CONFIGURE_COMMAND + ${LUV_CONFIGURE_COMMAND_COMMON} + # Pass toolchain + -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} + "-DCMAKE_C_FLAGS:STRING=${LUV_INCLUDE_FLAGS} -D_WIN32_WINNT=0x0600" + # Hack to avoid -rdynamic in Mingw + -DCMAKE_SHARED_LIBRARY_LINK_C_FLAGS="") +elseif(MSVC) + set(LUV_CONFIGURE_COMMAND + ${LUV_CONFIGURE_COMMAND_COMMON} + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + # Same as Unix without fPIC + "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_COMPILER_ARG1} ${LUV_INCLUDE_FLAGS}" + # Make sure we use the same generator, otherwise we may + # accidentaly end up using different MSVC runtimes + -DCMAKE_GENERATOR=${CMAKE_GENERATOR} + # Use static runtime + -DCMAKE_C_FLAGS_DEBUG="-MTd" + -DCMAKE_C_FLAGS_RELEASE="-MT") +else() + set(LUV_CONFIGURE_COMMAND + ${LUV_CONFIGURE_COMMAND_COMMON} + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_COMPILER_ARG1} ${LUV_INCLUDE_FLAGS} -fPIC") +endif() + +set(LUV_BUILD_COMMAND ${CMAKE_COMMAND} --build .) +set(LUV_INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install) + +BuildLuv(PATCH_COMMAND ${LUV_PATCH_COMMAND} + CONFIGURE_COMMAND ${LUV_CONFIGURE_COMMAND} + BUILD_COMMAND ${LUV_BUILD_COMMAND} + INSTALL_COMMAND ${LUV_INSTALL_COMMAND}) + +list(APPEND THIRD_PARTY_DEPS luv-static) +add_dependencies(luv-static luajit) +add_dependencies(luv-static libuv) diff --git a/third-party/cmake/PatchLuv.cmake b/third-party/cmake/PatchLuv.cmake new file mode 100644 index 0000000000..96595a2f30 --- /dev/null +++ b/third-party/cmake/PatchLuv.cmake @@ -0,0 +1,29 @@ +# replace luv default rockspec with the alternate one under the "rockspecs" +# directory +file(GLOB LUV_ROCKSPEC RELATIVE ${LUV_SRC_DIR} ${LUV_SRC_DIR}/*.rockspec) +file(RENAME ${LUV_SRC_DIR}/rockspecs/${LUV_ROCKSPEC} ${LUV_SRC_DIR}/${LUV_ROCKSPEC}) + +# Some versions of mingw are missing defines required by luv dns module, add +# them now +set(LUV_SRC_DNS_C_DEFS +"#ifndef AI_NUMERICSERV +# define AI_NUMERICSERV 0x0008 +#endif +#ifndef AI_ALL +# define AI_ALL 0x00000100 +#endif +#ifndef AI_ADDRCONFIG +# define AI_ADDRCONFIG 0x00000400 +#endif +#ifndef AI_V4MAPPED +# define AI_V4MAPPED 0x00000800 +#endif") + +file(READ ${LUV_SRC_DIR}/src/dns.c LUV_SRC_DNS_C) +string(REPLACE + "\n#include " + "\n#include \n#else\n${LUV_SRC_DNS_C_DEFS}" + LUV_SRC_DNS_C_PATCHED + "${LUV_SRC_DNS_C}") +file(WRITE ${LUV_SRC_DIR}/src/dns.c "${LUV_SRC_DNS_C_PATCHED}") +