[CMake] custom targets always running in MSVC 2005, test issues
Ryan Pavlik
rpavlik at iastate.edu
Thu Jan 14 17:50:47 EST 2010
I have some questions about a custom target I'm adding to my projects.
It works as expected (even before I added a set_target_properties call)
on Mac and Linux, but even with that additional call, it always builds
this additional target (or possibly the test) when built from Visual
Studio 2005's IDE. (No such behavior occurs during dashboard builds
started by a ctest -S script: in fact, it doesn't even find the test
added by this same module when building on anything except Linux. Any
advice on this one, either?)
Here are the modules (CppcheckTargets.cmake, Findcppcheck.cmake, and its
dummy data Findcppcheck.cpp) I'm using: to use it in a project you just
need to toss all the files in the same directory in your
CMAKE_MODULE_PATH, and add two things to your CMakeLists.txt -
include(CppcheckTargets) and then one or more calls to
add_cppcheck(nameofexistingtargetwhosesourcesyouwishtocheck) cppcheck
is an open-source C++ static analysis tool (like a "lint" tool).
Thanks for any help - I'm happy to provide more info if needed.
Ryan
---------------------- CppcheckTargets.cmake -----------------
# - Run cppcheck on c++ source files as a custom target and a test
#
# include(CppcheckTargets)
# add_cppcheck(<target-name> [UNUSED_FUNCTIONS] [STYLE] [POSSIBLE_ERROR])
#
# Requires these CMake modules:
# Findcppcheck
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik<rpavlik at iastate.edu> <abiryan at ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
if(NOT CPPCHECK_FOUND)
find_package(cppcheck QUIET)
endif()
function(add_cppcheck _targetname)
if(CPPCHECK_FOUND)
set(_cppcheck_args)
list(FIND ARGN UNUSED_FUNCTIONS _unused_func)
if("${_unused_func}" GREATER "-1")
list(APPEND _cppcheck_args ${CPPCHECK_UNUSEDFUNC_ARG})
endif()
list(FIND ARGN STYLE _style)
if("${_style}" GREATER "-1")
list(APPEND _cppcheck_args ${CPPCHECK_STYLE_ARG})
endif()
list(FIND ARGN POSSIBLE_ERROR _poss_err)
if("${_poss_err}" GREATER "-1")
list(APPEND _cppcheck_args ${CPPCHECK_POSSIBLEERROR_ARG})
endif()
#get_directory_property(_cppcheck_include_dirs INCLUDE_DIRECTORIES)
#set(_includeflags)
#foreach(_dir ${_cppcheck_include_dirs})
# list(APPEND _cppcheck_args "${CPPCHECK_INCLUDEPATH_ARG}${_dir}")
#endforeach()
get_target_property(_cppcheck_sources "${_targetname}" SOURCES)
set(_files)
foreach(_source ${_cppcheck_sources})
get_source_file_property(_cppcheck_lang "${_source}" LANGUAGE)
get_source_file_property(_cppcheck_loc "${_source}" LOCATION)
if("${_cppcheck_lang}" MATCHES "CXX")
list(APPEND _files "${_cppcheck_loc}")
endif()
endforeach()
add_test(NAME
${_targetname}_cppcheck_test
COMMAND
${CPPCHECK_EXECUTABLE}
${CPPCHECK_QUIET_ARG}
${CPPCHECK_TEMPLATE_ARG}
${_cppcheck_args}
${_files}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT
"Running cppcheck on target ${_targetname}..."
VERBATIM)
set_tests_properties(${_targetname}_cppcheck_test
PROPERTIES
FAIL_REGULAR_EXPRESSION
"[(]error[)]")
if(NOT TARGET all_cppcheck)
add_custom_target(all_cppcheck)
set_target_properties(all_cppcheck PROPERTIES EXCLUDE_FROM_ALL true)
endif()
add_custom_target(${_targetname}_cppcheck
COMMAND
${CPPCHECK_EXECUTABLE}
${CPPCHECK_QUIET_ARG}
${CPPCHECK_TEMPLATE_ARG}
${_cppcheck_args}
${_files}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT
"${_targetname}_cppcheck: Running cppcheck on target ${_targetname}..."
VERBATIM)
set_target_properties(${_targetname}_cppcheck PROPERTIES EXCLUDE_FROM_ALL true)
add_dependencies(all_cppcheck ${_targetname}_cppcheck)
endif()
endfunction()
---------- Findcppcheck.cmake -------------
# - try to find cppcheck tool
#
# Cache Variables:
# CPPCHECK_EXECUTABLE
#
# Non-cache variables you might use in your CMakeLists.txt:
# CPPCHECK_FOUND
# CPPCHECK_POSSIBLEERROR_ARG
# CPPCHECK_UNUSEDFUNC_ARG
# CPPCHECK_STYLE_ARG
# CPPCHECK_QUIET_ARG
# CPPCHECK_INCLUDEPATH_ARG
# CPPCHECK_MARK_AS_ADVANCED - whether to mark our vars as advanced even
# if we don't find this program.
#
# Requires these CMake modules:
# FindPackageHandleStandardArgs (known included with CMake>=2.6.2)
#
# Original Author:
# 2009-2010 Ryan Pavlik<rpavlik at iastate.edu> <abiryan at ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
set(CPPCHECK_ROOT_DIR "" CACHE PATH "Path to search for cppcheck")
# cppcheck app bundles on Mac OS X are GUI, we want command line only
set(_oldappbundlesetting ${CMAKE_FIND_APPBUNDLE})
set(CMAKE_FIND_APPBUNDLE NEVER)
# If we have a custom path, look there first.
if(CPPCHECK_ROOT_DIR)
find_program(CPPCHECK_EXECUTABLE
NAMES cppcheck cli
PATHS "${CPPCHECK_ROOT_DIR}"
PATH_SUFFIXES cli
NO_DEFAULT_PATH)
endif()
find_program(CPPCHECK_EXECUTABLE
NAMES cppcheck)
# Restore original setting for appbundle finding
set(CMAKE_FIND_APPBUNDLE ${_oldappbundlesetting})
if(CPPCHECK_EXECUTABLE)
# Find out where our test file is
get_filename_component(_cppcheckmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
set(_cppcheckdummyfile "${_cppcheckmoddir}/Findcppcheck.cpp")
# Check for the two types of command line arguments by just trying them
execute_process(COMMAND
"${CPPCHECK_EXECUTABLE}"
"--enable=style"
"--quiet"
"${_cppcheckdummyfile}"
RESULT_VARIABLE
_cppcheck_new_result)
execute_process(COMMAND
"${CPPCHECK_EXECUTABLE}"
"--style"
"--quiet"
"${_cppcheckdummyfile}"
RESULT_VARIABLE
_cppcheck_old_result)
if("${_cppcheck_new_result}" EQUAL 0)
# New arguments
set(CPPCHECK_UNUSEDFUNC_ARG "--enable=unusedFunctions")
set(CPPCHECK_POSSIBLEERROR_ARG "--enable=possibleError")
set(CPPCHECK_STYLE_ARG "--enable=style")
set(CPPCHECK_QUIET_ARG "--quiet")
set(CPPCHECK_INCLUDEPATH_ARG "-I")
if(MSVC)
set(CPPCHECK_TEMPLATE_ARG --template vs)
elseif(CMAKE_COMPILER_IS_GNUCXX)
set(CPPCHECK_TEMPLATE_ARG --template gcc)
endif()
elseif("${_cppcheck_old_result}" EQUAL 0)
# Old arguments
set(CPPCHECK_UNUSEDFUNC_ARG "--unused-functions")
set(CPPCHECK_POSSIBLEERROR_ARG "--all")
set(CPPCHECK_STYLE_ARG "--style")
set(CPPCHECK_QUIET_ARG "--quiet")
set(CPPCHECK_INCLUDEPATH_ARG "-I")
else()
# No idea - some other issue must be getting in the way
message(STATUS
"WARNING: Can't detect whether CPPCHECK wants new or old-style arguments!")
endif()
endif()
set(CPPCHECK_ALL
"${CPPCHECK_EXECUTABLE} ${CPPCHECK_POSSIBLEERROR_ARG} ${CPPCHECK_UNUSEDFUNC_ARG} ${CPPCHECK_STYLE_ARG} ${CPPCHECK_QUIET_ARG} ${CPPCHECK_INCLUDEPATH_ARG} some/include/path")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(cppcheck
DEFAULT_MSG
CPPCHECK_ALL
CPPCHECK_EXECUTABLE
CPPCHECK_POSSIBLEERROR_ARG
CPPCHECK_UNUSEDFUNC_ARG
CPPCHECK_STYLE_ARG
CPPCHECK_INCLUDEPATH_ARG
CPPCHECK_QUIET_ARG)
if(CPPCHECK_FOUND OR CPPCHECK_MARK_AS_ADVANCED)
mark_as_advanced(CPPCHECK_ROOT_DIR CPPCHECK_EXECUTABLE)
endif()
------------------ Findcppcheck.cpp ---------------
/**
* \file Findcppcheck.cpp
* \brief Dummy C++ source file used by CMake module Findcppcheck.cmake
*
* \author
* Ryan Pavlik, 2009-2010
*<rpavlik at iastate.edu>
* http://academic.cleardefinition.com/
*
*/
int main(int argc, char* argv[]) {
return 0;
}
--
Ryan Pavlik
HCI Graduate Student
Virtual Reality Applications Center
Iowa State University
rpavlik at iastate.edu
http://academic.cleardefinition.com
Internal VRAC/HCI Site: http://tinyurl.com/rpavlik
More information about the CMake
mailing list