I found a solution to the problem myself. In the files generated by CMake when using "NMake Makefiles" as generator, there is a file for each target called "DependInfo.cmake". The file is located in CMakeFiles/.dir/DependInfo.cmake for each target. In that file there is a variable named "CMAKE_CXX_TARGET_INCLUDE_PATH" which contain all include paths needed by the target. What I ended up doing, was a powershell script parsing that file and just picked out those paths in that variable and output those to a file in the format PC-Lint wants it.
Powershell script:
$projectRoot = $args[0]
$dependInfoFile = $args[1]
$output = $args[2]
if (Test-Path $dependInfoFile)
{
$lines = Get-Content $dependInfoFile
Remove-Item $output -Force -ErrorAction SilentlyContinue
foreach ($line in $lines)
{
if ($line -eq "set(CMAKE_CXX_TARGET_INCLUDE_PATH")
{
$printToFile = $TRUE
}
elseif ($printToFile -and ($line -eq " )"))
{
$printToFile = $FALSE
break
}
elseif ($printToFile)
{
$line = $line.trim()
$line = $line.Substring(1,$line.length-2)
while ($line.Substring(0,3) -eq "../")
{
$line = $line.SubString(3)
}
$outLine = "-i`"$projectRoot`/$line`""
Add-Content $output $outLine
}
}
}
For PC-lint, I added a custom_target which runs this powershell script with correct DependInfo.cmake file and the name of the output file. This custom_target is added as a dependency to the normal lint target, which results in that the generation of the output file is made just before linting. (Notice that some paths could possibly be needed to be changed)
FindLint.cmake (FindLint.cmake is provided by cmake, but has been modified)
# This file contains functions and configurations for generating PC-Lint build
# targets for your CMake projects.
set(PC_LINT_EXECUTABLE "c:/lint/lint-nt.exe" CACHE STRING "full path to the pc-lint executable. NOT the generated lin.bat")
set(PC_LINT_CONFIG_DIR "c:/lint/" CACHE STRING "full path to the directory containing pc-lint configuration files")
set(PC_LINT_USER_FLAGS "-b" CACHE STRING "additional pc-lint command line options -- some flags of pc-lint cannot be set in option files (most notably -b)")
# a phony target which causes all available *_LINT targets to be executed
add_custom_target(ALL_LINT)
# add_pc_lint(target source1 [source2 ...])
#
# Takes a list of source files and generates a build target which can be used
# for linting all files
#
# The generated lint commands assume that a top-level config file named
# 'std.lnt' resides in the configuration directory 'PC_LINT_CONFIG_DIR'. This
# config file must include all other config files. This is standard lint
# behaviour.
#
# Parameters:
# - target: the name of the target to which the sources belong. You will get a
# new build target named ${target}_LINT
# - source1 ... : a list of source files to be linted. Just pass the same list
# as you passed for add_executable or add_library. Everything except
# C and CPP files (*.c, *.cpp, *.cxx) will be filtered out.
#
# Example:
# If you have a CMakeLists.txt which generates an executable like this:
#
# set(MAIN_SOURCES main.c foo.c bar.c)
# add_executable(main ${MAIN_SOURCES})
#
# include this file
#
# include(/path/to/pc_lint.cmake)
#
# and add a line to generate the main_LINT target
#
# if(COMMAND add_pc_lint)
# add_pc_lint(main ${MAIN_SOURCES})
# endif(COMMAND add_pc_lint)
#
function(add_pc_lint target)
get_directory_property(lint_include_directories INCLUDE_DIRECTORIES)
get_directory_property(lint_defines COMPILE_DEFINITIONS)
# let's get those elephants across the alps
# prepend each include directory with "-i"; also quotes the directory
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/lint_include/${target}.lnt "")
foreach(include_dir ${lint_include_directories})
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/lint_include/${target}.lnt -i"${include_dir}"\n)
endforeach(include_dir)
# prepend each definition with "-d"
set(lint_defines_transformed)
foreach(definition ${lint_defines})
list(APPEND lint_defines_transformed -d${definition})
endforeach(definition)
# list of all commands, one for each given source file
set(pc_lint_commands)
foreach(sourcefile ${ARGN})
# only include c and cpp files
if( sourcefile MATCHES \\.c$|\\.cxx$|\\.cpp$ )
# make filename absolute
get_filename_component(sourcefile_abs ${sourcefile} ABSOLUTE)
# create command line for linting one source file and add it to the list of commands
list(APPEND pc_lint_commands
COMMAND ${PC_LINT_EXECUTABLE}
-i"${PC_LINT_CONFIG_DIR}" std.lnt
"-u" ${PC_LINT_USER_FLAGS}
"${CMAKE_CURRENT_BINARY_DIR}/lint_include/${target}.lnt"
${lint_defines_transformed}
${sourcefile_abs})
endif()
endforeach(sourcefile)
add_custom_target(${target}_LINT_INCLUDE
powershell.exe -File \"${CMAKE_MODULE_PATH}/generate_lint_include.ps1\" ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.dir/DependInfo.cmake ${CMAKE_CURRENT_BINARY_DIR}/lint_include/${target}.lnt)
# add a custom target consisting of all the commands generated above
add_custom_target(${target}_LINT ${pc_lint_commands} VERBATIM)
add_dependencies(${target}_LINT ${target}_LINT_INCLUDE)
# make the ALL_LINT target depend on each and every *_LINT target
add_dependencies(lint ${target}_LINT)
endfunction(add_pc_lint)