Apivalidator (#15951)

* Improved API validator logic (#15942)

* Fix for apiValidator when more than 1 target needs to be checked (#15950)

* Prevent infinite recursion
This commit is contained in:
Ilya Lavrenov 2023-02-25 23:36:11 +04:00 committed by GitHub
parent 00b5232419
commit 7274cdb51b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 155 additions and 104 deletions

View File

@ -5,56 +5,73 @@
if(WIN32)
set(PROGRAMFILES_ENV "ProgramFiles(X86)")
file(TO_CMAKE_PATH $ENV{${PROGRAMFILES_ENV}} PROGRAMFILES)
set(UWP_SDK_PATH "${PROGRAMFILES}/Windows Kits/10/bin/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/x64")
message(STATUS "Trying to find apivalidator in: ${UWP_SDK_PATH}")
find_host_program(UWP_API_VALIDATOR
set(WDK_PATHS "${PROGRAMFILES}/Windows Kits/10/bin/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/x64"
"${PROGRAMFILES}/Windows Kits/10/bin/x64")
message(STATUS "Trying to find apivalidator in: ")
foreach(wdk_path IN LISTS WDK_PATHS)
message(" * ${wdk_path}")
endforeach()
find_host_program(ONECORE_API_VALIDATOR
NAMES apivalidator
PATHS "${UWP_SDK_PATH}"
DOC "ApiValidator for UWP compliance")
PATHS ${WDK_PATHS}
DOC "ApiValidator for OneCore compliance")
if(UWP_API_VALIDATOR)
message(STATUS "Found apivalidator: ${UWP_API_VALIDATOR}")
if(ONECORE_API_VALIDATOR)
message(STATUS "Found apivalidator: ${ONECORE_API_VALIDATOR}")
endif()
endif()
function(_ie_add_api_validator_post_build_step_recursive)
cmake_parse_arguments(API_VALIDATOR "" "TARGET" "" ${ARGN})
list(APPEND API_VALIDATOR_TARGETS ${API_VALIDATOR_TARGET})
set(API_VALIDATOR_TARGETS ${API_VALIDATOR_TARGETS} PARENT_SCOPE)
get_target_property(IS_IMPORTED ${API_VALIDATOR_TARGET} IMPORTED)
if(IS_IMPORTED)
return()
endif()
get_target_property(LIBRARY_TYPE ${API_VALIDATOR_TARGET} TYPE)
if(LIBRARY_TYPE STREQUAL "EXECUTABLE" OR LIBRARY_TYPE STREQUAL "SHARED_LIBRARY")
get_target_property(LINKED_LIBRARIES ${API_VALIDATOR_TARGET} LINK_LIBRARIES)
if(LINKED_LIBRARIES)
foreach(ITEM IN LISTS LINKED_LIBRARIES)
if(NOT TARGET ${ITEM})
continue()
endif()
get_target_property(LIBRARY_TYPE_DEPENDENCY ${ITEM} TYPE)
if(LIBRARY_TYPE_DEPENDENCY STREQUAL "SHARED_LIBRARY")
_ie_add_api_validator_post_build_step_recursive(TARGET ${ITEM})
endif()
endforeach()
endif()
if(LIBRARY_TYPE MATCHES "^(SHARED_LIBRARY|MODULE_LIBRARY|EXECUTABLE)$" AND
NOT ${API_VALIDATOR_TARGET} IN_LIST API_VALIDATOR_TARGETS)
list(APPEND API_VALIDATOR_TARGETS ${API_VALIDATOR_TARGET})
endif()
# keep checks target list to track cyclic dependencies, leading to infinite recursion
list(APPEND checked_targets ${API_VALIDATOR_TARGET})
if(NOT LIBRARY_TYPE STREQUAL "INTERFACE_LIBRARY")
get_target_property(LINKED_LIBRARIES ${API_VALIDATOR_TARGET} LINK_LIBRARIES)
else()
set(LINKED_LIBRARIES)
endif()
get_target_property(INTERFACE_LINKED_LIBRARIES ${API_VALIDATOR_TARGET} INTERFACE_LINK_LIBRARIES)
foreach(library IN LISTS LINKED_LIBRARIES INTERFACE_LINKED_LIBRARIES)
if(TARGET "${library}")
get_target_property(orig_library ${library} ALIASED_TARGET)
if(orig_library IN_LIST checked_targets OR library IN_LIST checked_targets)
# in case of cyclic dependencies, we need to skip current target
continue()
endif()
if(TARGET "${orig_library}")
_ie_add_api_validator_post_build_step_recursive(TARGET ${orig_library})
else()
_ie_add_api_validator_post_build_step_recursive(TARGET ${library})
endif()
endif()
endforeach()
set(API_VALIDATOR_TARGETS ${API_VALIDATOR_TARGETS} PARENT_SCOPE)
endfunction()
set(VALIDATED_LIBRARIES "" CACHE INTERNAL "")
set(VALIDATED_TARGETS "" CACHE INTERNAL "")
function(_ov_add_api_validator_post_build_step)
set(UWP_API_VALIDATOR_APIS "${PROGRAMFILES}/Windows Kits/10/build/universalDDIs/x64/UniversalDDIs.xml")
set(UWP_API_VALIDATOR_EXCLUSION "${UWP_SDK_PATH}/BinaryExclusionlist.xml")
find_file(ONECORE_API_VALIDATOR_APIS NAMES UniversalDDIs.xml
PATHS "${PROGRAMFILES}/Windows Kits/10/build/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/universalDDIs/x64"
"${PROGRAMFILES}/Windows Kits/10/build/universalDDIs/x64"
DOC "Path to UniversalDDIs.xml file")
find_file(ONECORE_API_VALIDATOR_EXCLUSION NAMES BinaryExclusionlist.xml
PATHS ${WDK_PATHS}
DOC "Path to BinaryExclusionlist.xml file")
if((NOT UWP_API_VALIDATOR) OR (WINDOWS_STORE OR WINDOWS_PHONE))
if((NOT ONECORE_API_VALIDATOR) OR (WINDOWS_STORE OR WINDOWS_PHONE))
return()
endif()
@ -73,25 +90,10 @@ function(_ov_add_api_validator_post_build_step)
_ie_add_api_validator_post_build_step_recursive(TARGET ${API_VALIDATOR_TARGET})
# remove targets which were tested before
foreach(target IN LISTS API_VALIDATOR_TARGETS)
list(FIND VALIDATED_LIBRARIES ${target} index)
if (NOT index EQUAL -1)
list(APPEND VALIDATED_TARGETS ${target})
endif()
if(TARGET "${target}")
get_target_property(orig_target ${target} ALIASED_TARGET)
list(FIND VALIDATED_LIBRARIES ${orig_target} index)
if (NOT index EQUAL -1)
list(APPEND VALIDATED_TARGETS ${target})
endif()
endif()
endforeach()
foreach(item IN LISTS VALIDATED_TARGETS)
list(REMOVE_ITEM API_VALIDATOR_TARGETS ${item})
endforeach()
list(REMOVE_DUPLICATES API_VALIDATOR_TARGETS)
if(NOT API_VALIDATOR_TARGETS)
return()
endif()
@ -99,44 +101,63 @@ function(_ov_add_api_validator_post_build_step)
# apply check
macro(api_validator_get_target_name)
get_target_property(IS_IMPORTED ${target} IMPORTED)
get_target_property(is_imported ${target} IMPORTED)
get_target_property(orig_target ${target} ALIASED_TARGET)
if(IS_IMPORTED)
get_target_property(target_location ${target} LOCATION)
get_filename_component(target_name "${target_location}" NAME_WE)
if(is_imported)
get_target_property(imported_configs ${target} IMPORTED_CONFIGURATIONS)
foreach(imported_config RELEASE RELWITHDEBINFO DEBUG)
if(imported_config IN_LIST imported_configs)
get_target_property(target_location ${target} IMPORTED_LOCATION_${imported_config})
get_filename_component(target_name "${target_location}" NAME_WE)
break()
endif()
endforeach()
unset(imported_configs)
elseif(TARGET "${orig_target}")
set(target_name ${orig_target})
set(target_location $<TARGET_FILE:${orig_target}>)
else()
set(target_name ${target})
set(target_location $<TARGET_FILE:${target}>)
endif()
unset(orig_target)
unset(is_imported)
endmacro()
foreach(target IN LISTS API_VALIDATOR_TARGETS)
api_validator_get_target_name()
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21 AND OV_GENERATOR_MULTI_CONFIG)
set(output_file "${CMAKE_BINARY_DIR}/api_validator/$<CONFIG>/${target_name}.txt")
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20 AND OV_GENERATOR_MULTI_CONFIG)
set(output_file "${OpenVINO_BINARY_DIR}/api_validator/$<CONFIG>/${target_name}.txt")
else()
set(output_file "${CMAKE_BINARY_DIR}/api_validator/${target_name}.txt")
set(output_file "${OpenVINO_BINARY_DIR}/api_validator/${target_name}.txt")
endif()
add_custom_command(TARGET ${API_VALIDATOR_TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND} --config $<CONFIG>
-D UWP_API_VALIDATOR=${UWP_API_VALIDATOR}
-D UWP_API_VALIDATOR_TARGET=$<TARGET_FILE:${target}>
-D UWP_API_VALIDATOR_APIS=${UWP_API_VALIDATOR_APIS}
-D UWP_API_VALIDATOR_EXCLUSION=${UWP_API_VALIDATOR_EXCLUSION}
-D UWP_API_VALIDATOR_OUTPUT=${output_file}
list(APPEND post_build_commands
${CMAKE_COMMAND} --config $<CONFIG>
-D ONECORE_API_VALIDATOR=${ONECORE_API_VALIDATOR}
-D ONECORE_API_VALIDATOR_TARGET=${target_location}
-D ONECORE_API_VALIDATOR_APIS=${ONECORE_API_VALIDATOR_APIS}
-D ONECORE_API_VALIDATOR_EXCLUSION=${ONECORE_API_VALIDATOR_EXCLUSION}
-D ONECORE_API_VALIDATOR_OUTPUT=${output_file}
-D CMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-P "${IEDevScripts_DIR}/api_validator/api_validator_run.cmake"
BYPRODUCTS ${output_file}
COMMENT "[apiValidator] Check ${target_name} for OneCore compliance"
VERBATIM)
-P "${IEDevScripts_DIR}/api_validator/api_validator_run.cmake")
list(APPEND byproducts_files ${output_file})
unset(target_name)
unset(target_location)
endforeach()
add_custom_command(TARGET ${API_VALIDATOR_TARGET} POST_BUILD
COMMAND ${post_build_commands}
BYPRODUCTS ${byproducts_files}
COMMENT "[apiValidator] Check ${API_VALIDATOR_TARGET} and dependencies for OneCore compliance"
VERBATIM)
# update list of validated libraries
list(APPEND VALIDATED_LIBRARIES ${API_VALIDATOR_TARGETS})
set(VALIDATED_LIBRARIES "${VALIDATED_LIBRARIES}" CACHE INTERNAL "" FORCE)
list(APPEND VALIDATED_TARGETS ${API_VALIDATOR_TARGETS})
set(VALIDATED_TARGETS "${VALIDATED_TARGETS}" CACHE INTERNAL "" FORCE)
endfunction()
#

View File

@ -4,9 +4,9 @@
cmake_policy(SET CMP0012 NEW)
foreach(var UWP_API_VALIDATOR UWP_API_VALIDATOR_TARGET
UWP_API_VALIDATOR_APIS UWP_API_VALIDATOR_EXCLUSION
UWP_API_VALIDATOR_OUTPUT CMAKE_TOOLCHAIN_FILE)
foreach(var ONECORE_API_VALIDATOR ONECORE_API_VALIDATOR_TARGET
ONECORE_API_VALIDATOR_APIS ONECORE_API_VALIDATOR_EXCLUSION
ONECORE_API_VALIDATOR_OUTPUT CMAKE_TOOLCHAIN_FILE)
if(NOT DEFINED ${var})
message(FATAL_ERROR "Variable ${var} is not defined")
endif()
@ -14,18 +14,18 @@ endforeach()
# create command
if(NOT EXISTS "${UWP_API_VALIDATOR_APIS}")
message(FATAL_ERROR "${UWP_API_VALIDATOR_APIS} does not exist")
if(NOT EXISTS "${ONECORE_API_VALIDATOR_APIS}")
message(FATAL_ERROR "${ONECORE_API_VALIDATOR_APIS} does not exist")
endif()
set(command "${UWP_API_VALIDATOR}"
-SupportedApiXmlFiles:${UWP_API_VALIDATOR_APIS}
-DriverPackagePath:${UWP_API_VALIDATOR_TARGET})
if(EXISTS "${UWP_API_VALIDATOR_EXCLUSION}")
set(command "${ONECORE_API_VALIDATOR}"
-SupportedApiXmlFiles:${ONECORE_API_VALIDATOR_APIS}
-DriverPackagePath:${ONECORE_API_VALIDATOR_TARGET})
if(EXISTS "${ONECORE_API_VALIDATOR_EXCLUSION}")
list(APPEND command
-BinaryExclusionListXmlFile:${UWP_API_VALIDATOR_EXCLUSION}
-BinaryExclusionListXmlFile:${ONECORE_API_VALIDATOR_EXCLUSION}
-StrictCompliance:TRUE)
set(UWP_HAS_BINARY_EXCLUSION ON)
set(ONECORE_HAS_BINARY_EXCLUSION ON)
endif()
# execute
@ -36,13 +36,13 @@ execute_process(COMMAND ${command}
RESULT_VARIABLE exit_code
OUTPUT_STRIP_TRAILING_WHITESPACE)
file(WRITE "${UWP_API_VALIDATOR_OUTPUT}" "${output_message}\n\n\n${error_message}")
file(WRITE "${ONECORE_API_VALIDATOR_OUTPUT}" "CMAKE COMMAND: ${command}\n\n\n${output_message}\n\n\n${error_message}")
# post-process output
get_filename_component(name "${UWP_API_VALIDATOR_TARGET}" NAME)
get_filename_component(name "${ONECORE_API_VALIDATOR_TARGET}" NAME)
if(NOT UWP_HAS_BINARY_EXCLUSION)
if(NOT ONECORE_HAS_BINARY_EXCLUSION)
if(CMAKE_TOOLCHAIN_FILE MATCHES "onecoreuap.toolchain.cmake$")
# empty since we compile with static MSVC runtime
else()
@ -66,7 +66,7 @@ endif()
# write output
if(UWP_HAS_BINARY_EXCLUSION AND NOT exit_code EQUAL 0)
if(ONECORE_HAS_BINARY_EXCLUSION AND NOT exit_code EQUAL 0)
message(FATAL_ERROR "${error_message}")
endif()

View File

@ -166,7 +166,7 @@ macro(ov_add_frontend)
add_library(openvino::frontend::${OV_FRONTEND_NAME} ALIAS ${TARGET_NAME})
endif()
# Shutdown protobuf when unloading the front dynamic library
# Shutdown protobuf when unloading the frontend dynamic library
if(proto_files AND BUILD_SHARED_LIBS)
target_link_libraries(${TARGET_NAME} PRIVATE ov_protobuf_shutdown)
endif()
@ -201,8 +201,6 @@ macro(ov_add_frontend)
ie_add_vs_version_file(NAME ${TARGET_NAME}
FILEDESCRIPTION ${OV_FRONTEND_FILEDESCRIPTION})
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
target_link_libraries(${TARGET_NAME} PUBLIC openvino::runtime)
target_link_libraries(${TARGET_NAME} PRIVATE ${OV_FRONTEND_LINK_LIBRARIES})
ov_add_library_version(${TARGET_NAME})
@ -239,6 +237,11 @@ macro(ov_add_frontend)
add_dependencies(ov_frontends ${TARGET_NAME})
# must be called after all target_link_libraries
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
# installation
if(NOT OV_FRONTEND_SKIP_INSTALL)
if(BUILD_SHARED_LIBS)
# Note:

View File

@ -29,7 +29,6 @@ add_library(openvino::runtime ALIAS ${TARGET_NAME})
set_target_properties(${TARGET_NAME} PROPERTIES EXPORT_NAME runtime)
ie_add_vs_version_file(NAME ${TARGET_NAME} FILEDESCRIPTION "OpenVINO runtime library")
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
target_include_directories(${TARGET_NAME} PUBLIC
$<BUILD_INTERFACE:${OpenVINO_SOURCE_DIR}/src/core/include>
@ -59,6 +58,9 @@ endif()
set_ie_threading_interface_for(${TARGET_NAME})
ie_mark_target_as_cc(${TARGET_NAME})
# must be called after all target_link_libraries
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
# LTO
set_target_properties(${TARGET_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE ${ENABLE_LTO})

View File

@ -166,6 +166,7 @@ if(ENABLE_GAPI_PREPROCESSING)
set_target_properties(${TARGET_NAME} PROPERTIES COMPILE_PDB_NAME ${TARGET_NAME})
endif()
# must be called after all target_link_libraries
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
ie_add_vs_version_file(NAME ${TARGET_NAME}

View File

@ -38,6 +38,7 @@ endif()
set_ie_threading_interface_for(${TARGET_NAME})
# must be called after all target_link_libraries
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
set_target_properties(${TARGET_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE ${ENABLE_LTO})

View File

@ -20,6 +20,7 @@ ie_add_plugin(NAME ${TARGET_NAME}
target_link_libraries(${TARGET_NAME} PRIVATE Threads::Threads)
# must be called after all target_link_libraries
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
set_target_properties(${TARGET_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE ${ENABLE_LTO})

View File

@ -24,6 +24,7 @@ ie_faster_build(${TARGET_NAME}
target_link_libraries(${TARGET_NAME} PRIVATE openvino::pugixml)
# must be called after all target_link_libraries
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
set_target_properties(${TARGET_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE ${ENABLE_LTO})

View File

@ -86,6 +86,7 @@ cross_compiled_file(${TARGET_NAME}
NAMESPACE InferenceEngine::Extensions::Cpu::XARCH
)
# must be called after all target_link_libraries
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
# add test object library

View File

@ -63,6 +63,7 @@ target_compile_definitions(${TARGET_NAME}
_NO_MKL_
)
# must be called after all target_link_libraries
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
#
@ -132,5 +133,3 @@ if(NOT BUILD_SHARED_LIBS)
endif()
add_subdirectory(tests)

View File

@ -2,8 +2,25 @@
# SPDX-License-Identifier: Apache-2.0
#
# module to locate GNA libraries
#
# The module defines several imported targets:
#
# - (Optional) libGNA::API
# - (Optional) libGNA::KERNEL
#
# And high-level imported interface target:
#
# - libGNA
#
# And the following variables:
#
# - libGNA_API_FOUND
# - libGNA_KERNEL_FOUND
#
# The example usage:
#
# find_package(libGNA COMPONENTS API KERNEL)
#
set(libGNA_FOUND TRUE)
@ -27,7 +44,17 @@ if(libGNA_FIND_REQUIRED_KERNEL)
if(GNA_KERNEL_LIBRARY)
add_library(libGNA::KERNEL SHARED IMPORTED)
set_target_properties(libGNA::KERNEL PROPERTIES IMPORTED_LOCATION ${GNA_KERNEL_LIBRARY})
set_property(TARGET libGNA::KERNEL APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
if(WIN32)
set(gna_dll "${CMAKE_SHARED_LIBRARY_PREFIX}${GNA_KERNEL_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}")
set_target_properties(libGNA::KERNEL PROPERTIES
IMPORTED_LOCATION_RELEASE "${libGNA_LIBRARIES_BASE_PATH}/${gna_dll}"
IMPORTED_IMPLIB_RELEASE "${GNA_KERNEL_LIBRARY}")
else()
set_target_properties(libGNA::KERNEL PROPERTIES
IMPORTED_LOCATION_RELEASE "${GNA_KERNEL_LIBRARY}"
INTERFACE_LINK_OPTIONS "-Wl,-rpath-link,${libGNA_LIBRARIES_BASE_PATH}")
endif()
set(libGNA_KERNEL_FOUND TRUE)
else()
message(SEND_ERROR "GNA KERNEL library (${GNA_KERNEL_LIB_NAME}) was not found in ${libGNA_LIBRARIES_BASE_PATH}")
@ -40,7 +67,7 @@ if(libGNA_FIND_REQUIRED_API)
NO_CMAKE_FIND_ROOT_PATH)
if(libGNA_INCLUDE_DIRS)
add_library(libGNA::API INTERFACE IMPORTED)
set_target_properties(libGNA::API PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${libGNA_INCLUDE_DIRS})
set_target_properties(libGNA::API PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${libGNA_INCLUDE_DIRS}")
set(libGNA_API_FOUND TRUE)
else()
message(SEND_ERROR "GNA API headers (gna2-api.h) was not found in ${GNA_EXT_DIR}/include")
@ -48,15 +75,6 @@ if(libGNA_FIND_REQUIRED_API)
endif()
add_library(libGNA INTERFACE IMPORTED)
foreach(_lib_name ${libGNA_FIND_COMPONENTS})
foreach(_lib_name IN LISTS libGNA_FIND_COMPONENTS)
set_property(TARGET libGNA APPEND PROPERTY INTERFACE_LINK_LIBRARIES libGNA::${_lib_name})
endforeach(_lib_name)
if (WIN32)
if(libGNA_FIND_REQUIRED_KERNEL)
set_target_properties(libGNA::KERNEL PROPERTIES
IMPORTED_IMPLIB ${GNA_KERNEL_LIBRARY})
endif()
else()
set_target_properties(libGNA PROPERTIES INTERFACE_LINK_OPTIONS "-Wl,-rpath-link,${libGNA_LIBRARIES_BASE_PATH}")
endif ()

View File

@ -70,4 +70,5 @@ if(ENABLE_TESTS)
endif()
# Failed because of OpenCL
# must be called after all target_link_libraries
# ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})

View File

@ -47,6 +47,7 @@ if(LINUX AND OV_GLIBC_VERSION VERSION_GREATER_EQUAL 2.24)
set_target_properties(${TARGET_NAME} PROPERTIES LINK_OPTIONS "-Wl,-z,nodelete")
endif()
# must be called after all target_link_libraries
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
# LTO

View File

@ -37,8 +37,6 @@ target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/"
target_link_libraries(${TARGET_NAME} PRIVATE openvino::runtime::dev
inference_engine_legacy openvino::pugixml openvino::itt)
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
if(WIN32)
set_target_properties(${TARGET_NAME} PROPERTIES COMPILE_PDB_NAME ${TARGET_NAME})
endif()
@ -50,6 +48,9 @@ else()
target_link_libraries(openvino PRIVATE ${TARGET_NAME})
endif()
# must be called after all target_link_libraries
ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
# code style
add_cpplint_target(${TARGET_NAME}_cpplint FOR_TARGETS ${TARGET_NAME})