2012-05-10 00:45:30 -04:00
|
|
|
# Copyright (C) 2011, 2012 Strahinja Val Markovic <val@markovic.io>
|
|
|
|
#
|
|
|
|
# This file is part of YouCompleteMe.
|
|
|
|
#
|
|
|
|
# YouCompleteMe is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# YouCompleteMe is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
cmake_minimum_required( VERSION 2.8 )
|
|
|
|
|
2012-08-04 21:59:22 -04:00
|
|
|
project( ycm_core )
|
2012-05-10 00:45:30 -04:00
|
|
|
|
2013-02-02 15:11:37 -05:00
|
|
|
set( Python_ADDITIONAL_VERSIONS 2.7 2.6 2.5 )
|
2013-02-05 19:48:40 -05:00
|
|
|
find_package( PythonLibs 2.5 REQUIRED )
|
2012-05-10 00:45:30 -04:00
|
|
|
|
2013-02-02 15:22:26 -05:00
|
|
|
if ( NOT PYTHONLIBS_VERSION_STRING VERSION_LESS "3.0.0" )
|
|
|
|
message( FATAL_ERROR
|
|
|
|
"CMake found python3 libs instead of python2 libs. YCM works only with "
|
|
|
|
"python2.\n" )
|
|
|
|
endif()
|
|
|
|
|
2013-01-13 19:39:53 -05:00
|
|
|
option( USE_CLANG_COMPLETER "Use Clang semantic completer for C/C++/ObjC" OFF )
|
|
|
|
option( PATH_TO_LLVM_ROOT "Path to the root of a LLVM+Clang binary distribution" )
|
|
|
|
option( USE_SYSTEM_LIBCLANG "Set to ON to use the system libclang library" OFF )
|
|
|
|
option( EXTERNAL_LIBCLANG_PATH "Path libclang library to use" )
|
|
|
|
|
2013-02-06 14:45:44 -05:00
|
|
|
# Checks for clang 3.2 (LLVM 4.2+)
|
2013-02-07 21:13:55 -05:00
|
|
|
if ( USE_CLANG_COMPLETER AND NOT USE_SYSTEM_LIBCLANG AND NOT PATH_TO_LLVM_ROOT )
|
|
|
|
# Figure out Clang version
|
|
|
|
if ( COMPILER_IS_CLANG )
|
|
|
|
set( CLANG_VERSION ${CMAKE_CXX_COMPILER_VERSION} )
|
2013-02-06 14:45:44 -05:00
|
|
|
else()
|
|
|
|
execute_process( COMMAND clang -dumpversion OUTPUT_VARIABLE CLANG_VERSION )
|
2013-02-07 21:13:55 -05:00
|
|
|
endif()
|
2013-02-07 22:09:53 -05:00
|
|
|
|
2013-02-07 21:13:55 -05:00
|
|
|
if ( CLANG_VERSION VERSION_EQUAL 4.2 OR CLANG_VERSION VERSION_GREATER 4.2 )
|
|
|
|
# Good enough, use it.
|
|
|
|
set( USE_SYSTEM_LIBCLANG ON )
|
2013-02-07 22:09:53 -05:00
|
|
|
message( "System libclang seems good enough, using it." )
|
|
|
|
else()
|
|
|
|
# If the wrong version, or not found, download
|
2013-02-07 22:24:34 -05:00
|
|
|
message( "Downloading Clang 3.2 (system libclang not present or not good enough)" )
|
2013-02-07 22:09:53 -05:00
|
|
|
|
2013-02-07 21:13:55 -05:00
|
|
|
set( CLANG_URL "http://llvm.org/releases/3.2" )
|
2013-02-07 22:09:53 -05:00
|
|
|
|
2013-02-07 21:13:55 -05:00
|
|
|
if ( APPLE )
|
|
|
|
set( CLANG_DIRNAME "clang+llvm-3.2-x86_64-apple-darwin11" )
|
|
|
|
set( CLANG_MD5 "fbdca3b4e8cdaa2352f2aeb038a16532" )
|
|
|
|
else()
|
|
|
|
set( CLANG_DIRNAME "clang+llvm-3.2-x86_64-linux-ubuntu-12.04" )
|
|
|
|
set( CLANG_MD5 "81821e339d7300afb76aca8edab2cf4f" )
|
2013-02-06 14:45:44 -05:00
|
|
|
endif()
|
2013-02-07 22:09:53 -05:00
|
|
|
|
2013-02-07 21:13:55 -05:00
|
|
|
set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.gz" )
|
2013-02-07 22:09:53 -05:00
|
|
|
|
2013-02-07 21:13:55 -05:00
|
|
|
file(
|
|
|
|
DOWNLOAD "${CLANG_URL}/${CLANG_FILENAME}" "./${CLANG_FILENAME}"
|
|
|
|
SHOW_PROGRESS EXPECTED_MD5 "${CLANG_MD5}"
|
|
|
|
)
|
2013-02-07 22:09:53 -05:00
|
|
|
|
2013-02-07 21:13:55 -05:00
|
|
|
execute_process( COMMAND tar -xzf ${CLANG_FILENAME} )
|
2013-02-07 22:09:53 -05:00
|
|
|
|
2013-02-07 21:13:55 -05:00
|
|
|
# And set PATH_TO_LLVM_ROOT
|
|
|
|
set( PATH_TO_LLVM_ROOT "${CMAKE_CURRENT_BINARY_DIR}/../${CLANG_DIRNAME}" )
|
2013-02-06 14:45:44 -05:00
|
|
|
endif()
|
|
|
|
endif()
|
|
|
|
|
2013-01-13 20:33:35 -05:00
|
|
|
if ( PATH_TO_LLVM_ROOT OR USE_SYSTEM_LIBCLANG OR EXTERNAL_LIBCLANG_PATH )
|
|
|
|
set( USE_CLANG_COMPLETER TRUE )
|
|
|
|
endif()
|
|
|
|
|
|
|
|
if ( USE_CLANG_COMPLETER AND
|
|
|
|
NOT PATH_TO_LLVM_ROOT AND
|
|
|
|
NOT USE_SYSTEM_LIBCLANG AND
|
|
|
|
NOT EXTERNAL_LIBCLANG_PATH )
|
2013-01-13 19:39:53 -05:00
|
|
|
message( FATAL_ERROR
|
|
|
|
"You have not specified which libclang to use. You have several options:\n"
|
|
|
|
" 1. Set PATH_TO_LLVM_ROOT to a path to the root of a LLVM+Clang binary "
|
|
|
|
"distribution. You can download such a binary distro from llvm.org. This "
|
|
|
|
"is the recommended approach.\n"
|
|
|
|
" 2. Set USE_SYSTEM_LIBCLANG to ON; this makes YCM search for the system "
|
|
|
|
"version of libclang.\n"
|
|
|
|
" 3. Set EXTERNAL_LIBCLANG_PATH to a path to whatever "
|
|
|
|
"libclang.[so|dylib|dll] you wish to use.\n"
|
|
|
|
"You HAVE to pick one option. See the docs for more information.")
|
|
|
|
endif()
|
|
|
|
|
2013-01-13 23:56:10 -05:00
|
|
|
if ( USE_CLANG_COMPLETER )
|
|
|
|
message( "Using libclang to provide semantic completion for C/C++/ObjC" )
|
|
|
|
else()
|
|
|
|
message( "NOT using libclang, no semantic completion for C/C++/ObjC will be "
|
|
|
|
"available" )
|
|
|
|
endif()
|
|
|
|
|
2013-01-13 19:39:53 -05:00
|
|
|
if ( PATH_TO_LLVM_ROOT )
|
|
|
|
set( CLANG_INCLUDES_DIR "${PATH_TO_LLVM_ROOT}/include" )
|
|
|
|
else()
|
|
|
|
set( CLANG_INCLUDES_DIR "${CMAKE_SOURCE_DIR}/llvm/include" )
|
|
|
|
endif()
|
|
|
|
|
2013-02-05 09:46:48 -05:00
|
|
|
if ( NOT IS_ABSOLUTE "${CLANG_INCLUDES_DIR}" )
|
|
|
|
get_filename_component(CLANG_INCLUDES_DIR
|
|
|
|
"${CMAKE_BINARY_DIR}/${CLANG_INCLUDES_DIR}" ABSOLUTE)
|
|
|
|
endif()
|
|
|
|
|
2013-01-13 19:39:53 -05:00
|
|
|
if ( NOT EXTERNAL_LIBCLANG_PATH AND PATH_TO_LLVM_ROOT )
|
|
|
|
# Need TEMP because find_library does not work with an option variable
|
|
|
|
find_library( TEMP clang
|
|
|
|
PATHS ${PATH_TO_LLVM_ROOT}/lib
|
|
|
|
NO_DEFAULT_PATH )
|
|
|
|
set( EXTERNAL_LIBCLANG_PATH ${TEMP} )
|
|
|
|
endif()
|
|
|
|
|
2012-07-05 00:24:16 -04:00
|
|
|
# This is a workaround for a CMake bug with include_directories(SYSTEM ...)
|
|
|
|
# on Mac OS X. Bug report: http://public.kitware.com/Bug/view.php?id=10837
|
|
|
|
set( CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem " )
|
|
|
|
|
2012-05-10 12:57:07 -04:00
|
|
|
# The SYSTEM flag makes sure that -isystem[header path] is passed to the
|
|
|
|
# compiler instead of the standard -I[header path]. Headers included with
|
|
|
|
# -isystem do not generate warnings (and they shouldn't; e.g. boost warnings are
|
|
|
|
# just noise for us since we won't be changing them).
|
2012-05-10 00:45:30 -04:00
|
|
|
include_directories(
|
2012-05-10 12:57:07 -04:00
|
|
|
SYSTEM
|
2012-05-10 00:45:30 -04:00
|
|
|
${BoostParts_SOURCE_DIR}
|
|
|
|
${PYTHON_INCLUDE_DIRS}
|
2013-01-13 19:39:53 -05:00
|
|
|
${CLANG_INCLUDES_DIR}
|
2012-05-10 00:45:30 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
file( GLOB_RECURSE SOURCES *.h *.cpp )
|
|
|
|
|
|
|
|
# The test sources are a part of a different target, so we remove them
|
|
|
|
# The CMakeFiles cpp file is picked up when the user creates an in-source build,
|
|
|
|
# and we don't want that.
|
|
|
|
file( GLOB_RECURSE to_remove tests/*.h tests/*.cpp CMakeFiles/*.cpp )
|
|
|
|
|
|
|
|
if( to_remove )
|
|
|
|
list( REMOVE_ITEM SOURCES ${to_remove} )
|
|
|
|
endif()
|
|
|
|
|
2013-01-12 19:38:00 -05:00
|
|
|
if ( USE_CLANG_COMPLETER )
|
|
|
|
include_directories(
|
|
|
|
${CMAKE_CURRENT_SOURCE_DIR}
|
|
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/ClangCompleter" )
|
|
|
|
add_definitions( -DUSE_CLANG_COMPLETER )
|
|
|
|
else()
|
2012-08-17 16:32:42 -04:00
|
|
|
file( GLOB_RECURSE to_remove_clang ClangCompleter/*.h ClangCompleter/*.cpp )
|
|
|
|
|
|
|
|
if( to_remove_clang )
|
|
|
|
list( REMOVE_ITEM SOURCES ${to_remove_clang} )
|
|
|
|
endif()
|
|
|
|
endif()
|
|
|
|
|
2012-07-05 00:24:16 -04:00
|
|
|
#############################################################################
|
|
|
|
|
2012-08-04 21:49:21 -04:00
|
|
|
# One can use the system libclang.[so|dylib] like so:
|
|
|
|
# cmake -DUSE_SYSTEM_LIBCLANG=1 [...]
|
|
|
|
# One can also explicitely pick the external libclang.[so|dylib] for use like so:
|
|
|
|
# cmake -DEXTERNAL_LIBCLANG_PATH=/path/to/libclang.so [...]
|
2012-07-29 23:58:04 -04:00
|
|
|
# The final .so we build will then first look in the same dir in which it is
|
|
|
|
# located for libclang.so. This is provided by the rpath = $ORIGIN feature.
|
|
|
|
|
2012-08-04 21:49:21 -04:00
|
|
|
if ( EXTERNAL_LIBCLANG_PATH OR USE_SYSTEM_LIBCLANG )
|
|
|
|
if ( USE_SYSTEM_LIBCLANG )
|
2013-02-09 16:13:16 -05:00
|
|
|
if ( APPLE )
|
|
|
|
set( ENV_LIB_PATHS ENV DYLD_LIBRARY_PATH )
|
|
|
|
elseif ( UNIX )
|
|
|
|
set( ENV_LIB_PATHS ENV LD_LIBRARY_PATH )
|
|
|
|
elseif ( WIN32 )
|
|
|
|
set( ENV_LIB_PATHS ENV PATH )
|
|
|
|
else ()
|
|
|
|
set( ENV_LIB_PATHS "" )
|
|
|
|
endif()
|
2013-01-13 19:39:53 -05:00
|
|
|
# Need TEMP because find_library does not work with an option variable
|
2013-02-09 16:13:16 -05:00
|
|
|
find_library( TEMP clang
|
|
|
|
PATHS
|
|
|
|
${ENV_LIB_PATHS}
|
2013-02-09 14:11:18 -05:00
|
|
|
/usr/lib
|
|
|
|
/usr/lib/llvm )
|
2013-01-13 19:39:53 -05:00
|
|
|
set( EXTERNAL_LIBCLANG_PATH ${TEMP} )
|
2012-08-04 22:37:00 -04:00
|
|
|
else()
|
2013-01-13 15:51:09 -05:00
|
|
|
# For Macs, we do things differently; look further in this file.
|
|
|
|
if ( NOT APPLE )
|
|
|
|
# Setting this to true makes sure that libraries we build will have our rpath
|
|
|
|
# set even without having to do "make install"
|
|
|
|
set( CMAKE_BUILD_WITH_INSTALL_RPATH TRUE )
|
|
|
|
set( CMAKE_INSTALL_RPATH "\$ORIGIN" )
|
|
|
|
endif()
|
2012-08-04 21:49:21 -04:00
|
|
|
endif()
|
|
|
|
|
2012-07-29 23:58:04 -04:00
|
|
|
set( LIBCLANG_TARGET ${EXTERNAL_LIBCLANG_PATH} )
|
|
|
|
message(
|
|
|
|
"Using external libclang: ${EXTERNAL_LIBCLANG_PATH}" )
|
2012-08-17 16:32:42 -04:00
|
|
|
else()
|
|
|
|
set( LIBCLANG_TARGET )
|
2012-07-29 23:58:04 -04:00
|
|
|
endif()
|
|
|
|
|
2012-07-30 17:20:05 -04:00
|
|
|
if ( EXTRA_RPATH )
|
|
|
|
set( CMAKE_INSTALL_RPATH "${EXTRA_RPATH}:${CMAKE_INSTALL_RPATH}" )
|
|
|
|
endif()
|
|
|
|
|
2012-07-29 23:58:04 -04:00
|
|
|
#############################################################################
|
|
|
|
|
2013-01-13 17:38:19 -05:00
|
|
|
# Due to a bug/misconfiguration/stupidity, boost 1.52 and libc++ don't like each
|
|
|
|
# other much: a compilation error "Constexpr function never produces a constant
|
|
|
|
# expression" pops up when trying to compile anything that uses
|
|
|
|
# boost/chrono/duration.hpp (namely boost/thread for us). This is a workaround
|
|
|
|
# that prevents this from happening. Also present in cpp/BoostParts/CMakeLists.txt.
|
2013-01-13 17:40:32 -05:00
|
|
|
# See here for more details: https://svn.boost.org/trac/boost/ticket/7671
|
2013-01-13 17:38:19 -05:00
|
|
|
# TODO: remove this when it's fixed upstream (probably boost 1.53).
|
|
|
|
add_definitions( -DBOOST_THREAD_DONT_USE_CHRONO )
|
|
|
|
|
|
|
|
#############################################################################
|
|
|
|
|
2012-05-10 00:45:30 -04:00
|
|
|
add_library( ${PROJECT_NAME} SHARED
|
|
|
|
${SOURCES}
|
|
|
|
)
|
|
|
|
|
|
|
|
target_link_libraries( ${PROJECT_NAME}
|
|
|
|
BoostParts
|
|
|
|
${PYTHON_LIBRARIES}
|
2012-07-29 23:58:04 -04:00
|
|
|
${LIBCLANG_TARGET}
|
2012-05-10 00:45:30 -04:00
|
|
|
)
|
|
|
|
|
2013-02-06 15:00:07 -05:00
|
|
|
if ( LIBCLANG_TARGET )
|
|
|
|
add_custom_command(
|
|
|
|
TARGET ${PROJECT_NAME}
|
|
|
|
POST_BUILD
|
|
|
|
COMMAND cp "${LIBCLANG_TARGET}" "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
|
|
|
|
)
|
|
|
|
endif()
|
|
|
|
|
2013-01-13 15:51:09 -05:00
|
|
|
#############################################################################
|
|
|
|
|
|
|
|
# Things are a bit different on Macs when using an external libclang.dylib; here
|
|
|
|
# we want to make sure we use @loader_path/libclang.dylib instead of
|
|
|
|
# @rpath/libclang.dylib in the final ycm_core.so. If we use the @rpath version,
|
|
|
|
# then it may load the system libclang which the user explicitely does not want
|
|
|
|
# (otherwise the user would specify USE_SYSTEM_LIBCLANG). With @loader_path, we
|
|
|
|
# make sure that only the libclang.dylib present in the same directory as our
|
|
|
|
# ycm_core.so is used.
|
|
|
|
if ( EXTERNAL_LIBCLANG_PATH AND APPLE )
|
|
|
|
add_custom_command( TARGET ${PROJECT_NAME}
|
|
|
|
POST_BUILD
|
|
|
|
COMMAND install_name_tool
|
|
|
|
"-change"
|
|
|
|
"@rpath/libclang.dylib"
|
|
|
|
"@loader_path/libclang.dylib"
|
|
|
|
"$<TARGET_FILE:${PROJECT_NAME}>"
|
2013-01-13 20:33:35 -05:00
|
|
|
)
|
2013-01-13 15:51:09 -05:00
|
|
|
endif()
|
|
|
|
|
|
|
|
|
2012-07-05 00:24:16 -04:00
|
|
|
#############################################################################
|
|
|
|
|
|
|
|
# We don't want the "lib" prefix, it can screw up python when it tries to search
|
|
|
|
# for our module
|
2012-05-10 00:45:30 -04:00
|
|
|
set_target_properties( ${PROJECT_NAME} PROPERTIES PREFIX "")
|
|
|
|
|
|
|
|
# Even on macs, we want a .so extension instead of a .dylib which is what cmake
|
|
|
|
# would give us by default. Python won't recognize a .dylib as a module, but it
|
|
|
|
# will recognize a .so
|
|
|
|
if ( NOT WIN32 )
|
|
|
|
set_target_properties( ${PROJECT_NAME} PROPERTIES SUFFIX ".so")
|
|
|
|
endif()
|
|
|
|
|
|
|
|
set_target_properties( ${PROJECT_NAME} PROPERTIES
|
2012-07-05 00:24:16 -04:00
|
|
|
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../python )
|
2012-05-10 00:45:30 -04:00
|
|
|
|
2012-07-05 00:50:28 -04:00
|
|
|
#############################################################################
|
2012-05-10 00:45:30 -04:00
|
|
|
|
|
|
|
if( CMAKE_COMPILER_IS_GNUCXX OR COMPILER_IS_CLANG )
|
|
|
|
# We want all warnings, and warnings should be treated as errors
|
2012-07-28 18:27:30 -04:00
|
|
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror" )
|
2012-07-09 16:58:56 -04:00
|
|
|
endif()
|
|
|
|
|
|
|
|
#############################################################################
|
|
|
|
|
|
|
|
# We want warnings if we accidentally use C++11 features
|
2012-08-11 22:00:39 -04:00
|
|
|
if ( COMPILER_IS_CLANG AND NOT CMAKE_GENERATOR_IS_XCODE )
|
2012-07-28 18:27:30 -04:00
|
|
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wc++98-compat" )
|
2012-05-10 00:45:30 -04:00
|
|
|
endif()
|
|
|
|
|
2012-07-05 00:50:28 -04:00
|
|
|
#############################################################################
|
|
|
|
|
2012-05-10 00:45:30 -04:00
|
|
|
add_subdirectory( tests )
|