Clang-Tidy CMake VisualStudio - c++

How to execute clang-tidy with CMake in Visual studio just as single target?
1.OS: Windows
2.IDE: Visual Studio 2022
3.LLVM: Installed
4.Clang-Tidy: 15.0.6
5.Ninja: Installed (and added to path)
CMakeLists.txt
add_custom_target(tidy
COMMAND ${CMAKE_COMMAND} -DCLANG_TIDY_EXECUTABLE=${CLANG_TIDY_EXECUTABLE} -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} -P ./cmake/Tidy.cmake
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} VERBATIM)
cmake/Tidy.cmake
find_program(CLANG_TIDY_EXECUTABLE "clang-tidy")
execute_process(COMMAND run-clang-tidy -clang-tidy-binary ${CLANG_TIDY_EXECUTABLE} -p ${PROJECT_BINARY_DIR} RESULTS_VARIABLE EXIT_CODE)
if(NOT EXIT_CODE STREQUAL 0)
message(FATAL_ERROR "Analysis failed")
endif()
Output:
Analysis failed

Related

CMake cannot find Conan package "gRPC"

I have prepared a simple reproductive draft of my problem.
conanfile.txt:
[requires]
grpc/1.48.0
[generators]
cmake_paths
CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 3.18.3)
PROJECT(GRPC_FIND_PACKAGE_TEST)
# Default values
IF(NOT CMAKE_BUILD_TYPE
OR
(
NOT ${CMAKE_BUILD_TYPE} MATCHES "Debug"
AND NOT ${CMAKE_BUILD_TYPE} MATCHES "Release"
)
)
#SET(CMAKE_BUILD_TYPE Debug)
MESSAGE(FATAL_ERROR "Build type is unknown!")
ENDIF()
SET(BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}")
# Conan initialization command
SET(CONAN_INITIALIZATION_COMMAND
conan install "${CMAKE_CURRENT_LIST_DIR}" -s build_type=${CMAKE_BUILD_TYPE} --build=missing
)
# Executes conan initialization command
EXECUTE_PROCESS(
COMMAND ${CONAN_INITIALIZATION_COMMAND}
WORKING_DIRECTORY "${BUILD_DIR}"
RESULT_VARIABLE CMD_RESULT_CODE
ERROR_VARIABLE CMD_ERROR
COMMAND_ECHO STDOUT
)
INCLUDE(${BUILD_DIR}/conan_paths.cmake)
# Find Protobuf installation
# Looks for protobuf-config.cmake file installed by Protobuf's cmake installation.
set(protobuf_MODULE_COMPATIBLE TRUE)
find_package(Protobuf REQUIRED)
message(STATUS "Using protobuf ${Protobuf_VERSION}")
# Find gRPC installation
# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation.
find_package(gRPC CONFIG REQUIRED)
message(STATUS "Using gRPC ${gRPC_VERSION}")
Issue
For some reason, FIND_PACKAGE cannot find the grpc package.
I had also error with:
find_package(Protobuf CONFIG REQUIRED)
I had to remove "CONFIG" and it started detecting this package properly.
What's going on? what's the problem?

Can't compile Asio with conan macos

I'm trying to build a C++ project with Conan to download the libraries, but the problem is that I can't build it since Asio throw error on it's own functions.
Here is the result of the build : https://pastebin.com/WQ2bFHvm
I'm going to share you my configuration :
//Conan Profile
[settings]
arch=x86_64
arch_build=x86_64
build_type=Debug
compiler=apple-clang
compiler.libcxx=libc++
compiler.version=12.0
os=Macos
os_build=Macos
[options]
[build_requires]
[env]
conanfile.txt
//conanfile.txt
[requires]
asio/1.20.0
boost/1.77.0
libbacktrace/cci.20210118
sfml/2.5.1#bincrafters/stable
[options]
libstd:compiler.libcxx=libstdc++11
[generators]
cmake
cmake_find_package
CMakeLists.txt :
//CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(R-Type)
# conan
set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
include(build/conanbuildinfo.cmake)
conan_basic_setup()
# Package
find_package(asio 1.20.0 REQUIRED)
find_package(Boost 1.77.0 REQUIRED)
find_package(SFML 2.5.1 COMPONENTS graphics window system REQUIRED)
# .cmake files
include(./rtype/client/build.cmake)
include(./rtype/server/build.cmake)
include(./ecs-engine/build.cmake)
include(./graphics/build.cmake)
set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
include(build/conanbuildinfo.cmake)
conan_basic_setup()
include_directories(${CMAKE_INCLUDE_PATH})
find_package(asio 1.19.2 REQUIRED)
find_package(SFML 2.5.1 COMPONENTS window graphics system audio REQUIRED)
set(ECS_ENGINE_DIR ./ecs-engine/)
set(GRAPHICS_DIR ./graphics/)
set(RTYPE_CLIENT_DIR ./rtype/client/)
set(RTYPE_SERVER_DIR ./rtype/server/)
build_engine()
set(ECS_ENGINE_INCLUDES INCLUDE_DIR)
build_graphics()
build_server()
build_client()
Server cmake build :
//build.cmake
set(RTYPE_SERVER_EXECUTABLE rtype_server)
set(RTYPE_SERVER_DIR ./rtype/server/)
macro(build_server)
set(SOURCE_DIR ${RTYPE_SERVER_DIR}/sources)
set(INCLUDE_DIR ${RTYPE_SERVER_DIR}/includes)
include_directories(${CMAKE_INCLUDE_PATH} ${INCLUDE_DIR})
add_executable(${RTYPE_SERVER_EXECUTABLE}
${SOURCE_DIR}/main.cpp
${SOURCE_DIR}/UDP.cpp
)
target_link_libraries(${RTYPE_SERVER_EXECUTABLE} ${CONAN_LIBS})
endmacro()
And finally here are the commands I run to build the project :
rm -rf build
mkdir build && cd build
conan install .. --build=missing
cmake .. -G "Unix Makefiles"
cmake --build .
I've tried to install the libraries locally but it does not work, do you guys have any idea on what I'm missing ?

Deploy icu libraries when linking a cmake project with Qt5

I've the following CMakeLists.txt for creating a little application:
cmake_minimum_required (VERSION 3.5.0)
project (sampleapp)
# Setting project flags
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib)
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib)
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/bin)
set (CMAKE_INCLUDE_CURRENT_DIR ON)
set (CMAKE_AUTOMOC ON)
# Finding needed packages
find_package (Qt5Widgets REQUIRED)
find_package (Qt5Core REQUIRED)
find_package (Qt5Gui REQUIRED)
# Setting project files
include_directories (${CMAKE_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE PROJECT_SRC *.cpp)
# Creating project
add_executable(${PROJECT_NAME} ${PROJECT_SRC})
# Linking dependencies
target_link_libraries (${PROJECT_NAME} somelibrary Qt5::Widgets Qt5::Gui Qt5::Core)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:${PROJECT_NAME}>)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Gui> $<TARGET_FILE_DIR:${PROJECT_NAME}>)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:${PROJECT_NAME}>)
When I run it and then build the application the Qt dlls are copied into target folder. In particular I copy:
Qt5Core.dll
Qt5Gui.dll
Qt5Widgets.dll
When I run the application it does not start anyway because the ICU libraries needed for Qt are not copied. When I start the application, Windows tells me that following libraries are missing:
icuin53.dll
icuuc53.dll
If I copy these libraries manually from Qt insallation folder it works (ok, I've an error regarding "platform plugins windows" missing but it's another story).
Is there a way to copy the icu libraries in a standard way, like the post build commands that I'm using for copying libraries? Or what's the best way to copy them in a transparent way, if possible (CMake can know what are dependencies of Qt and copy them where Qt are needed)?
Instead of copying each dll by hand, you can install all Qt dependencies using windeployqt, the tool provided with Qt for deployment on Windows.
You can first declare windeployqt as an imported executable:
find_package(Qt5
# ...
)
if(Qt5_FOUND AND WIN32 AND TARGET Qt5::qmake AND NOT TARGET Qt5::windeployqt)
get_target_property(_qt5_qmake_location
Qt5::qmake IMPORTED_LOCATION
)
execute_process(
COMMAND "${_qt5_qmake_location}" -query QT_INSTALL_PREFIX
RESULT_VARIABLE return_code
OUTPUT_VARIABLE qt5_install_prefix
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(imported_location "${qt5_install_prefix}/bin/windeployqt.exe")
if(EXISTS ${imported_location})
add_executable(Qt5::windeployqt IMPORTED)
set_target_properties(Qt5::windeployqt PROPERTIES
IMPORTED_LOCATION ${imported_location}
)
endif()
endif()
Now the imported executable can be used as follows:
add_executable(foo
# ...
)
if(TARGET Qt5::windeployqt)
add_custom_command(TARGET foo
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/windeployqt"
COMMAND set PATH=%PATH%$<SEMICOLON>${qt5_install_prefix}/bin
COMMAND Qt5::windeployqt --dir "${CMAKE_CURRENT_BINARY_DIR}/windeployqt" "$<TARGET_FILE:foo>"
)
install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/windeployqt/"
DESTINATION ${FOO_INSTALL_RUNTIME_DESTINATION}
)
endif()

Building Google glog with CMake on Linux

I want to build Google glog with CMake as part of bigger project (solution, in words of Visual Studio). What I want to have as a result:
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug
-DCMAKE_INSTALL_PREFIX:PATH=xxx {MAIN CMakeLists.txt location}
cmake --build . --target install --config Debug
will build solution in Debug configuration and install files to xxx folder.
Ok, glog is sub project of main solution:
add_subdirectory(third_party/glog_0.3.4)
On Windows everything is ok (see CMakeLists.txt): everything works as expected.
To build glog on Linux, I need to configure .h.in files too (among other work). CMake configure_file does not works: I have .h files but they contain #undef's only. But glog's ./configure works fine, so I found that ExternalProject_Add() may help:
if(UNIX)
include(ExternalProject)
ExternalProject_Add(glog
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/configure
CMAKE_GENERATOR 'Unix Makefiles'
BUILD_COMMAND ${MAKE})
endif()
And cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX:PATH=xxx . works fine, but cmake --build . --target install --config Debug will give me:
make: *** No rule to make target 'install'. Stop.
If I invoke cmake --build . --config Debug, then it will build and install glog to /usr/local/lib. Next try:
if(UNIX)
include(ExternalProject)
get_filename_component(glog_absolute_install_dir ${CMAKE_INSTALL_PREFIX} ABSOLUTE)
ExternalProject_Add(glog
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/configure --prefix=${glog_absolute_install_dir}
CMAKE_GENERATOR 'Unix Makefiles'
BUILD_COMMAND ${MAKE}
INSTALL_DIR ${glog_absolute_install_dir}
INSTALL_COMMAND "${MAKE}")
endif()
will not install files to xxx and just build it to glog-prefix/src/glog-build/.
Ok, I have no idea how to make it work.. And how to
specify install dir
lib build type (static/shared)
configure type (Debug/Release) - not sure that now it works
On Windows, according to glog's documentation, for 2nd case I do next:
add_library(${lib_name} ${lib_type} ${src_files})
if(build_shared_lib)
add_definitions(-DLIBGLOG_EXPORTS)
else()
add_definitions(-DGOOGLE_GLOG_DLL_DECL=)
endif()
Thanks for any help
I will show you by example, the below is my project structure:
The file FindGLog.cmake in the directory cmake is used to find glog, it contents :
# - Try to find Glog
#
# The following variables are optionally searched for defaults
# GLOG_ROOT_DIR: Base directory where all GLOG components are found
#
# The following are set after configuration is done:
# GLOG_FOUND
# GLOG_INCLUDE_DIRS
# GLOG_LIBRARIES
include(FindPackageHandleStandardArgs)
if (NOT DEFINED GLOG_ROOT)
message("set GLOG_ROOT========================")
set (GLOG_ROOT /usr /usr/local /usr/include/)
endif (NOT DEFINED GLOG_ROOT)
#set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog")
find_path(GLOG_INCLUDE_DIR glog/logging.h
PATHS
${GLOG_ROOT_DIR}
PATH_SUFFIXES
src)
find_library(GLOG_LIBRARY glog libglog
PATHS
${GLOG_ROOT_DIR}
PATH_SUFFIXES
.libs
lib
lib64)
find_package_handle_standard_args(GLOG DEFAULT_MSG
GLOG_INCLUDE_DIR GLOG_LIBRARY)
if(GLOG_FOUND)
set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR})
set(GLOG_LIBRARIES ${GLOG_LIBRARY})
message("GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIRS}===========")
message("GLOG_LIBRARY ${GLOG_LIBRARY}===========")
endif()
The main CMakeLists.txt use the above FindGLog.cmake to find glog:
cmake_minimum_required(VERSION 3.5)
project(my_caffe)
set(CMAKE_CXX_STANDARD 11)
# find glog
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
find_package(GLog REQUIRED)
set(SOURCE_FILES main.cpp)
add_executable(my_caffe_test ${SOURCE_FILES})
# link glog
target_link_libraries(my_caffe_test
${GLOG_LIBRARIES}
)
cited from:https://davidstutz.de/running-google-glog-on-travis-ci/
Nowadays (presumably this will be in glog release 0.3.5), there is a CMakeLists.txt included with glog, so no longer any need for ExternalProject.

CMakelists.txt is ridiculously complex to get windows and mac to work, is there a better way?

I have been getting a CMakeLists.txt together to compile what right now is an SFML sample in preparation to do my own source code. It feels like a hack, even though it works (Mac Makefile, VS nmake, VS solution) right now.
The main repository is at https://github.com/iaefai/Spider-Fish/
Any suggestions are welcome.
cmake_minimum_required(VERSION 2.8)
PROJECT(Spider-Fish)
FIND_PACKAGE(OpenGL REQUIRED)
FIND_PACKAGE(SFML REQUIRED)
IF (WIN32)
# Windows
link_directories(${SFML_INCLUDE_DIR}/../lib)
set(RESOURCE_HANDLER ${CMAKE_CURRENT_SOURCE_DIR}/src/windows/resources.cpp)
# link_directories(${FIND_SFML_LIB_PATHS})
ELSEIF(APPLE)
# Mac
SET(RESOURCE_HANDLER ${CMAKE_CURRENT_SOURCE_DIR}/src/mac/resources.mm)
SET(MACOSX_BUNDLE_GUI_IDENTIFER "com.iaefai.Spider-Fish")
SET(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME})
if (NOT CMAKE_OSX_ARCHITECTURES)
set(CMAKE_OSX_ARCHITECTURES "i386;x86_64"
CACHE STRING "Build architectures for OSX" FORCE)
endif()
if(EXISTS /Developer/SDKs/MacOSX10.7.sdk)
set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.7.sdk"
CACHE STRING "Defaults to 10.7" FORCE)
else()
# use default SDK
endif()
find_library(COCOA_LIB Cocoa)
SET(EXTRA_LIBS ${COCOA_LIB} ${OPENGL_LIBRARIES})
ELSE()
# Linux // Assumed??
ENDIF()
#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include})
include_directories(${SFML_INCLUDE_DIR})
SET(RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/assets/background.jpg
${CMAKE_CURRENT_SOURCE_DIR}/assets/blur.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/colorize.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/edge.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/fisheye.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/nothing.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/pixelate.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/sansation.ttf
${CMAKE_CURRENT_SOURCE_DIR}/assets/sprite.png
${CMAKE_CURRENT_SOURCE_DIR}/assets/wave.jpg
${CMAKE_CURRENT_SOURCE_DIR}/assets/wave.sfx)
SET (SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/Shader.cpp)
#SET (HEADERS include/resources.h)
add_executable(${PROJECT_NAME} ${SOURCES} ${RESOURCE_HANDLER})
The biggest hack seems to be the stuff to copy resources. That would be ideal to have a special command that could do that on multiplatform. Not entirely certain how to do that — I suspect a set_target_resources would be a good name.
IF (APPLE)
set_target_properties(${PROJECT_NAME}
PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/src/mac/Spider-Fish-Info.plist
MACOSX_BUNDLE TRUE)
# add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND echo copying resources...
#${RESOURCES}
COMMAND mkdir -p ./${PROJECT_NAME}.app/Contents/Resources
COMMAND cp ${RESOURCES} ./${PROJECT_NAME}.app/Contents/Resources
)
# add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND echo ${PROJECT_NAME}.app/Contents/Resources)
ENDIF (APPLE)
IF (WIN32)
set_target_properties(${PROJECT_NAME}
PROPERTIES
WIN32_EXECUTABLE FALSE)
I would worry about this custom stuff on windows because of how specialized it is getting.
set(EXTRA_LIBS sfml-main ${OPENGL_LIBRARIES})
# note we can add stuff to ADDITIONAL_MAKE_CLEAN_FILES
string(COMPARE EQUAL ${CMAKE_GENERATOR} "NMake Makefiles" NMAKE)
if (NMAKE)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND echo copying dlls...
COMMAND copy ${SFML_INCLUDE_DIR}\\..\\bin\\*.dll .
COMMAND echo copying resources... from ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND -mkdir resources
COMMAND copy \"${CMAKE_CURRENT_SOURCE_DIR}\\assets\\*.*\" resources)
else ()
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND echo copying dlls...
COMMAND copy ${SFML_INCLUDE_DIR}\\..\\bin\\*.dll .
COMMAND echo copying resources... from ${CMAKE_CURRENT_SOURCE_DIR}
# Visual Studio does not support the '-' to ignore errors
COMMAND rmdir /s /q resources
COMMAND mkdir resources
COMMAND copy \"${CMAKE_CURRENT_SOURCE_DIR}\\assets\\*.*\" resources)
endif (NMAKE)
ENDIF (WIN32)
#if (APPLE)
target_link_libraries(${PROJECT_NAME}
sfml-system
sfml-window
sfml-network
sfml-graphics
sfml-audio
${EXTRA_LIBS})
#endif (APPLE)
Have you tried using the INSTALL command instead of the custom post build steps.