# This is the top-level CMakeLists.txt file for the Clazy project. # # To build the man page from POD, run 'make man' after CMake (assumes perl is available) # To install the resulting man page, run 'make install' # The man page is not available on Windows. # project(ClangLazy) cmake_minimum_required(VERSION 3.3) include(FeatureSummary) include(GenerateExportHeader) include("GNUInstallDirs") # Version setup set(CLAZY_VERSION_MAJOR "1") set(CLAZY_VERSION_MINOR "4") set(CLAZY_VERSION_PATCH "0") set(CLAZY_VERSION "${CLAZY_VERSION_MAJOR}.${CLAZY_VERSION_MINOR}.${CLAZY_VERSION_PATCH}") set(CLAZY_PRINT_VERSION "${CLAZY_VERSION_MAJOR}.${CLAZY_VERSION_MINOR}") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/cmake) if (NOT CLAZY_BUILD_WITH_CLANG) find_package(Clang 3.9 MODULE REQUIRED) endif() set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) add_definitions(-D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS) add_definitions(-D_GNU_SOURCE -DHAVE_CLANG_CONFIG_H) option(CLAZY_BUILD_UTILS_LIB "Enable this option to build a library so you can reuse clazy's utility functions" OFF) option(CLAZY_AST_MATCHERS_CRASH_WORKAROUND "Disable AST Matchers if being built with clang. See bug #392223" ON) if (CLAZY_AST_MATCHERS_CRASH_WORKAROUND AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") message("Enabling AST Matchers workaround. Consider building with gcc instead. See bug #392223.") add_definitions(-DCLAZY_DISABLE_AST_MATCHERS) endif() if(CLAZY_BUILD_UTILS_LIB) add_definitions(-DCLAZY_BUILD_UTILS_LIB) endif() if(NOT CLAZY_BUILD_WITH_CLANG AND MSVC AND NOT CLANG_LIBRARY_IMPORT) message(FATAL_ERROR "\nOn MSVC you need to pass -DCLANG_LIBRARY_IMPORT=C:/path/to/llvm-build/lib/clang.lib to cmake when building Clazy.\nAlso make sure you've built LLVM with -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON") endif() if(MSVC) # disable trigger-happy warnings from Clang/LLVM headers set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4244 /wd4291 /wd4800 /wd4141 /wd4146 /wd4251") elseif(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-common -Woverloaded-virtual -Wcast-qual -fno-strict-aliasing -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -fno-exceptions -fno-rtti") endif() set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-flat_namespace -Wl,-undefined -Wl,suppress") if(WIN32) add_definitions(-D_CRT_SECURE_NO_WARNINGS) else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") endif() # Look for std::regex support message("Looking for std::regex support...") try_run(RUN_RESULT COMPILE_RESULT ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_LIST_DIR}/.cmake_has_regex_test.cpp) if(RUN_RESULT EQUAL 0) set(HAS_STD_REGEX TRUE) else() set(HAS_STD_REGEX FALSE) add_definitions(-DNO_STD_REGEX) message("old-style-connect check is disabled due to missing std::regex support") message("Suppressions are disabled due to missing std::regex support") endif() include(ClazySources.cmake) include_directories(${CMAKE_BINARY_DIR}) include_directories(${CLANG_INCLUDE_DIRS} ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/src) link_directories("${LLVM_INSTALL_PREFIX}/lib" ${LLVM_LIBRARY_DIRS}) macro(link_to_llvm name is_standalone) foreach(clang_lib ${CLANG_LIBS}) if(MSVC) get_filename_component(LIB_FILENAME ${clang_lib} NAME) if(LIB_FILENAME STREQUAL "clangFrontend.lib") # On MSVC we don't link against clangFrontend.lib, instead we link against clang.exe (via clang.lib) # Otherwise the clazy plugin would have it's own plugin registry and clang wouldn't see it. # This way clazy registers with clang. continue() endif() endif() target_link_libraries(${name} ${clang_lib}) endforeach() foreach(llvm_lib ${LLVM_LIBS}) if(NOT ${is_standalone} AND NOT APPLE AND NOT MINGW AND NOT MSVC) ## Don't link against LLVMSupport, causes: CommandLine Error: Option 'view-background' registered more than once! if (NOT llvm_lib MATCHES ".*LLVMSupport.*") target_link_libraries(${name} ${llvm_lib}) endif() else() target_link_libraries(${name} ${llvm_lib}) endif() endforeach() foreach(user_lib ${USER_LIBS}) target_link_libraries(${name} ${user_lib}) endforeach() foreach(llvm_system_lib ${LLVM_SYSTEM_LIBS}) target_link_libraries(${name} ${llvm_system_lib}) endforeach() if(WIN32) target_link_libraries(${name} version.lib) endif() endmacro() macro(add_clang_plugin name) set(srcs ${ARGN}) add_library(${name} SHARED ${srcs}) if(SYMBOL_FILE) set_target_properties(${name} PROPERTIES LINK_FlAGS "-exported_symbols_list ${SYMBOL_FILE}") endif() link_to_llvm(${name} FALSE) if(MSVC) target_link_libraries(${name} ${CLANG_LIBRARY_IMPORT}) # Link against clang.exe to share the plugin registry endif() if(CLAZY_BUILD_UTILS_LIB) target_link_libraries(${name} clazylib) endif() endmacro() if(CLAZY_BUILD_UTILS_LIB) # clazylib version set(clazylib_VERSION_MAJOR 0) set(clazylib_VERSION_MINOR 1) # Enable the full x.y.z version only for release versions set(clazylib_VERSION_PATCH 0) set(clazylib_VERSION ${clazylib_VERSION_MAJOR}.${clazylib_VERSION_MINOR}) add_library(clazylib SHARED ${CLAZY_LIB_SRC}) link_to_llvm(clazylib FALSE) generate_export_header(clazylib) set_target_properties(clazylib PROPERTIES VERSION ${clazylib_VERSION} SOVERSION ${clazylib_VERSION_MAJOR}) install(TARGETS clazylib EXPORT LibClazyExport RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) endif() set(SYMBOL_FILE Lazy.exports) if (NOT CLAZY_BUILD_WITH_CLANG) add_clang_plugin(ClangLazy ${CLAZY_PLUGIN_SRCS}) set_target_properties(ClangLazy PROPERTIES LINKER_LANGUAGE CXX PREFIX "" ) install(TARGETS ClangLazy RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) set(SHARE_INSTALL_DIR ${CMAKE_INSTALL_DATAROOTDIR} CACHE STRING "Share directory name") if(NOT WIN32) configure_file(${CMAKE_CURRENT_LIST_DIR}/clazy.cmake ${CMAKE_BINARY_DIR}/clazy @ONLY) install(FILES ${CMAKE_BINARY_DIR}/clazy DESTINATION bin PERMISSIONS OWNER_WRITE OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_READ WORLD_EXECUTE) else() install(FILES ${CMAKE_CURRENT_LIST_DIR}/clazy.bat DESTINATION bin PERMISSIONS OWNER_WRITE OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_READ WORLD_EXECUTE) if(MSVC) install(FILES ${CMAKE_CURRENT_LIST_DIR}/clazy-cl.bat DESTINATION bin PERMISSIONS OWNER_WRITE OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_READ WORLD_EXECUTE) endif() endif() # Install the explanation README's set(DOC_INSTALL_DIR ${SHARE_INSTALL_DIR}/doc/clazy) include(${CMAKE_CURRENT_LIST_DIR}/readmes.cmake) install(FILES ${README_LEVEL0_FILES} DESTINATION ${DOC_INSTALL_DIR}/level0) install(FILES ${README_LEVEL1_FILES} DESTINATION ${DOC_INSTALL_DIR}/level1) install(FILES ${README_LEVEL2_FILES} DESTINATION ${DOC_INSTALL_DIR}/level2) install(FILES ${README_LEVEL3_FILES} DESTINATION ${DOC_INSTALL_DIR}/level3) install(FILES ${README_manuallevel_FILES} DESTINATION ${DOC_INSTALL_DIR}/manuallevel) # Install more doc files install(FILES README.md COPYING-LGPL2.txt checks.json DESTINATION ${DOC_INSTALL_DIR}) # Build docs set(MAN_INSTALL_DIR "${SHARE_INSTALL_DIR}/man/man1") add_subdirectory(docs) if(CLAZY_BUILD_UTILS_LIB) # Install public headers set(CLAZY_LIB_INCLUDES src/AccessSpecifierManager.h src/checkbase.h src/checkmanager.h src/clazy_export.h src/clazy_stl.h src/ContextUtils.h src/FixItUtils.h src/HierarchyUtils.h src/LoopUtils.h src/MacroUtils.h src/QtUtils.h src/SuppressionManager.h src/StmtBodyRange.h src/StringUtils.h src/TemplateUtils.h src/TypeUtils.h src/Utils.h src/ClazyContext.h ) install(FILES ${CLAZY_LIB_INCLUDES} DESTINATION include/clazy) endif() # rpath set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" isSystemDir) if("${isSystemDir}" STREQUAL "-1") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") endif("${isSystemDir}" STREQUAL "-1") # Build clazy-standalone add_executable(clazy-standalone ${CLAZY_STANDALONE_SRCS}) if(MSVC) # On MSVC clang-standalone crashes with a meaningless backtrace if linked to ClangLazy.dll target_link_libraries(clazy-standalone clangFrontend) else() target_link_libraries(clazy-standalone ClangLazy) endif() link_to_llvm(clazy-standalone TRUE) install(TARGETS clazy-standalone DESTINATION bin PERMISSIONS OWNER_WRITE OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_READ WORLD_EXECUTE) set(CPACK_PACKAGE_VERSION_MAJOR ${CLAZY_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${CLAZY_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${CLAZY_VERSION_PATCH}) include(CPack) else() set(LLVM_LINK_COMPONENTS Support ) add_clang_library(clazyPlugin ${CLAZY_PLUGIN_SRCS} LINK_LIBS clangFrontend clangDriver clangCodeGen clangSema clangAnalysis clangRewriteFrontend clangRewrite clangAST clangASTMatchers clangParse clangLex clangBasic clangARCMigrate clangEdit clangFrontendTool clangRewrite clangSerialization clangTooling clangStaticAnalyzerCheckers clangStaticAnalyzerCore clangStaticAnalyzerFrontend ) add_executable(clazy-standalone ${CLAZY_STANDALONE_SRCS}) target_link_libraries(clazy-standalone clazyPlugin) install(TARGETS clazy-standalone DESTINATION bin PERMISSIONS OWNER_WRITE OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_READ WORLD_EXECUTE) endif()