CMakeLists.txt 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. # Copyright (C) 2011, 2012 Google Inc.
  2. #
  3. # This file is part of YouCompleteMe.
  4. #
  5. # YouCompleteMe is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # YouCompleteMe is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
  17. cmake_minimum_required( VERSION 2.8 )
  18. project( ycm_support_libs )
  19. set( CLIENT_LIB "ycm_client_support" )
  20. set( SERVER_LIB "ycm_core" )
  21. set( Python_ADDITIONAL_VERSIONS 2.7 2.6 )
  22. find_package( PythonLibs 2.6 REQUIRED )
  23. if ( NOT PYTHONLIBS_VERSION_STRING VERSION_LESS "3.0.0" )
  24. message( FATAL_ERROR
  25. "CMake found python3 libs instead of python2 libs. YCM works only with "
  26. "python2.\n" )
  27. endif()
  28. option( USE_DEV_FLAGS "Use compilation flags meant for YCM developers" OFF )
  29. option( USE_CLANG_COMPLETER "Use Clang semantic completer for C/C++/ObjC" OFF )
  30. option( USE_SYSTEM_LIBCLANG "Set to ON to use the system libclang library" OFF )
  31. set( PATH_TO_LLVM_ROOT "" CACHE PATH "Path to the root of a LLVM+Clang binary distribution" )
  32. set( EXTERNAL_LIBCLANG_PATH "" CACHE PATH "Path to the libclang library to use" )
  33. if ( USE_CLANG_COMPLETER AND
  34. NOT USE_SYSTEM_LIBCLANG AND
  35. NOT PATH_TO_LLVM_ROOT AND
  36. NOT EXTERNAL_LIBCLANG_PATH )
  37. message( "Downloading Clang 3.4" )
  38. set( CLANG_URL "http://llvm.org/releases/3.4" )
  39. if ( APPLE )
  40. set( CLANG_DIRNAME "clang+llvm-3.4-x86_64-apple-darwin10.9" )
  41. set( CLANG_MD5 "4f43ea0e87090ae5e7bec12373ca4927" )
  42. set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.gz" )
  43. else()
  44. if ( 64_BIT_PLATFORM )
  45. set( CLANG_DIRNAME "clang+llvm-3.4-x86_64-unknown-ubuntu12.04" )
  46. set( CLANG_MD5 "6077459d20a7ff412eefc6ce3b9f5c85" )
  47. set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.xz" )
  48. else()
  49. message( "No pre-built Clang 3.4 binaries for 32 bit linux, "
  50. "downloading Clang 3.3" )
  51. set( CLANG_URL "http://llvm.org/releases/3.3" )
  52. set( CLANG_DIRNAME "clang+llvm-3.3-i386-debian6" )
  53. set( CLANG_MD5 "415d033b60659433d4631df894673802" )
  54. set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.bz2" )
  55. endif()
  56. endif()
  57. file(
  58. DOWNLOAD "${CLANG_URL}/${CLANG_FILENAME}" "./${CLANG_FILENAME}"
  59. SHOW_PROGRESS EXPECTED_MD5 "${CLANG_MD5}"
  60. )
  61. if ( CLANG_FILENAME MATCHES ".+bz2" )
  62. execute_process( COMMAND tar -xjf ${CLANG_FILENAME} )
  63. elseif( CLANG_FILENAME MATCHES ".+xz" )
  64. execute_process( COMMAND tar -xJf ${CLANG_FILENAME} )
  65. else()
  66. execute_process( COMMAND tar -xzf ${CLANG_FILENAME} )
  67. endif()
  68. # And set PATH_TO_LLVM_ROOT
  69. set( PATH_TO_LLVM_ROOT "${CMAKE_CURRENT_BINARY_DIR}/../${CLANG_DIRNAME}" )
  70. endif()
  71. if ( PATH_TO_LLVM_ROOT OR USE_SYSTEM_LIBCLANG OR EXTERNAL_LIBCLANG_PATH )
  72. set( USE_CLANG_COMPLETER TRUE )
  73. endif()
  74. if ( USE_CLANG_COMPLETER AND
  75. NOT PATH_TO_LLVM_ROOT AND
  76. NOT USE_SYSTEM_LIBCLANG AND
  77. NOT EXTERNAL_LIBCLANG_PATH )
  78. message( FATAL_ERROR
  79. "You have not specified which libclang to use. You have several options:\n"
  80. " 1. Set PATH_TO_LLVM_ROOT to a path to the root of a LLVM+Clang binary "
  81. "distribution. You can download such a binary distro from llvm.org. This "
  82. "is the recommended approach.\n"
  83. " 2. Set USE_SYSTEM_LIBCLANG to ON; this makes YCM search for the system "
  84. "version of libclang.\n"
  85. " 3. Set EXTERNAL_LIBCLANG_PATH to a path to whatever "
  86. "libclang.[so|dylib|dll] you wish to use.\n"
  87. "You HAVE to pick one option. See the docs for more information.")
  88. endif()
  89. if ( USE_CLANG_COMPLETER )
  90. message( "Using libclang to provide semantic completion for C/C++/ObjC" )
  91. else()
  92. message( "NOT using libclang, no semantic completion for C/C++/ObjC will be "
  93. "available" )
  94. endif()
  95. if ( PATH_TO_LLVM_ROOT )
  96. set( CLANG_INCLUDES_DIR "${PATH_TO_LLVM_ROOT}/include" )
  97. else()
  98. set( CLANG_INCLUDES_DIR "${CMAKE_SOURCE_DIR}/llvm/include" )
  99. endif()
  100. if ( NOT IS_ABSOLUTE "${CLANG_INCLUDES_DIR}" )
  101. get_filename_component(CLANG_INCLUDES_DIR
  102. "${CMAKE_BINARY_DIR}/${CLANG_INCLUDES_DIR}" ABSOLUTE)
  103. endif()
  104. if ( NOT EXTERNAL_LIBCLANG_PATH AND PATH_TO_LLVM_ROOT )
  105. if ( MINGW )
  106. set( LIBCLANG_SEARCH_PATH "${PATH_TO_LLVM_ROOT}/bin" )
  107. else()
  108. set( LIBCLANG_SEARCH_PATH "${PATH_TO_LLVM_ROOT}/lib" )
  109. endif()
  110. # Need TEMP because find_library does not work with an option variable
  111. find_library( TEMP NAMES clang libclang
  112. PATHS ${LIBCLANG_SEARCH_PATH}
  113. NO_DEFAULT_PATH )
  114. set( EXTERNAL_LIBCLANG_PATH ${TEMP} )
  115. endif()
  116. # This is a workaround for a CMake bug with include_directories(SYSTEM ...)
  117. # on Mac OS X. Bug report: http://public.kitware.com/Bug/view.php?id=10837
  118. if ( APPLE )
  119. set( CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem " )
  120. endif()
  121. # The SYSTEM flag makes sure that -isystem[header path] is passed to the
  122. # compiler instead of the standard -I[header path]. Headers included with
  123. # -isystem do not generate warnings (and they shouldn't; e.g. boost warnings are
  124. # just noise for us since we won't be changing them).
  125. include_directories(
  126. SYSTEM
  127. ${BoostParts_SOURCE_DIR}
  128. ${PYTHON_INCLUDE_DIRS}
  129. ${CLANG_INCLUDES_DIR}
  130. )
  131. file( GLOB_RECURSE SERVER_SOURCES *.h *.cpp )
  132. # The test sources are a part of a different target, so we remove them
  133. # The CMakeFiles cpp file is picked up when the user creates an in-source build,
  134. # and we don't want that. We also remove client-specific code
  135. file( GLOB_RECURSE to_remove tests/*.h tests/*.cpp CMakeFiles/*.cpp *client* )
  136. if( to_remove )
  137. list( REMOVE_ITEM SERVER_SOURCES ${to_remove} )
  138. endif()
  139. if ( USE_CLANG_COMPLETER )
  140. include_directories(
  141. ${CMAKE_CURRENT_SOURCE_DIR}
  142. "${CMAKE_CURRENT_SOURCE_DIR}/ClangCompleter" )
  143. add_definitions( -DUSE_CLANG_COMPLETER )
  144. else()
  145. file( GLOB_RECURSE to_remove_clang ClangCompleter/*.h ClangCompleter/*.cpp )
  146. if( to_remove_clang )
  147. list( REMOVE_ITEM SERVER_SOURCES ${to_remove_clang} )
  148. endif()
  149. endif()
  150. #############################################################################
  151. # One can use the system libclang.[so|dylib] like so:
  152. # cmake -DUSE_SYSTEM_LIBCLANG=1 [...]
  153. # One can also explicitely pick the external libclang.[so|dylib] for use like so:
  154. # cmake -DEXTERNAL_LIBCLANG_PATH=/path/to/libclang.so [...]
  155. # The final .so we build will then first look in the same dir in which it is
  156. # located for libclang.so. This is provided by the rpath = $ORIGIN feature.
  157. if ( EXTERNAL_LIBCLANG_PATH OR USE_SYSTEM_LIBCLANG )
  158. if ( USE_SYSTEM_LIBCLANG )
  159. if ( APPLE )
  160. set( ENV_LIB_PATHS ENV DYLD_LIBRARY_PATH )
  161. elseif ( UNIX )
  162. set( ENV_LIB_PATHS ENV LD_LIBRARY_PATH )
  163. elseif ( WIN32 )
  164. set( ENV_LIB_PATHS ENV PATH )
  165. else ()
  166. set( ENV_LIB_PATHS "" )
  167. endif()
  168. # On Debian-based systems, llvm installs into /usr/lib/llvm-x.y.
  169. file( GLOB SYS_LLVM_PATHS "/usr/lib/llvm*/lib" )
  170. # Need TEMP because find_library does not work with an option variable
  171. find_library( TEMP clang
  172. PATHS
  173. ${ENV_LIB_PATHS}
  174. /usr/lib
  175. /usr/lib/llvm
  176. ${SYS_LLVM_PATHS}
  177. /Library/Developer/CommandLineTools/usr/lib,
  178. /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib )
  179. set( EXTERNAL_LIBCLANG_PATH ${TEMP} )
  180. else()
  181. # For Macs, we do things differently; look further in this file.
  182. if ( NOT APPLE )
  183. # Setting this to true makes sure that libraries we build will have our rpath
  184. # set even without having to do "make install"
  185. set( CMAKE_BUILD_WITH_INSTALL_RPATH TRUE )
  186. set( CMAKE_INSTALL_RPATH "\$ORIGIN" )
  187. endif()
  188. endif()
  189. set( LIBCLANG_TARGET ${EXTERNAL_LIBCLANG_PATH} )
  190. message(
  191. "Using external libclang: ${EXTERNAL_LIBCLANG_PATH}" )
  192. else()
  193. set( LIBCLANG_TARGET )
  194. endif()
  195. if ( EXTRA_RPATH )
  196. set( CMAKE_INSTALL_RPATH "${EXTRA_RPATH}:${CMAKE_INSTALL_RPATH}" )
  197. endif()
  198. # Needed on Linux machines, but not on Macs
  199. if ( UNIX AND NOT APPLE )
  200. set( EXTRA_LIBS rt )
  201. endif()
  202. #############################################################################
  203. # We don't actually need all of the files this picks up, just the ones needed by
  204. # PythonSupport.cpp. But this is easier to maintain and dead code elemination
  205. # will remove unused code.
  206. file( GLOB CLIENT_SOURCES *.h *.cpp )
  207. file( GLOB SERVER_SPECIFIC *ycm_core* )
  208. if( SERVER_SPECIFIC )
  209. list( REMOVE_ITEM CLIENT_SOURCES ${SERVER_SPECIFIC} )
  210. endif()
  211. add_library( ${CLIENT_LIB} SHARED
  212. ${CLIENT_SOURCES}
  213. )
  214. target_link_libraries( ${CLIENT_LIB}
  215. BoostParts
  216. ${PYTHON_LIBRARIES}
  217. ${EXTRA_LIBS}
  218. )
  219. #############################################################################
  220. add_library( ${SERVER_LIB} SHARED
  221. ${SERVER_SOURCES}
  222. )
  223. target_link_libraries( ${SERVER_LIB}
  224. BoostParts
  225. ${PYTHON_LIBRARIES}
  226. ${LIBCLANG_TARGET}
  227. ${EXTRA_LIBS}
  228. )
  229. if( LIBCLANG_TARGET )
  230. if( NOT WIN32 )
  231. add_custom_command(
  232. TARGET ${SERVER_LIB}
  233. POST_BUILD
  234. COMMAND ${CMAKE_COMMAND} -E copy "${LIBCLANG_TARGET}" "$<TARGET_FILE_DIR:${SERVER_LIB}>"
  235. )
  236. else()
  237. add_custom_command(
  238. TARGET ${SERVER_LIB}
  239. POST_BUILD
  240. COMMAND ${CMAKE_COMMAND} -E copy "${PATH_TO_LLVM_ROOT}/bin/libclang.dll" "$<TARGET_FILE_DIR:${SERVER_LIB}>")
  241. endif()
  242. endif()
  243. #############################################################################
  244. # Convenience target that builds both support libs.
  245. add_custom_target( ${PROJECT_NAME}
  246. DEPENDS ${CLIENT_LIB} ${SERVER_LIB} )
  247. #############################################################################
  248. # Things are a bit different on Macs when using an external libclang.dylib; here
  249. # we want to make sure we use @loader_path/libclang.dylib instead of
  250. # @rpath/libclang.dylib in the final ycm_core.so. If we use the
  251. # @rpath version, then it may load the system libclang which the user
  252. # explicitely does not want (otherwise the user would specify
  253. # USE_SYSTEM_LIBCLANG). With @loader_path, we make sure that only the
  254. # libclang.dylib present in the same directory as our ycm_core.so
  255. # is used.
  256. if ( EXTERNAL_LIBCLANG_PATH AND APPLE )
  257. add_custom_command( TARGET ${SERVER_LIB}
  258. POST_BUILD
  259. COMMAND install_name_tool
  260. "-change"
  261. "@rpath/libclang.dylib"
  262. "@loader_path/libclang.dylib"
  263. "$<TARGET_FILE:${SERVER_LIB}>"
  264. )
  265. endif()
  266. #############################################################################
  267. # We don't want the "lib" prefix, it can screw up python when it tries to search
  268. # for our module
  269. set_target_properties( ${CLIENT_LIB} PROPERTIES PREFIX "")
  270. set_target_properties( ${SERVER_LIB} PROPERTIES PREFIX "")
  271. if ( WIN32 OR CYGWIN )
  272. # DLL platforms put dlls in the RUNTIME_OUTPUT_DIRECTORY
  273. set_target_properties( ${CLIENT_LIB} PROPERTIES
  274. RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../python )
  275. set_target_properties( ${SERVER_LIB} PROPERTIES
  276. RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../python )
  277. if ( WIN32 )
  278. # This is the extension for compiled Python modules on Windows
  279. set_target_properties( ${CLIENT_LIB} PROPERTIES SUFFIX ".pyd")
  280. set_target_properties( ${SERVER_LIB} PROPERTIES SUFFIX ".pyd")
  281. elseif ( CYGWIN )
  282. # This is the extension for compiled Python modules in Cygwin
  283. set_target_properties( ${CLIENT_LIB} PROPERTIES SUFFIX ".dll")
  284. set_target_properties( ${SERVER_LIB} PROPERTIES SUFFIX ".dll")
  285. endif()
  286. else()
  287. # Even on macs, we want a .so extension instead of a .dylib which is what
  288. # cmake would give us by default. Python won't recognize a .dylib as a module,
  289. # but it will recognize a .so
  290. set_target_properties( ${CLIENT_LIB} PROPERTIES SUFFIX ".so")
  291. set_target_properties( ${SERVER_LIB} PROPERTIES SUFFIX ".so")
  292. endif()
  293. set_target_properties( ${CLIENT_LIB} PROPERTIES
  294. LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../python )
  295. set_target_properties( ${SERVER_LIB} PROPERTIES
  296. LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../python )
  297. #############################################################################
  298. # For some reason, Xcode is too dumb to understand the -isystem flag and thus
  299. # borks on warnings in Boost.
  300. if ( USE_DEV_FLAGS AND ( CMAKE_COMPILER_IS_GNUCXX OR COMPILER_IS_CLANG ) AND
  301. NOT CMAKE_GENERATOR_IS_XCODE )
  302. # We want all warnings, and warnings should be treated as errors
  303. set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror" )
  304. endif()
  305. #############################################################################
  306. # We want warnings if we accidentally use C++11 features
  307. # We can't use this warning on FreeBSD because std headers on that OS are dumb.
  308. # See here: https://github.com/Valloric/YouCompleteMe/issues/260
  309. if ( USE_DEV_FLAGS AND COMPILER_IS_CLANG AND NOT CMAKE_GENERATOR_IS_XCODE AND
  310. NOT SYSTEM_IS_FREEBSD )
  311. set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wc++98-compat" )
  312. endif()
  313. #############################################################################
  314. if( SYSTEM_IS_SUNOS )
  315. # SunOS needs this setting for thread support
  316. set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthreads" )
  317. endif()
  318. add_subdirectory( tests )