标签:
1 # CMake要求的最低版本号 2 cmake_minimum_required( VERSION 2.8 ) 3 4 # 项目名称 5 project( ycm_support_libs ) 6 # 设置客户端lib和服务端lib的变量名称 7 set( CLIENT_LIB "ycm_client_support" ) 8 set( SERVER_LIB "ycm_core" ) 9 10 # 设置Python的版本号变量 11 set( Python_ADDITIONAL_VERSIONS 2.7 2.6 ) 12 # 进行Python包的查找,这里是REQUIRED表示必须 13 find_package( PythonLibs 2.6 REQUIRED ) 14 15 # 如果Python版本号低于3.0.0就进行FATAL_ERROR的出错信息 16 if ( NOT PYTHONLIBS_VERSION_STRING VERSION_LESS "3.0.0" ) 17 message( FATAL_ERROR 18 "CMake found python3 libs instead of python2 libs. YCM works only with " 19 "python2.\n" ) 20 endif() 21 22 # 各种option 23 option( USE_DEV_FLAGS "Use compilation flags meant for YCM developers" OFF ) 24 # 这个变量就是我上文讲到的很关键的一个变量,来判断当前用户需要不需要libclang 25 option( USE_CLANG_COMPLETER "Use Clang semantic completer for C/C++/ObjC" OFF ) 26 # install.sh中的--system-libclang就与这个变量进行交互 27 option( USE_SYSTEM_LIBCLANG "Set to ON to use the system libclang library" OFF ) 28 # YCM作者推荐的用法,在这里直接写入Clang的相关路径 注意这里的CACHE PATH,表示当用户如果命令行 29 # 进行指定,那优先会去读用户的命令行,而不是用这里的set,并且把相关的值写入Cache中 30 set( PATH_TO_LLVM_ROOT "" CACHE PATH "Path to the root of a LLVM+Clang binary distribution" ) 31 # YCM作者推荐的另外一种安装方法,直接将libclang.so全路径写死 32 set( EXTERNAL_LIBCLANG_PATH "" CACHE PATH "Path to the libclang library to use" ) 33 34 # 如果你使用libclang但是没有指定用不用系统的libclang,没有指定llvm_root,没有指定额外的libclang.so,那么就会带你去下载 35 if ( USE_CLANG_COMPLETER AND 36 NOT USE_SYSTEM_LIBCLANG AND 37 NOT PATH_TO_LLVM_ROOT AND 38 NOT EXTERNAL_LIBCLANG_PATH ) 39 message( "Downloading Clang 3.4" ) 40 41 # 这就是llvm官网的3.4下载路径 42 set( CLANG_URL "http://llvm.org/releases/3.4" ) 43 44 # 如果当前客户端是苹果 Mac OS X 45 if ( APPLE ) 46 # 设置Clang的文件夹名称 47 set( CLANG_DIRNAME "clang+llvm-3.4-x86_64-apple-darwin10.9" ) 48 # 设置Clang的MD5校验码 49 set( CLANG_MD5 "4f43ea0e87090ae5e7bec12373ca4927" ) 50 # 设置Clang文件名称为之后加上tar.gz 51 set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.gz" ) 52 else() 53 # 如果是64位平台 54 if ( 64_BIT_PLATFORM ) 55 # 设置Clang的文件夹名称 56 set( CLANG_DIRNAME "clang+llvm-3.4-x86_64-unknown-ubuntu12.04" ) 57 # 设置Clang的MD5校验码 58 set( CLANG_MD5 "6077459d20a7ff412eefc6ce3b9f5c85" ) 59 # 设置Clang文件名称为之后加上tar.gz 60 set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.xz" ) 61 else() 62 # 表示此时为32位的Linux,下载3.3版本 63 message( "No pre-built Clang 3.4 binaries for 32 bit linux, " 64 "downloading Clang 3.3" ) 65 set( CLANG_URL "http://llvm.org/releases/3.3" ) 66 # 设置Clang的文件夹名称 67 set( CLANG_DIRNAME "clang+llvm-3.3-i386-debian6" ) 68 # 设置Clang的MD5校验码 69 set( CLANG_MD5 "415d033b60659433d4631df894673802" ) 70 # 设置Clang文件名称为之后加上tar.gz 71 set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.bz2" ) 72 endif() 73 endif() 74 75 # 下载命令 76 file( 77 DOWNLOAD "${CLANG_URL}/${CLANG_FILENAME}" "./${CLANG_FILENAME}" 78 SHOW_PROGRESS EXPECTED_MD5 "${CLANG_MD5}" 79 ) 80 81 # 文件名正则表达式匹配,进行相应的解压 82 if ( CLANG_FILENAME MATCHES ".+bz2" ) 83 # 执行相关的外部命令 tar 84 execute_process( COMMAND tar -xjf ${CLANG_FILENAME} ) 85 elseif( CLANG_FILENAME MATCHES ".+xz" ) 86 execute_process( COMMAND tar -xJf ${CLANG_FILENAME} ) 87 else() 88 execute_process( COMMAND tar -xzf ${CLANG_FILENAME} ) 89 endif() 90 91 # 设置PATH_TO_LLVM_ROOT的路径为当前CMake二进制路径下的Clang目录 92 set( PATH_TO_LLVM_ROOT "${CMAKE_CURRENT_BINARY_DIR}/../${CLANG_DIRNAME}" ) 93 endif() 94 95 # 如果设置了PATH_TO_LLVM_ROOT或者用户使用系统libclang或者有额外的libclang,就开启USE_CLANG_COMPLETER 96 # 这个变量我上文提过,很关键 97 if ( PATH_TO_LLVM_ROOT OR USE_SYSTEM_LIBCLANG OR EXTERNAL_LIBCLANG_PATH ) 98 set( USE_CLANG_COMPLETER TRUE ) 99 endif() 100 101 # 开始使用这个变量,如果用户确定使用libclang,但是没有root没有系统clang没有额外clang,那么 102 # 进行错误性提示 103 if ( USE_CLANG_COMPLETER AND 104 NOT PATH_TO_LLVM_ROOT AND 105 NOT USE_SYSTEM_LIBCLANG AND 106 NOT EXTERNAL_LIBCLANG_PATH ) 107 message( FATAL_ERROR 108 "You have not specified which libclang to use. You have several options:\n" 109 " 1. Set PATH_TO_LLVM_ROOT to a path to the root of a LLVM+Clang binary " 110 "distribution. You can download such a binary distro from llvm.org. This " 111 "is the recommended approach.\n" 112 " 2. Set USE_SYSTEM_LIBCLANG to ON; this makes YCM search for the system " 113 "version of libclang.\n" 114 " 3. Set EXTERNAL_LIBCLANG_PATH to a path to whatever " 115 "libclang.[so|dylib|dll] you wish to use.\n" 116 "You HAVE to pick one option. See the docs for more information.") 117 endif() 118 119 # 进行用户提醒,提醒用户当前是否使用libclang 120 if ( USE_CLANG_COMPLETER ) 121 message( "Using libclang to provide semantic completion for C/C++/ObjC" ) 122 else() 123 message( "NOT using libclang, no semantic completion for C/C++/ObjC will be " 124 "available" ) 125 endif() 126 127 # 如果设置了root就设置CLANG_INCLUDES_DIR为root下的include 128 # 否则CLANG_INCLUDES_DIR为CMake下llvm/include 129 if ( PATH_TO_LLVM_ROOT ) 130 set( CLANG_INCLUDES_DIR "${PATH_TO_LLVM_ROOT}/include" ) 131 else() 132 set( CLANG_INCLUDES_DIR "${CMAKE_SOURCE_DIR}/llvm/include" ) 133 endif() 134 135 # 如果当前的include路径不是绝对路径 136 if ( NOT IS_ABSOLUTE "${CLANG_INCLUDES_DIR}" ) 137 # 设置它为绝对路径 138 get_filename_component(CLANG_INCLUDES_DIR 139 "${CMAKE_BINARY_DIR}/${CLANG_INCLUDES_DIR}" ABSOLUTE) 140 endif() 141 142 # 如果没有额外的libclang,但是有root 143 if ( NOT EXTERNAL_LIBCLANG_PATH AND PATH_TO_LLVM_ROOT ) 144 if ( MINGW ) # 如果是MINGW 145 # 设置libclang的寻找路径(后面的find_library会去寻找) 146 set( LIBCLANG_SEARCH_PATH "${PATH_TO_LLVM_ROOT}/bin" ) 147 else() 148 set( LIBCLANG_SEARCH_PATH "${PATH_TO_LLVM_ROOT}/lib" ) 149 endif() 150 151 # 这里TEMP会被find_library去寻找clang,和libclang两个so,并且复制路径给TEMP 152 find_library( TEMP NAMES clang libclang 153 PATHS ${LIBCLANG_SEARCH_PATH} 154 NO_DEFAULT_PATH ) 155 156 message("temp is ${TEMP}") 157 # 设置额外的libclang为这个路径 158 set( EXTERNAL_LIBCLANG_PATH ${TEMP} ) 159 endif() 160 161 # 如果当前为苹果,设置额外的flag 162 if ( APPLE ) 163 set( CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem " ) 164 endif() 165 166 # 如果用户使用系统自带的boost 167 if ( USE_SYSTEM_BOOST ) 168 # 进行find boost命令,会用到python,filesystem,system,regex,thread等components 169 find_package( Boost REQUIRED COMPONENTS python filesystem system regex thread ) 170 else() 171 # 使用自己的Boost 172 set( Boost_INCLUDE_DIR ${BoostParts_SOURCE_DIR} ) 173 set( Boost_LIBRARIES BoostParts ) 174 endif() 175 176 # 相关头文件的加入,Boost,Python和Clang 177 include_directories( 178 SYSTEM 179 ${Boost_INCLUDE_DIR} 180 ${PYTHON_INCLUDE_DIRS} 181 ${CLANG_INCLUDES_DIR} 182 ) 183 184 # 全局递归查找h,cpp文件给SERVER_SOURCES 185 file( GLOB_RECURSE SERVER_SOURCES *.h *.cpp ) 186 187 # 全局递归查找测试相关文件 188 file( GLOB_RECURSE to_remove tests/*.h tests/*.cpp CMakeFiles/*.cpp *client* ) 189 190 if( to_remove ) 191 # 学习list相关的REMOVE_ITEM命令 192 list( REMOVE_ITEM SERVER_SOURCES ${to_remove} ) 193 endif() 194 195 # 这里就是这个变量最关键的地方,它会去include并且开启宏 196 if ( USE_CLANG_COMPLETER ) 197 include_directories( 198 ${CMAKE_CURRENT_SOURCE_DIR} 199 "${CMAKE_CURRENT_SOURCE_DIR}/ClangCompleter" ) 200 add_definitions( -DUSE_CLANG_COMPLETER ) 201 else() 202 # 否则的话寻找所有ClangCompleter下的头和源文件进行删除 203 file( GLOB_RECURSE to_remove_clang ClangCompleter/*.h ClangCompleter/*.cpp ) 204 205 if( to_remove_clang ) 206 list( REMOVE_ITEM SERVER_SOURCES ${to_remove_clang} ) 207 endif() 208 endif() 209 210 # 如果用户使用额外的libclang或者使用系统自带的libclang 211 if ( EXTERNAL_LIBCLANG_PATH OR USE_SYSTEM_LIBCLANG ) 212 if ( USE_SYSTEM_LIBCLANG ) # 如果是系统自带 213 if ( APPLE ) 214 set( ENV_LIB_PATHS ENV DYLD_LIBRARY_PATH ) # 将环境变量下的DYLD_LIBRARY_PATH给ENV_LIB_PATHS 215 elseif ( UNIX ) 216 set( ENV_LIB_PATHS ENV LD_LIBRARY_PATH ) # 这也是我之前讲的一定要把你编译的libclang加入到这个环境变量中,因为它会根据这个去寻找 217 elseif ( WIN32 ) 218 set( ENV_LIB_PATHS ENV PATH ) 219 else () 220 set( ENV_LIB_PATHS "" ) 221 endif() 222 file( GLOB SYS_LLVM_PATHS "/usr/lib/llvm*/lib" ) 223 224 # 进行相关的libclang查找,在你之前给它指定的环境变量中 225 find_library( TEMP clang 226 PATHS 227 ${ENV_LIB_PATHS} 228 /usr/lib 229 /usr/lib/llvm 230 ${SYS_LLVM_PATHS} 231 /Library/Developer/CommandLineTools/usr/lib, 232 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib ) 233 # 将寻找到的变量给EXTERNAL_LIBCLANG_PATH 234 set( EXTERNAL_LIBCLANG_PATH ${TEMP} ) 235 else() 236 if ( NOT APPLE ) 237 # 设置相关rpath 238 set( CMAKE_BUILD_WITH_INSTALL_RPATH TRUE ) 239 # 设置make install之后的rpath 240 set( CMAKE_INSTALL_RPATH "\$ORIGIN" ) 241 endif() 242 endif() 243 244 set( LIBCLANG_TARGET "" ) 245 message( 246 "Using external libclang: ${EXTERNAL_LIBCLANG_PATH}" ) 247 message("libclang_target is ${LIBCLANG_TARGET}") 248 else() 249 set( LIBCLANG_TARGET ) 250 endif() 251 252 # 如果有额外的rpath,在这里进行设置 253 if ( EXTRA_RPATH ) 254 set( CMAKE_INSTALL_RPATH "${EXTRA_RPATH}:${CMAKE_INSTALL_RPATH}" ) 255 endif() 256 257 # 如果在Linux下需要额外的rt库 258 if ( UNIX AND NOT APPLE ) 259 set( EXTRA_LIBS rt ) 260 endif() 261 262 # 将目录下所有的h和cpp给CLIENT_SOURCES 263 file( GLOB CLIENT_SOURCES *.h *.cpp ) 264 # 相应SERVER_SPECIFIC赋值 265 file( GLOB SERVER_SPECIFIC *ycm_core* ) 266 267 if( SERVER_SPECIFIC ) 268 # 移除相关CLIEN_SOURCES下的SERVER_SPECIFIC 269 list( REMOVE_ITEM CLIENT_SOURCES ${SERVER_SPECIFIC} ) 270 endif() 271 272 # 创建client的library,并且是动态库 273 add_library( ${CLIENT_LIB} SHARED 274 ${CLIENT_SOURCES} 275 ) 276 277 # 将这个库与之前的rt,Boost,Python进行链接 278 target_link_libraries( ${CLIENT_LIB} 279 ${Boost_LIBRARIES} 280 ${PYTHON_LIBRARIES} 281 ${EXTRA_LIBS} 282 ) 283 284 # 创建server的library,并且是动态库 285 add_library( ${SERVER_LIB} SHARED 286 ${SERVER_SOURCES} 287 ) 288 289 # 将这个库与之前的rt,Boost,Python,libclang,而外的server lib进行链接 290 target_link_libraries( ${SERVER_LIB} 291 ${Boost_LIBRARIES} 292 ${PYTHON_LIBRARIES} 293 ${LIBCLANG_TARGET} 294 ${EXTRA_LIBS} 295 ) 296 297 # 如果定义了LIBCLANG_TARGET 298 if( LIBCLANG_TARGET ) 299 if( NOT WIN32 ) 300 # 在非WIN32情况下增加自定义命令,将libclang.so/dll拷贝到自己目录下 301 add_custom_command( 302 TARGET ${SERVER_LIB} 303 POST_BUILD 304 COMMAND ${CMAKE_COMMAND} -E copy "${LIBCLANG_TARGET}" "$<TARGET_FILE_DIR:${SERVER_LIB}>" 305 ) 306 else() 307 add_custom_command( 308 TARGET ${SERVER_LIB} 309 POST_BUILD 310 COMMAND ${CMAKE_COMMAND} -E copy "${PATH_TO_LLVM_ROOT}/bin/libclang.dll" "$<TARGET_FILE_DIR:${SERVER_LIB}>") 311 endif() 312 endif() 313 314 # 建立依赖关系,表示这个项目需要这两个库共同完成 315 add_custom_target( ${PROJECT_NAME} 316 DEPENDS ${CLIENT_LIB} ${SERVER_LIB} ) 317 318 # Mac下的相关设置,如果是利用rpath的话Mac下还是会去寻找系统库,即使用户显示指定 319 # 这里需要改用@loader_path 320 if ( EXTERNAL_LIBCLANG_PATH AND APPLE ) 321 add_custom_command( TARGET ${SERVER_LIB} 322 POST_BUILD 323 COMMAND install_name_tool 324 "-change" 325 "@rpath/libclang.dylib" 326 "@loader_path/libclang.dylib" 327 "$<TARGET_FILE:${SERVER_LIB}>" 328 ) 329 endif() 330 331 # 将这些库的前缀lib去掉,因为会扰乱Python模块的查找 332 set_target_properties( ${CLIENT_LIB} PROPERTIES PREFIX "") 333 set_target_properties( ${SERVER_LIB} PROPERTIES PREFIX "") 334 335 if ( WIN32 OR CYGWIN ) 336 # 进行Windows下相关库的转移存放 337 set_target_properties( ${CLIENT_LIB} PROPERTIES 338 RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../.. ) 339 set_target_properties( ${SERVER_LIB} PROPERTIES 340 RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../.. ) 341 foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} ) 342 string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) 343 set_target_properties( ${CLIENT_LIB} PROPERTIES 344 RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_SOURCE_DIR}/../.. ) 345 set_target_properties( ${SERVER_LIB} PROPERTIES 346 RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_SOURCE_DIR}/../.. ) 347 endforeach() 348 349 if ( WIN32 ) 350 # 建立后缀名.pyd 351 set_target_properties( ${CLIENT_LIB} PROPERTIES SUFFIX ".pyd") 352 set_target_properties( ${SERVER_LIB} PROPERTIES SUFFIX ".pyd") 353 elseif ( CYGWIN ) 354 # CYGIN下后缀为dll 355 set_target_properties( ${CLIENT_LIB} PROPERTIES SUFFIX ".dll") 356 set_target_properties( ${SERVER_LIB} PROPERTIES SUFFIX ".dll") 357 endif() 358 else() 359 # Mac和Linux下都为.so,虽然Mac下应该默认为.dylib,但Python识别不了dylib,因此这里还是设置成.so 360 set_target_properties( ${CLIENT_LIB} PROPERTIES SUFFIX ".so") 361 set_target_properties( ${SERVER_LIB} PROPERTIES SUFFIX ".so") 362 endif() 363 364 # 设置相关lib的输出目录 365 set_target_properties( ${CLIENT_LIB} PROPERTIES 366 LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../.. ) 367 set_target_properties( ${SERVER_LIB} PROPERTIES 368 LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../.. ) 369 370 if ( USE_DEV_FLAGS AND ( CMAKE_COMPILER_IS_GNUCXX OR COMPILER_IS_CLANG ) AND 371 NOT CMAKE_GENERATOR_IS_XCODE ) 372 # 增加相应flag 373 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror" ) 374 endif() 375 376 # 提出警告在使用C++11特性下 377 if ( USE_DEV_FLAGS AND COMPILER_IS_CLANG AND NOT CMAKE_GENERATOR_IS_XCODE AND 378 NOT SYSTEM_IS_FREEBSD ) 379 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wc++98-compat" ) 380 endif() 381 382 if( SYSTEM_IS_SUNOS ) 383 # SunOS需要-pthreads这个flag才能正常使用 384 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthreads" ) 385 endif() 386 387 # 增加测试子目录tests 388 add_subdirectory( tests )
标签:
原文地址:http://www.cnblogs.com/chris-cp/p/4316449.html