# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2022-2025, Intel Corporation include(FindOpenSSL) # All pcm-* executables set(PROJECT_NAMES pcm pcm-numa pcm-latency pcm-power pcm-msr pcm-memory pcm-tsx pcm-pcie pcm-core pcm-iio pcm-pcicfg pcm-mmio pcm-tpmi pcm-raw pcm-accel) set(MINIMUM_OPENSSL_VERSION 1.1.1) file(GLOB COMMON_SOURCES pcm-accel-common.cpp msr.cpp cpucounters.cpp pci.cpp mmio.cpp tpmi.cpp pmt.cpp bw.cpp utils.cpp topology.cpp debug.cpp threadpool.cpp uncore_pmu_discovery.cpp pcm-iio-pmu.cpp lspci.cpp ${PCM_PUGIXML_CPP}) if (APPLE) file(GLOB UNIX_SOURCES dashboard.cpp) else() file(GLOB UNIX_SOURCES dashboard.cpp resctrl.cpp) endif() if (LINUX) if(EXISTS "/etc/os-release") # AND IS_READABLE "/etc/os-release" (3.29 cmake required :-( ) file(STRINGS "/etc/os-release" OS_RELEASE_CONTENTS) foreach(LINE ${OS_RELEASE_CONTENTS}) if(LINE MATCHES "^ID=") string(REGEX REPLACE "^ID=\"?\([a-zA-Z]+\)\"?" "\\1" OS_ID ${LINE}) endif() endforeach() message(STATUS "Detected Linux distribution: ${OS_ID}") else() message(STATUS "Unable to read /etc/os-release") endif() endif() if(NOT PCM_NO_ASAN) if(OS_ID STREQUAL "centos") set(PCM_NO_STATIC_LIBASAN ON) message(STATUS "CentOS detected, using dynamic libasan") endif() if(OS_ID STREQUAL "arch") set(PCM_NO_STATIC_LIBASAN ON) message(STATUS "arch Linux detected, using dynamic libasan") endif() endif() if(UNIX) # LINUX, FREE_BSD, APPLE if (NOT APPLE) set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS} -s") # --strip-unneeded for packaging endif() list(APPEND PROJECT_NAMES pcm-sensor-server) list(APPEND PROJECT_NAMES pcm-sensor) # libpcm.a add_library(PCM_STATIC STATIC ${COMMON_SOURCES} ${UNIX_SOURCES}) set_target_properties(PCM_STATIC PROPERTIES OUTPUT_NAME pcm) # libpcm.a with -DPCM_SILENT for Release* add_library(PCM_STATIC_SILENT STATIC ${COMMON_SOURCES} ${UNIX_SOURCES}) target_compile_definitions(PCM_STATIC_SILENT PRIVATE $<$:PCM_SILENT> $<$:PCM_SILENT> $<$:PCM_SILENT> ) set_target_properties(PCM_STATIC PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(PCM_STATIC_SILENT PROPERTIES POSITION_INDEPENDENT_CODE ON) # libpcm.so add_library(PCM_SHARED SHARED pcm-core.cpp) target_compile_options(PCM_SHARED PRIVATE -DPCM_SHARED_LIBRARY=1) # PCM_SILENT in Release* for pcm-core.cpp target_compile_definitions(PCM_SHARED PRIVATE $<$:PCM_SILENT> $<$:PCM_SILENT> $<$:PCM_SILENT> ) if(PCM_NO_ASAN) set(PCM_DYNAMIC_ASAN "") set(PCM_STATIC_ASAN "") else() if(PCM_NO_STATIC_LIBASAN) message(STATUS "Using dynamic libasan") set(PCM_DYNAMIC_ASAN "asan") set(PCM_STATIC_ASAN "") else() set(PCM_DYNAMIC_ASAN "") set(PCM_STATIC_ASAN "-static-libasan") message(STATUS "Using static libasan") message(STATUS "To use dynamic libasan, use -DPCM_NO_STATIC_LIBASAN=1 option (required for CentOS and arch Linux)") endif() endif() if(APPLE) add_subdirectory(MacMSRDriver) include_directories("${CMAKE_SOURCE_DIR}/src/MacMSRDriver") # target_include_directories doesn't work target_link_libraries(PCM_SHARED PRIVATE PCM_STATIC_SILENT PcmMsr Threads::Threads) elseif(LINUX) target_link_libraries(PCM_SHARED PRIVATE PCM_STATIC_SILENT Threads::Threads "${PCM_DYNAMIC_ASAN}") else() target_link_libraries(PCM_SHARED PRIVATE PCM_STATIC_SILENT Threads::Threads) endif() set_target_properties(PCM_SHARED PROPERTIES OUTPUT_NAME pcm) endif() if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2 /wd4251 /wd4273 /EHa /Zi") add_definitions(/W3) # windows/* files -> PCM_STATIC file(GLOB WINDOWS_SOURCES winpmem/winpmem.cpp windows/stdafx.cpp freegetopt/getopt.cpp) add_library(PCM_STATIC STATIC ${COMMON_SOURCES} ${WINDOWS_SOURCES}) target_compile_definitions(PCM_STATIC PRIVATE UNICODE _UNICODE _CONSOLE) if(PCM_NO_STATIC_MSVC_RUNTIME_LIBRARY) set(PCM_MSVC_RUNTIME_LIBRARY_OPTIONS "") else() set(PCM_MSVC_RUNTIME_LIBRARY_OPTIONS "/MT$<$:d>") message(STATUS "Using static MSVC runtime library") message(STATUS "To use default/dynamic MSVC runtime library, use -DNO_STATIC_MSVC_RUNTIME_LIBRARY=1 option") endif() target_compile_options(PCM_STATIC PRIVATE "${PCM_MSVC_RUNTIME_LIBRARY_OPTIONS}") # Graphical perfmon front-end: pcm-lib, pcm-service # Files: COMMON_FILES() + pcm-lib.cpp winpmem\winpmem.cpp dllmain.cpp file(GLOB PCM_LIB_SOURCES winpmem/winpmem.cpp dllmain.cpp pcm-lib.cpp ) add_library(pcm-lib SHARED ${COMMON_SOURCES} ${PCM_LIB_SOURCES}) target_compile_definitions(pcm-lib PRIVATE _WINDOWS _USRDLL PCM_EXPORTS _WINDLL _UNICODE UNICODE) target_compile_options(pcm-lib PRIVATE "${PCM_MSVC_RUNTIME_LIBRARY_OPTIONS}") # Pcm-service files: PCM_SHARED + AssemblyInfo.cpp PCMInstaller.cpp PCMService.cpp file(GLOB PCM_SERVICE_SOURCES windows/PCMInstaller.cpp windows/PCMService.cpp windows/AssemblyInfo.cpp winddows/utils.cpp) add_executable(pcm-service ${PCM_SERVICE_SOURCES}) target_compile_definitions(pcm-service PRIVATE _UNICODE UNICODE _CONSOLE) set_target_properties(pcm-service PROPERTIES LINK_FLAGS "/INCREMENTAL:NO" COMMON_LANGUAGE_RUNTIME "") set_property(TARGET pcm-service PROPERTY VS_DOTNET_REFERENCES "System;System.Configuration.Install;System.Data;System.Management;System.ServiceProcess;System.Xml") target_link_libraries(pcm-service pcm-lib) endif(MSVC) ####################### # SIMDJSON dependency ####################### add_library(PCM_SIMDJSON INTERFACE) # interface library for simdjson set(SIMDJSON_IS_APPLICABLE TRUE) # true if simdjson can be used, default - TRUE # check simdjson support matrix - https://github.com/simdjson/simdjson/blob/master/doc/basics.md # > GCC 7.4, > Clang 6.0 , > MSVC 2017 if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.4) OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6) OR (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND MSVC_TOOLSET_VERSION VERSION_LESS 141)) # corresponds to VS2017 message(WARNING " ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_VERSION} is incompartible with simdjson features' requirements.\n" " Refer to simdjson support matrix - https://github.com/simdjson/simdjson/blob/master/doc/basics.md .\n" " Parsing events from https://github.com/intel/perfmon won't be supported.") set(SIMDJSON_IS_APPLICABLE FALSE) endif() if(SIMDJSON_IS_APPLICABLE) find_package(simdjson QUIET) # Working form Ubuntu 22.04 if(simdjson_FOUND) message(STATUS "System SIMDJSON is used") target_link_libraries(PCM_SIMDJSON INTERFACE simdjson::simdjson) target_compile_definitions(PCM_SIMDJSON INTERFACE SYSTEM_SIMDJSON) target_compile_definitions(PCM_SIMDJSON INTERFACE PCM_SIMDJSON_AVAILABLE) else() if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/simdjson/singleheader/simdjson.h") message(STATUS "Local SIMDJSON exists: ${CMAKE_CURRENT_SOURCE_DIR}/simdjson/singleheader/simdjson.h") file(GLOB SIMDJSON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/simdjson/singleheader/simdjson.cpp) target_sources(PCM_SIMDJSON INTERFACE ${SIMDJSON_SOURCE}) target_include_directories(PCM_SIMDJSON INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/simdjson/singleheader) target_compile_definitions(PCM_SIMDJSON INTERFACE PCM_SIMDJSON_AVAILABLE) else() message(WARNING " ${CMAKE_CURRENT_SOURCE_DIR}/simdjson/singleheader/simdjson.h doesn't exist\n" " Use `git clone --recursive` flag when cloning pcm repository to clone simdjson submodule as well or\n" " update submodule with command 'git submodule update --init --recursive' or\n" " run 'git clone https://github.com/simdjson/simdjson.git' in 'src' directory to get simdjson library") endif() endif(simdjson_FOUND) endif(SIMDJSON_IS_APPLICABLE) ####################### # End of SIMDJSON dependency section ####################### if(PCM_BUILD_EXECUTABLES) foreach(PROJECT_NAME ${PROJECT_NAMES}) file(GLOB PROJECT_FILE ${PROJECT_NAME}.cpp) set(LIBS PCM_STATIC) add_executable(${PROJECT_NAME} ${PROJECT_FILE}) if(MSVC) target_compile_options(${PROJECT_NAME} PRIVATE "${PCM_MSVC_RUNTIME_LIBRARY_OPTIONS}") endif(MSVC) if(UNIX) set(LIBS ${LIBS} "-fPIE") endif(UNIX) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "${PCM_STATIC_ASAN}") endif() # specific file for pcm-raw project if(${PROJECT_NAME} STREQUAL pcm-raw) set(LIBS ${LIBS} PCM_SIMDJSON) endif(${PROJECT_NAME} STREQUAL pcm-raw) if(${PROJECT_NAME} STREQUAL pcm-sensor-server) if(NO_SSL) message(STATUS "SSL is disabled") else() message(STATUS "Compiling with SSL support, requires libssl-dev or openssl-devel or libopenssl-devel or libopenssl-dev package installed") message(STATUS "To disable SSL support, use -DNO_SSL=1 option") find_package(OpenSSL ${MINIMUM_OPENSSL_VERSION} QUIET) if(OPENSSL_FOUND) message(STATUS "OpenSSL version ${OPENSSL_VERSION} >= ${MINIMUM_OPENSSL_VERSION}, OpenSSL support enabled") target_compile_options(${PROJECT_NAME} PRIVATE "-DUSE_SSL") set(LIBS ${LIBS} OpenSSL::SSL OpenSSL::Crypto) else() message(STATUS "OpenSSL support has been disabled, the version is less than ${MINIMUM_OPENSSL_VERSION}") endif() endif() file(READ pcm-sensor-server.service.in SENSOR_SERVICE_IN) string(REPLACE "@@CMAKE_INSTALL_SBINDIR@@" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_SBINDIR}" SENSOR_SERVICE "${SENSOR_SERVICE_IN}") file(WRITE "${CMAKE_BINARY_DIR}/pcm-sensor-server.service" "${SENSOR_SERVICE}") file(GLOB PROJECT_FILE ${PROJECT_NAME}.cpp pcm-accel-common.h pcm-accel-common.cpp) target_include_directories(pcm-sensor-server PUBLIC ${CMAKE_SOURCE_DIR}) if(LINUX_SYSTEMD) install(FILES "${CMAKE_BINARY_DIR}/pcm-sensor-server.service" DESTINATION "${LINUX_SYSTEMD_UNITDIR}") endif(LINUX_SYSTEMD) endif(${PROJECT_NAME} STREQUAL pcm-sensor-server) if(LINUX OR FREE_BSD) set(LIBS ${LIBS} Threads::Threads) install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_SBINDIR}) endif(LINUX OR FREE_BSD) if(APPLE) set(LIBS ${LIBS} Threads::Threads PcmMsr) install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_SBINDIR}) endif(APPLE) if(MSVC) target_compile_definitions(${PROJECT_NAME} PRIVATE _UNICODE UNICODE _CONSOLE) # for all, except pcm-lib and pcm-service endif(MSVC) target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBS}) endforeach(PROJECT_NAME ${PROJECT_NAMES}) endif(PCM_BUILD_EXECUTABLES) ####################### # Install ####################### if(UNIX) # APPLE, LINUX, FREE_BSD if(LINUX) # Daemon & client file(GLOB DAEMON_SOURCES "daemon/*.cpp") add_executable(daemon ${DAEMON_SOURCES}) target_link_libraries(daemon PRIVATE PCM_STATIC Threads::Threads "-fPIE") set_target_properties(daemon PROPERTIES OUTPUT_NAME "pcm-daemon") install(TARGETS daemon DESTINATION ${CMAKE_INSTALL_SBINDIR}) file(GLOB CLIENT_SOURCES "client/*.cpp") add_executable(client ${CLIENT_SOURCES}) target_link_libraries(client PRIVATE Threads::Threads "-fPIE") set_target_properties(client PROPERTIES OUTPUT_NAME "pcm-client") install(TARGETS client DESTINATION ${CMAKE_INSTALL_BINDIR}) endif(LINUX) # Install extra files install(FILES pcm-bw-histogram.sh DESTINATION ${CMAKE_INSTALL_SBINDIR} RENAME pcm-bw-histogram PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ) file(GLOB OPCODE_FILES "opCode*.txt") foreach(opcode_file ${OPCODE_FILES}) get_filename_component(opcode_file_name ${opcode_file} NAME) configure_file(${opcode_file} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${opcode_file_name} COPYONLY) install(FILES ${opcode_file} DESTINATION ${CMAKE_INSTALL_DATADIR}/pcm) endforeach(opcode_file ${OPCODE_FILES}) file(COPY "PMURegisterDeclarations" DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) install(DIRECTORY "PMURegisterDeclarations" DESTINATION ${CMAKE_INSTALL_DATADIR}/pcm) # Install docs install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_INSTALL_DATADIR}/licenses/pcm) install(FILES ${CMAKE_SOURCE_DIR}/README.md DESTINATION ${CMAKE_INSTALL_DOCDIR}) file(GLOB DOC_FILES ${CMAKE_SOURCE_DIR}/doc/*.txt ${CMAKE_SOURCE_DIR}/doc/*.md) foreach(doc_file ${DOC_FILES}) get_filename_component(doc_file_name ${doc_file} NAME) configure_file(${doc_file} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${doc_file_name} COPYONLY) install(FILES ${doc_file} DESTINATION ${CMAKE_INSTALL_DOCDIR}) endforeach(doc_file ${DOC_FILES}) endif(UNIX) if(MSVC) file(GLOB OPCODE_FILES "opCode*.txt") foreach(opcode_file ${OPCODE_FILES}) add_custom_command(TARGET pcm-iio POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${opcode_file} $) endforeach(opcode_file ${OPCODE_FILES}) add_custom_command(TARGET pcm-raw POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "$/PMURegisterDeclarations") add_custom_command(TARGET pcm-raw POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/src/PMURegisterDeclarations" "$/PMURegisterDeclarations") add_custom_command(TARGET pcm-service POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECT_SOURCE_DIR}/src/windows/pcm-service.exe.config" $) endif(MSVC)