CMakeLists.txt 11.1 KB
Newer Older
1 2
cmake_minimum_required(VERSION 2.8.7)
project(NEOVIM)
3

4
# Point CMake at any custom modules we may ship
5
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
6

7
# Prefer our bundled versions of dependencies.
8 9
set(DEPS_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/.deps/usr" CACHE PATH "Path prefix for finding dependencies")
list(INSERT CMAKE_PREFIX_PATH 0 ${DEPS_PREFIX})
10
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${DEPS_PREFIX}/lib/pkgconfig")
11

12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  # CMake tries to treat /sw and /opt/local as extension of the system path, but
  # that doesn't really work out very well.  Once you have a dependency that
  # resides there and have to add it as an include directory, then any other
  # dependency that could be satisfied from there must be--otherwise you can end
  # up with conflicting versions.  So, let's make them more of a priority having
  # them be included as one of the first places to look for dependencies.
  list(APPEND CMAKE_PREFIX_PATH /sw /opt/local)

  # Work around some old, broken detection by CMake for knowing when to use the
  # isystem flag.  Apple's compilers have supported this for quite some time
  # now.
  if(CMAKE_COMPILER_IS_GNUCC)
    set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
  endif()
  if(CMAKE_COMPILER_IS_GNUCXX)
    set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ")
  endif()
30 31 32

  # Enable fixing case-insensitive filenames for Mac.
  set(USE_FNAME_CASE TRUE)
33 34
endif()

35 36 37 38 39 40 41 42 43 44 45
# Set available build types for CMake GUIs.
# A different build type can still be set by -DCMAKE_BUILD_TYPE=...
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
  STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")

# Set default build type.
if(NOT CMAKE_BUILD_TYPE)
  message(STATUS "CMAKE_BUILD_TYPE not given; setting to 'RelWithDebInfo'.")
  set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build." FORCE)
endif()

46
# Version tokens
47
include(GetGitRevisionDescription)
48
get_git_head_revision(GIT_REFSPEC NVIM_VERSION_COMMIT)
49
if(NOT NVIM_VERSION_COMMIT)
50 51
  set(NVIM_VERSION_COMMIT "?")
endif()
52 53 54 55
set(NVIM_VERSION_MAJOR 0)
set(NVIM_VERSION_MINOR 0)
set(NVIM_VERSION_PATCH 0)
set(NVIM_VERSION_PRERELEASE "-alpha")
56 57
# TODO(justinmk): UTC time would be nice here #1071
git_timestamp(GIT_TIMESTAMP)
58
# TODO(justinmk): do not set this for "release" builds #1071
59
if(GIT_TIMESTAMP)
60 61
  set(NVIM_VERSION_BUILD "+${GIT_TIMESTAMP}")
endif()
62 63
set(NVIM_VERSION_BUILD_TYPE "${CMAKE_BUILD_TYPE}")
# NVIM_VERSION_CFLAGS set further below.
64 65 66

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

67 68 69
# Default to -O2 on release builds.
string(REPLACE "-O3" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")

70 71 72
# Enable -Wconversion.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion")

73 74 75
# gcc 4.0 and better turn on _FORTIFY_SOURCE=2 automatically.  This currently
# does not work with Neovim due to some uses of dynamically-sized structures.
# See https://github.com/neovim/neovim/issues/223 for details.
76
include(CheckCSourceCompiles)
77 78 79 80 81 82 83 84 85 86 87

# Include the build type's default flags in the check for _FORTIFY_SOURCE,
# otherwise we may incorrectly identify the level as acceptable and find out
# later that it was not when optimizations were enabled.  CFLAGS is applied
# even though you don't see it in CMAKE_REQUIRED_FLAGS.
set(INIT_FLAGS_NAME CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE})
string(TOUPPER ${INIT_FLAGS_NAME} INIT_FLAGS_NAME)
if(${INIT_FLAGS_NAME})
  set(CMAKE_REQUIRED_FLAGS "${${INIT_FLAGS_NAME}}")
endif()

88 89 90 91 92 93 94 95 96 97 98 99
check_c_source_compiles("
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 1
#error \"_FORTIFY_SOURCE > 1\"
#endif
int
main(void)
{
  return 0;
}
" _FORTIFY_SOURCE_ACCEPTABLE)

if(NOT _FORTIFY_SOURCE_ACCEPTABLE)
100 101 102 103 104 105
  # Extract possible prefix to _FORTIFY_SOURCE (e.g. -Wp,-D_FORTIFY_SOURCE).
  STRING(REGEX MATCH "[^\ ]+-D_FORTIFY_SOURCE" _FORTIFY_SOURCE_PREFIX "${CMAKE_C_FLAGS}")
  STRING(REPLACE "-D_FORTIFY_SOURCE" "" _FORTIFY_SOURCE_PREFIX "${_FORTIFY_SOURCE_PREFIX}" )
  if (NOT _FORTIFY_SOURCE_PREFIX STREQUAL "")
    message(STATUS "Detected _FORTIFY_SOURCE Prefix=${_FORTIFY_SOURCE_PREFIX}")
  endif()
106 107
  # -U in add_definitions doesn't end up in the correct spot, so we add it to
  # the flags variable instead.
108 109
  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_FORTIFY_SOURCE_PREFIX}-U_FORTIFY_SOURCE ${_FORTIFY_SOURCE_PREFIX}-D_FORTIFY_SOURCE=1")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_FORTIFY_SOURCE_PREFIX}-U_FORTIFY_SOURCE ${_FORTIFY_SOURCE_PREFIX}-D_FORTIFY_SOURCE=1")
110 111
endif()

112 113
add_definitions(-Wall -Wextra -pedantic -Wno-unused-parameter
    -Wstrict-prototypes -std=gnu99)
114 115 116 117 118 119 120 121

option(
  TRAVIS_CI_BUILD "Travis CI build.  Extra compilation flags will be set." OFF)

if(TRAVIS_CI_BUILD)
  message(STATUS "Travis CI build enabled.")
  add_definitions(-Werror)
endif()
122

123 124 125 126 127 128 129
if(CMAKE_COMPILER_IS_GNUCC)
  include(CheckCCompilerFlag)
  check_c_compiler_flag(-Og HAS_OG_FLAG)
else()
  set(HAS_OG_FLAG 0)
endif()

130 131
# Set custom build flags for RelWithDebInfo.
# -DNDEBUG purposely omitted because we want assertions.
132
if(HAS_OG_FLAG)
133 134 135 136 137 138
  set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Og -g"
    CACHE STRING "Flags used by the compiler during release builds with debug info." FORCE)
else()
  set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g"
    CACHE STRING "Flags used by the compiler during release builds with debug info." FORCE)
endif()
139

140 141 142 143 144 145
if(CMAKE_BUILD_TYPE MATCHES Debug)
  set(DEBUG 1)
else()
  set(DEBUG 0)
endif()

146 147 148
add_definitions(-DINCLUDE_GENERATED_DECLARATIONS)
add_definitions(-DHAVE_CONFIG_H)

149 150 151 152 153 154
if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined")
  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
  set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
endif()

155 156 157 158
if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_NAME STREQUAL "SunOS")
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined -lsocket")
endif()

159 160 161 162 163 164 165 166 167 168
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
  # Required for luajit.
  set(CMAKE_EXE_LINKER_FLAGS
    "${CMAKE_EXE_LINKER_FLAGS} -pagezero_size 10000 -image_base 100000000")
  set(CMAKE_SHARED_LINKER_FLAGS
    "${CMAKE_SHARED_LINKER_FLAGS} -image_base 100000000")
  set(CMAKE_MODULE_LINKER_FLAGS
    "${CMAKE_MODULE_LINKER_FLAGS} -image_base 100000000")
endif()

aph's avatar
aph committed
169 170 171 172 173 174 175 176 177
option(USE_GCOV "Enable gcov support" OFF)

if(USE_GCOV)
  message(STATUS "Enabling gcov support")
  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage")
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage")
endif()

178 179 180
include_directories("${PROJECT_BINARY_DIR}/config")
include_directories("${PROJECT_SOURCE_DIR}/src")

181 182 183
# Modules used by platform auto-detection
include(CheckLibraryExists)

184
find_package(LibUV REQUIRED)
185
include_directories(SYSTEM ${LIBUV_INCLUDE_DIRS})
186

187
find_package(Msgpack REQUIRED)
188
include_directories(SYSTEM ${MSGPACK_INCLUDE_DIRS})
189

190
find_package(LuaJit REQUIRED)
191
include_directories(SYSTEM ${LUAJIT_INCLUDE_DIRS})
192

193
option(LIBUNIBILIUM_USE_STATIC "Use static libunibilium" ON)
194 195 196
find_package(LibUnibilium REQUIRED)
include_directories(SYSTEM ${LIBUNIBILIUM_INCLUDE_DIRS})

197
option(LIBTERMKEY_USE_STATIC "Use static libtermkey" ON)
198
find_package(LibTermkey REQUIRED)
199
include_directories(SYSTEM ${LIBTERMKEY_INCLUDE_DIRS})
200

201
option(LIBVTERM_USE_STATIC "Use static libvterm" ON)
202 203 204
find_package(LibVterm REQUIRED)
include_directories(SYSTEM ${LIBVTERM_INCLUDE_DIRS})

205 206
find_package(LibIntl)
if(LibIntl_FOUND)
207
  include_directories(SYSTEM ${LibIntl_INCLUDE_DIRS})
208 209
endif()

210 211 212
find_package(Iconv)
if(Iconv_FOUND)
  include_directories(SYSTEM ${Iconv_INCLUDE_DIRS})
213 214
endif()

215
# Determine platform's threading library. Set CMAKE_THREAD_PREFER_PTHREAD
216
# explicitly to indicate a strong preference for pthread.
217 218 219
set(CMAKE_THREAD_PREFER_PTHREAD ON)
find_package(Threads REQUIRED)

220
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
221 222
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
223

224
# Find Lua interpreter
225
include(LuaHelpers)
226
set(LUA_DEPENDENCIES lpeg MessagePack bit)
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
if(NOT LUA_PRG)
  foreach(CURRENT_LUA_PRG luajit lua)
    # If LUA_PRG is set find_program() will not search
    unset(LUA_PRG CACHE)
    unset(LUA_PRG_WORKS)
    find_program(LUA_PRG ${CURRENT_LUA_PRG})

    if(LUA_PRG)
      check_lua_deps(${LUA_PRG} "${LUA_DEPENDENCIES}" LUA_PRG_WORKS)
      if(LUA_PRG_WORKS)
        break()
      endif()
    endif()
  endforeach()
else()
  check_lua_deps(${LUA_PRG} "${LUA_DEPENDENCIES}" LUA_PRG_WORKS)
endif()
244

245 246
if(NOT LUA_PRG_WORKS)
  message(FATAL_ERROR "A suitable Lua interpreter was not found")
247 248
endif()

249
message(STATUS "Using the Lua interpreter ${LUA_PRG}")
250

251
# Setup busted.
252
find_program(BUSTED_PRG busted)
253 254 255
if(NOT BUSTED_OUTPUT_TYPE)
  set(BUSTED_OUTPUT_TYPE "utfTerminal")
endif()
256

257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
# CMake is painful here.  It will create the destination using the user's
# current umask, and we don't want that.  And we don't just want to install
# the target directory, as it will mess with existing permissions.  So this
# seems like the best compromise.  If we create it, then everyone can see it.
# If it's preexisting, leave it alone.
include(InstallHelpers)

install_helper(
  DIRECTORY runtime
  DESTINATION share/nvim)

file(GLOB_RECURSE RUNTIME_PROGRAMS
  RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
  runtime/*.pl runtime/*.awk runtime/*.sh
  runtime/tools/ref
  runtime/tools/vimm)

foreach(PROG ${RUNTIME_PROGRAMS})
  get_filename_component(BASEDIR ${PROG} PATH)
  install_helper(PROGRAMS ${PROG} DESTINATION share/nvim/${BASEDIR})
endforeach()

279
install(SCRIPT ${PROJECT_SOURCE_DIR}/cmake/GenerateHelptags.cmake)
280 281

# Go down the tree.
282

283
add_subdirectory(src/nvim)
284 285 286 287 288
# Read compilation flags from src/nvim,
# used in config subdirectory below.
include(GetCompileFlags)
get_compile_flags(NVIM_VERSION_CFLAGS)

289
add_subdirectory(test/includes)
290
add_subdirectory(config)
291 292
add_subdirectory(test/functional/job) # compile pty test program

293 294 295

# Setup some test-related bits.  We do this after going down the tree because we
# need some of the targets.
John Szakmeister's avatar
John Szakmeister committed
296
if(BUSTED_PRG)
297 298
  get_property(TEST_INCLUDE_DIRS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    PROPERTY INCLUDE_DIRECTORIES)
299 300 301 302 303 304

  # Set policy CMP0026 to OLD so we avoid CMake warnings on newer
  # versions of cmake.
  if(POLICY CMP0026)
    cmake_policy(SET CMP0026 OLD)
  endif()
305 306 307 308 309 310
  get_target_property(TEST_LIBNVIM_PATH nvim-test LOCATION)

  configure_file(
    test/config/paths.lua.in
    ${CMAKE_BINARY_DIR}/test/config/paths.lua)

John Szakmeister's avatar
John Szakmeister committed
311 312 313
  add_custom_target(unittest
    COMMAND ${CMAKE_COMMAND}
      -DBUSTED_PRG=${BUSTED_PRG}
Thiago de Arruda's avatar
Thiago de Arruda committed
314
      -DLUA_PRG=${LUA_PRG}
John Szakmeister's avatar
John Szakmeister committed
315 316 317
      -DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR}
      -DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE}
      -DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
318
      -DBUILD_DIR=${CMAKE_BINARY_DIR}
319
      -DTEST_TYPE=unit
320
      -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake
John Szakmeister's avatar
John Szakmeister committed
321
    DEPENDS nvim-test unittest-headers)
322

323
  add_custom_target(functionaltest
324
    COMMAND ${CMAKE_COMMAND}
325
      -DBUSTED_PRG=${BUSTED_PRG}
326
      -DNVIM_PRG=$<TARGET_FILE:nvim>
327 328 329 330 331
      -DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR}
      -DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE}
      -DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
      -DBUILD_DIR=${CMAKE_BINARY_DIR}
      -DTEST_TYPE=functional
332
      -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake
333
    DEPENDS nvim tty-test)
John Szakmeister's avatar
John Szakmeister committed
334
endif()