cmake_minimum_required(VERSION 3.5) include(cmake/QtMajorVersion.cmake) # Enable PVS support set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "Enable/Disable output of compile commands during generation.") project("Torrent File Editor") set(EXE_NAME "torrent-file-editor") # Fallback version. Will be used when compiling out of git repository. set(APP_VERSION "1.0.0") set(MACOSX_BUNDLE_EXECUTABLE_NAME "${PROJECT_NAME}") set(MACOSX_BUNDLE_INFO_STRING "Torrent File Editor \${APP_VERSION}. This program is licensed under the GNU GPL.") set(MACOSX_BUNDLE_ICON_FILE "application.icns") set(MACOSX_BUNDLE_GUI_IDENTIFIER "io.github.torrent-file-editor") set(MACOSX_BUNDLE_BUNDLE_NAME "Torrent File Editor") set(MACOSX_BUNDLE_SHORT_VERSION_STRING "\${APP_VERSION}") set(MACOSX_BUNDLE_BUNDLE_VERSION "\${APP_VERSION}") include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # to find FindSparkle.cmake file # Workaround: On Fedora will be executed cmake not mingw32-cmake for building Windows version if(WIN32) # FIXME: this policy fix static .exe liniking with Fedora MinGW cmake_policy(SET CMP0060 OLD) set(UPDATE_VERSION_OUTPUT appversion config.h app.rc appcast.json ) set(UPDATE_VERSION_DEPENDS config.h.in app.rc.in appcast.json.in ) elseif(APPLE) set(UPDATE_VERSION_OUTPUT appversion config.h "Torrent File Editor.app/Contents/Info.plist" ) set(UPDATE_VERSION_DEPENDS config.h.in app.rc.in appcast.json.in "${CMAKE_BINARY_DIR}/MacOSXBundleInfo.plist.in" ) else() set(UPDATE_VERSION_OUTPUT appversion config.h ) set(UPDATE_VERSION_DEPENDS config.h.in ) endif() add_custom_command( OUTPUT ${UPDATE_VERSION_OUTPUT} COMMAND ${CMAKE_COMMAND} -DWIN32=${WIN32} -DAPP_VERSION="v${APP_VERSION}" -P "${CMAKE_SOURCE_DIR}/cmake/Version.cmake" DEPENDS ${UPDATE_VERSION_DEPENDS} COMMENT "Generate config.h" ) add_custom_target(update_version ALL DEPENDS ${UPDATE_VERSION_OUTPUT} ) # Enable C++11 if(QT6_BUILD) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") endif() # Enable all warnings set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic") # If building a release version, make most warnings into errors if(CMAKE_BUILD_TYPE STREQUAL Release OR CMAKE_BUILD_TYPE STREQUAL RelWithDbInfo) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") # Earlier versions of GCC might not recognise certain pragma directives in the C++ code set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=pragmas") # #warning is not an error if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "AppleClang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-#warnings") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=cpp") endif() endif() # Disable automatic conversions from 8-bit strings (char *) to unicode QStrings add_definitions(-DQT_NO_CAST_FROM_ASCII) option(ENABLE_DEBUG_LOG "Show debugging messages" OFF) if(ENABLE_DEBUG_LOG) add_definitions(-DDEBUG) endif() option(DISABLE_DONATION "Do not show donation text in About dialog" OFF) if(DISABLE_DONATION) add_definitions(-DNO_DONATION) endif() if(UNIX) option(ENABLE_NVWA "Check for memory leaks" OFF) else() # Not working correctly on Windows. See https://stackoverflow.com/questions/46025819/global-overload-operator-new-delete-in-mingw set(ENABLE_NVWA OFF) # For Windows by default build single binary without any dependencies option(BUILD_SHARED "Link with shared libraries" ON) endif() if(ENABLE_NVWA) add_definitions( -DENABLE_NVWA -D_DEBUG_NEW_REDEFINE_NEW=0 -D_DEBUG_NEW_ERROR_ACTION= ) endif() if(QT6_BUILD) find_package(QT NAMES Qt6 REQUIRED) find_package(Qt6Core REQUIRED) find_package(Qt6Gui REQUIRED) find_package(Qt6Widgets REQUIRED) find_package(Qt6LinguistTools REQUIRED) find_package(Qt6Core5Compat REQUIRED) macro(QT4_ADD_TRANSLATION) qt6_add_translation(${ARGN}) endmacro() macro(qt4_add_resources) qt6_add_resources(${ARGN}) endmacro() macro(qt4_wrap_cpp) qt6_wrap_cpp(${ARGN}) endmacro() macro(qt4_wrap_ui) qt6_wrap_ui(${ARGN}) endmacro() elseif(QT5_BUILD) find_package(QT NAMES Qt5 REQUIRED) find_package(Qt5Core REQUIRED) find_package(Qt5Gui REQUIRED) find_package(Qt5Widgets REQUIRED) find_package(Qt5LinguistTools REQUIRED) macro(QT4_ADD_TRANSLATION) qt5_add_translation(${ARGN}) endmacro() macro(qt4_add_resources) qt5_add_resources(${ARGN}) endmacro() macro(qt4_wrap_cpp) qt5_wrap_cpp(${ARGN}) endmacro() macro(qt4_wrap_ui) qt5_wrap_ui(${ARGN}) endmacro() else() find_package(Qt4 REQUIRED) add_definitions("'-DQStringLiteral(str)=QString::fromUtf8(\"\" str \"\", sizeof(str) - 1)'") if(WIN32 AND (NOT BUILD_SHARED)) string(REPLACE "-DQT_DLL" "" QT_DEFINITIONS "${QT_DEFINITIONS}") set(QT_DEFINITIONS ${QT_DEFINITIONS} "-DQT_NODLL") endif() include(${QT_USE_FILE}) endif() if(WIN32 AND (NOT BUILD_SHARED)) add_definitions(-DBUILD_STATIC) endif() macro(qt_add_translation ARG1 ARG2) if(QT6_BUILD) qt6_add_translation(${ARG1} ${ARG2}) elseif(QT5_BUILD) qt5_add_translation(${ARG1} ${ARG2}) else() qt4_add_translation(${ARG1} ${ARG2}) endif() endmacro() configure_file(translations.qrc.in translations.qrc COPYONLY) set(LANGS af ar bn cs de en es fi fr he ko hu id it ja nl pl pt ro ru tr uk vi zh_CN zh_TW) foreach(l ${LANGS}) list(APPEND TRANSLATIONS ${CMAKE_SOURCE_DIR}/translations/torrentfileeditor_${l}.ts) endforeach() if(WIN32) if(QT6_BUILD) get_target_property(QT_QMAKE_EXECUTABLE Qt6::qmake IMPORTED_LOCATION) execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS OUTPUT_VARIABLE QT_TRANSLATIONS_DIR OUTPUT_STRIP_TRAILING_WHITESPACE ) elseif(QT5_BUILD) get_target_property(QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS OUTPUT_VARIABLE QT_TRANSLATIONS_DIR OUTPUT_STRIP_TRAILING_WHITESPACE ) endif() set(QT_TRANSLATIONS "") foreach(l ${LANGS}) if(EXISTS "${QT_TRANSLATIONS_DIR}/qt_${l}.qm") set(QT_TRANSLATIONS "${QT_TRANSLATIONS}qt_${l}.qm\n") configure_file("${QT_TRANSLATIONS_DIR}/qt_${l}.qm" "qt_${l}.qm" COPYONLY) endif() endforeach() configure_file(qt_translations.qrc.in qt_translations.qrc) endif() set(HEADERS ${CMAKE_SOURCE_DIR}/application.h ${CMAKE_SOURCE_DIR}/mainwindow.h ${CMAKE_SOURCE_DIR}/datewidget.h ${CMAKE_SOURCE_DIR}/lineeditwidget.h ${CMAKE_SOURCE_DIR}/urledit.h ${CMAKE_SOURCE_DIR}/folderedit.h ${CMAKE_SOURCE_DIR}/aboutdlg.h ${CMAKE_SOURCE_DIR}/bencodemodel.h ${CMAKE_SOURCE_DIR}/bencodedelegate.h ${CMAKE_SOURCE_DIR}/tableview.h ${CMAKE_SOURCE_DIR}/treeview.h ${CMAKE_SOURCE_DIR}/combobox.h ${CMAKE_SOURCE_DIR}/searchdlg.h ${CMAKE_SOURCE_DIR}/plaintextedit.h ) if(WIN32) list(APPEND HEADERS ${CMAKE_SOURCE_DIR}/checkupdate.h ) endif() set(PLAIN_HEADERS ${CMAKE_SOURCE_DIR}/bencode.h ${CMAKE_SOURCE_DIR}/jsonconverter.h ${CMAKE_SOURCE_DIR}/abstracttreemodel.h ${CMAKE_SOURCE_DIR}/abstracttreenode.h ${CMAKE_SOURCE_DIR}/proxystyle.h ${CMAKE_SOURCE_DIR}/json.hpp ${CMAKE_BINARY_DIR}/config.h ) # config.h is a generated file set_source_files_properties(${CMAKE_BINARY_DIR}/config.h PROPERTIES GENERATED TRUE HEADER_FILE_ONLY TRUE ) set(FORMS ${CMAKE_SOURCE_DIR}/mainwindow.ui ${CMAKE_SOURCE_DIR}/aboutdlg.ui ${CMAKE_SOURCE_DIR}/searchdlg.ui ) set(SOURCES ${CMAKE_SOURCE_DIR}/application.cpp ${CMAKE_SOURCE_DIR}/jsonconverter.cpp ${CMAKE_SOURCE_DIR}/main.cpp ${CMAKE_SOURCE_DIR}/mainwindow.cpp ${CMAKE_SOURCE_DIR}/bencode.cpp ${CMAKE_SOURCE_DIR}/datewidget.cpp ${CMAKE_SOURCE_DIR}/lineeditwidget.cpp ${CMAKE_SOURCE_DIR}/urledit.cpp ${CMAKE_SOURCE_DIR}/folderedit.cpp ${CMAKE_SOURCE_DIR}/aboutdlg.cpp ${CMAKE_SOURCE_DIR}/bencodemodel.cpp ${CMAKE_SOURCE_DIR}/bencodedelegate.cpp ${CMAKE_SOURCE_DIR}/proxystyle.cpp ${CMAKE_SOURCE_DIR}/tableview.cpp ${CMAKE_SOURCE_DIR}/treeview.cpp ${CMAKE_SOURCE_DIR}/combobox.cpp ${CMAKE_SOURCE_DIR}/searchdlg.cpp ${CMAKE_SOURCE_DIR}/plaintextedit.cpp ) if(WIN32) list(APPEND SOURCES ${CMAKE_SOURCE_DIR}/checkupdate.cpp ) endif() if(APPLE) list(APPEND SOURCES ${CMAKE_SOURCE_DIR}/cocoainitializer.mm ${CMAKE_SOURCE_DIR}/sparkleautoupdater.mm ) find_package(Sparkle REQUIRED) include_directories(${SPARKLE_INCLUDE_DIR}) endif() set(RESOURCES ${CMAKE_BINARY_DIR}/translations.qrc resources.qrc ) add_custom_target(lupdate) foreach(l ${LANGS}) add_custom_target( lupdate_${l} COMMAND Qt${QT_VERSION_MAJOR}::lupdate -no-obsolete -no-recursive ${CMAKE_SOURCE_DIR} -ts "torrentfileeditor_${l}.ts" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/translations" COMMENT "Updating .ts files" ) add_custom_target( fix_${l} COMMAND "xmllint" "--noblanks" "torrentfileeditor_${l}.ts" "--output" "torrentfileeditor_${l}.ts" COMMAND "perl" "-pi" "-e" "s|QLineEdit.*?||g" "torrentfileeditor_${l}.ts" COMMAND "xmllint" "--format" "torrentfileeditor_${l}.ts" "--output" "torrentfileeditor_${l}.ts" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/translations" VERBATIM COMMENT "Fix .ts files formating" ) add_dependencies(fix_${l} lupdate_${l}) add_dependencies(lupdate fix_${l}) endforeach() if(WIN32) list(APPEND RESOURCES "${CMAKE_BINARY_DIR}/qt_translations.qrc") endif() QT4_ADD_TRANSLATION(QM ${TRANSLATIONS}) qt4_add_resources(QRC_SOURCES ${RESOURCES}) qt4_wrap_cpp(MOC_SOURCES ${HEADERS}) qt4_wrap_ui(UI_SOURCES ${FORMS}) if(WIN32) if(NOT BUILD_SHARED) set(START_STATIC -Wl,-Bstatic) set(END_STATIC z jpeg png tiff stdc++ -lwinpthread -Wl,-Bdynamic) if(QT5_BUILD) find_package(PkgConfig REQUIRED) pkg_check_modules(QT5_PKGCONFIG Qt5Widgets) set(EXTRA_LIBS Qt5::QWindowsIntegrationPlugin Qt5::QICOPlugin Qt5::QJpegPlugin Qt5::QGifPlugin Qt5::QWindowsVistaStylePlugin ${QT5_PKGCONFIG_LDFLAGS} Qt5AccessibilitySupport Qt5EventDispatcherSupport Qt5FontDatabaseSupport Qt5ThemeSupport jpeg ) endif() endif() list(APPEND EXTRA_LIBS ws2_32 winmm imm32 wininet) # resource compilation for MinGW add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/app.o DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/app.rc COMMENT "Building RC object app.o" COMMAND ${CMAKE_RC_COMPILER} -I${CMAKE_CURRENT_SOURCE_DIR} -i${CMAKE_CURRENT_BINARY_DIR}/app.rc -o ${CMAKE_CURRENT_BINARY_DIR}/app.o ) set(SOURCES ${SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/app.o) endif() if(ENABLE_NVWA) add_subdirectory(nvwa) set(NWVA_TARGET $) if(UNIX AND NOT APPLE) set(NWVA_LIBS -ldl) elseif(WIN32) set(NWVA_LIBS -ldbghelp) endif() endif() add_executable(${EXE_NAME} WIN32 MACOSX_BUNDLE ${QM} ${HEADERS} ${PLAIN_HEADERS} ${SOURCES} ${MOC_SOURCES} ${QRC_SOURCES} ${UI_SOURCES} ${NWVA_TARGET}) add_dependencies(${EXE_NAME} update_version) if(QT6_BUILD) target_link_libraries(${EXE_NAME} ${START_STATIC} Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Core5Compat ${END_STATIC} ${EXTRA_LIBS} ${NWVA_LIBS}) elseif(QT5_BUILD) target_link_libraries(${EXE_NAME} ${START_STATIC} Qt5::Core Qt5::Gui Qt5::Widgets ${END_STATIC} ${EXTRA_LIBS} ${NWVA_LIBS}) else() target_link_libraries(${EXE_NAME} ${START_STATIC} ${QT_LIBRARIES} ${END_STATIC} ${EXTRA_LIBS} ${NWVA_LIBS}) endif() if(APPLE) target_link_libraries(${EXE_NAME} ${SPARKLE_LIBRARY} "-framework AppKit") endif() if(UNIX AND NOT APPLE) install(TARGETS ${EXE_NAME} DESTINATION bin) install(FILES torrent-file-editor.desktop DESTINATION share/applications) install(FILES torrent-file-editor.appdata.xml DESTINATION share/appdata) install(FILES icons/app_16.png DESTINATION share/icons/hicolor/16x16/apps RENAME torrent-file-editor.png) install(FILES icons/app_32.png DESTINATION share/icons/hicolor/32x32/apps RENAME torrent-file-editor.png) install(FILES icons/app_48.png DESTINATION share/icons/hicolor/48x48/apps RENAME torrent-file-editor.png) install(FILES icons/app_64.png DESTINATION share/icons/hicolor/64x64/apps RENAME torrent-file-editor.png) install(FILES icons/app_128.png DESTINATION share/icons/hicolor/128x128/apps RENAME torrent-file-editor.png) install(FILES icons/app_256.png DESTINATION share/icons/hicolor/256x256/apps RENAME torrent-file-editor.png) endif() if(APPLE) install(TARGETS ${EXE_NAME} BUNDLE DESTINATION . COMPONENT Runtime) set_target_properties(torrent-file-editor PROPERTIES OUTPUT_NAME "${PROJECT_NAME}" ) configure_file(MacOSXBundleInfo.plist.in "${CMAKE_BINARY_DIR}/MacOSXBundleInfo.plist.in") # Install app icon install(FILES icons/application.icns DESTINATION "${PROJECT_NAME}.app/Contents/Resources" COMPONENT Runtime) # Install needed Qt plugins by copying each pluging separately find_package(Qt5PrintSupport REQUIRED) set(PLATFORM_PLUGINS Qt5::QCocoaIntegrationPlugin) set(IMAGE_PLUGINS Qt5::QICNSPlugin) set(PRINTSUPPORT_PLUGINS Qt5::QCocoaPrinterSupportPlugin) set(PLUGINS_DEST_PATH "${PROJECT_NAME}.app/Contents/PlugIns") set(TRANSLATIONS_DEST_PATH "${PROJECT_NAME}.app/Contents/Resources/translations") foreach(plugin ${PLATFORM_PLUGINS}) get_target_property(_loc ${plugin} LOCATION) install(FILES "${_loc}" DESTINATION ${PLUGINS_DEST_PATH}/platforms/ COMPONENT Runtime) endforeach() foreach(plugin ${IMAGE_PLUGINS}) get_target_property(_loc ${plugin} LOCATION) install(FILES "${_loc}" DESTINATION ${PLUGINS_DEST_PATH}/imageformats/ COMPONENT Runtime) endforeach() foreach(plugin ${PRINTSUPPORT_PLUGINS}) get_target_property(_loc ${plugin} LOCATION) install(FILES "${_loc}" DESTINATION ${PLUGINS_DEST_PATH}/printsupport/ COMPONENT Runtime) endforeach() if(TARGET Qt5::QMacStylePlugin) get_target_property(_loc Qt5::QMacStylePlugin LOCATION) install(FILES "${_loc}" DESTINATION ${PLUGINS_DEST_PATH}/styles/ COMPONENT Runtime) endif() # Install public key for Sparkle Updater install(FILES "dsa_pub.pem" DESTINATION "${PROJECT_NAME}.app/Contents/Resources" COMPONENT Runtime) # Install qt.conf file # Qt can't find plugins in standard path on case-sensetive file system # Write correct case-sensetive folder name in qt.conf file install(FILES "qt.conf" DESTINATION "${PROJECT_NAME}.app/Contents/Resources" COMPONENT Runtime) # Now the work of copying dependencies into the bundle/package # The quotes are escaped and variables to use at install time have their $ escaped # An alternative is the do a configure_file() on a script and use install(SCRIPT ...). # Note that the image plugins depend on QtSvg and QtXml, and it got those copied # over. get_target_property(QT_LIBRARY_DIR Qt5::Core LOCATION) while(NOT ${QT_LIBRARY_DIR} MATCHES "lib$") get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} DIRECTORY) endwhile() foreach(l ${LANGS}) # In Qt lacks some languages if(EXISTS "${QT_LIBRARY_DIR}/../translations/qtbase_${l}.qm") install(FILES "${QT_LIBRARY_DIR}/../translations/qtbase_${l}.qm" DESTINATION ${TRANSLATIONS_DEST_PATH} COMPONENT Runtime) endif() endforeach() SET(APPS "\${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app") install(CODE " file(GLOB_RECURSE QTPLUGINS \"\${CMAKE_INSTALL_PREFIX}/${PLUGINS_DEST_PATH}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\" ) include(BundleUtilities) fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR};${SPARKLE_LIBRARY}\") file(GLOB BINARIES \"${APPS}/Contents/Frameworks/*.framework\" \"${APPS}/Contents/Frameworks/Sparkle.framework/Resources/Autoupdate.app\" \"${APPS}/Contents/MacOS/*.dylib\" \"${APPS}/Contents/PlugIns/*.dylib\" \"${APPS}/Contents/PlugIns/*/*.dylib\" ) execute_process(COMMAND codesign --deep -f -s \"Ivan Romanov\" \${BINARIES} \"${APPS}\" WORKING_DIRECTORY \"${APPS}\") " COMPONENT Runtime ) # To Create a package, one can run "cpack -G DragNDrop CPackConfig.cmake" on Mac OS X # where CPackConfig.cmake is created by including CPack # And then there's ways to customize this as well set(CPACK_GENERATOR "DragNDrop") set(CPACK_DMG_VOLUME_NAME ${PROJECT_NAME}) set(CPACK_DMG_DS_STORE_SETUP_SCRIPT "${CMAKE_SOURCE_DIR}/CMakeDMGSetup.scpt") set(CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/DS_Background.png") include(CPack) add_custom_target("dmg" COMMAND ${CMAKE_COMMAND} -DPROJECT_NAME=${PROJECT_NAME} -DAPP_NAME=${EXE_NAME} -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Dmg.cmake" DEPENDS "${EXE_NAME}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" ) endif() # collect_info_files function # Takes collect_info_files - list of non-source files to look for # Returns INFO_FILES with all files found from the input list. # Based on macro posted here # http://lists.qt-project.org/pipermail/qt-creator/2012-August/001191.html [^] function(collect_info_files) list(APPEND _all_found) foreach(_it ${ARGN}) if(NOT IS_DIRECTORY ${_it}) get_filename_component(_path ${_it} ABSOLUTE) if(EXISTS ${_path}) list(APPEND _all_found ${_it}) if(NOT ${_it} MATCHES "^/\\\\..*$;~$") set_source_files_properties(${_it} PROPERTIES HEADER_FILE_ONLY TRUE) endif() endif() endif() endforeach() set(INFO_FILES ${_all_found} PARENT_SCOPE) endfunction() # List all non-source code files (documents, configuration files, etc.) set(OTHER_FILES .gitignore .travis.yml CMakeDMGSetup.scpt PVS-Studio.cfg Plog-Converter.cfg README.md appcast.json.in appcast.xml.in build.sh build.sh cmake/Dmg.cmake cmake/Version.cmake cmake/Version.cmake qt_translations.qrc.in translations.qrc.in update-translations.sh ) # Collect all existing files and configure as non-sources. collect_info_files(${OTHER_FILES}) # Create dummy target/project for an IDE with documents attached add_custom_target(docs SOURCES ${INFO_FILES}) if(CMAKE_EXPORT_COMPILE_COMMANDS) if(NOT PVS_ANALYZER) find_program(PVS_ANALYZER pvs-studio-analyzer) find_program(PVS_CONVERTER plog-converter) if(PVS_ANALYZER AND PVS_CONVERTER) message(STATUS "Found PVS-Studio: ${PVS_ANALYZER}") endif() endif() mark_as_advanced(PVS_ANALYZER PVS_CONVERTER) if(PVS_ANALYZER AND PVS_CONVERTER) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(PVS_PREPROCESSOR "clang") else() set(PVS_PREPROCESSOR "gcc") endif() include(ProcessorCount) ProcessorCount(N) add_custom_target(analyze COMMAND ${PVS_ANALYZER} analyze -o PVS-Studio.log.raw --preprocessor=${PVS_PREPROCESSOR} -e ${CMAKE_BINARY_DIR} -c ${CMAKE_SOURCE_DIR}/PVS-Studio.cfg -j ${N} COMMAND ${PVS_CONVERTER} -t errorfile PVS-Studio.log.raw -o PVS-Studio.log -s ${CMAKE_SOURCE_DIR}/Plog-Converter.cfg COMMAND rm -f PVS-Studio.log.raw COMMAND sed -i "'/^www\\.viva64\\.com/d'" PVS-Studio.log COMMAND cat PVS-Studio.log 1>&2 COMMENT "Analyze ${EXE_NAME}" DEPENDS ${EXE_NAME} ) endif() endif()