# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # # Copyright 2023 Google LLC # # Licensed under the Apache License v2.0 with LLVM Exceptions (the # "License"); you may not use this file except in compliance with the # License. You may obtain a copy of the License at # # https://llvm.org/LICENSE.txt # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Author: Aleksei Vetrov cmake_minimum_required(VERSION 3.14) project( stg VERSION 0.0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) add_compile_options(-fstrict-enums -Wall -Wextra) set(MINIMUM_GNU_VERSION 11) set(MINIMUM_Clang_VERSION 15) # Note, the quotes around the variable are significant. If we use a compiler # that does not resolve to a definition above, the empty string corresponds to # a version where all components are omitted and hence treated as zero. if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${MINIMUM_${CMAKE_CXX_COMPILER_ID}_VERSION}") message(FATAL_ERROR "Unsupported Compiler Version!\n" "Need at least ${CMAKE_CXX_COMPILER_ID} ${MINIMUM_${CMAKE_CXX_COMPILER_ID}_VERSION}") endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # GCC has problems detecting "no-return" switches and destructors. add_compile_options(-Wno-return-type) endif() # Enable LTO for release builds set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) find_package(LibElf 0.189 REQUIRED) find_package(LibDw 0.189 REQUIRED) find_package(LibXml2 2.9 REQUIRED) find_package(LinuxUAPI 5.19 REQUIRED) find_package(Protobuf 3.19 REQUIRED) if(NOT Protobuf_PROTOC_EXECUTABLE) message(FATAL_ERROR "Could NOT find protobuf::protoc. Please install protobuf-compiler or set Protobuf_PROTOC_EXECUTABLE to the location of the \"protoc\" binary.") endif() set(COMMON_LIBRARIES LibElf::LibElf LibDw::LibDw LibXml2::LibXml2 protobuf::libprotobuf) if(NOT Jemalloc_DISABLE) find_package(Jemalloc 5) if(Jemalloc_FOUND) list(APPEND COMMON_LIBRARIES Jemalloc::Jemalloc) else() message(WARNING "jemalloc significantly improves performance, but is not functionally required to build STG. Use -DJemalloc_DISABLE=TRUE to disable jemalloc and suppress this warning.") endif() endif() protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS stg.proto) add_library(libstg OBJECT abigail_reader.cc btf_reader.cc comparison.cc deduplication.cc dwarf_processor.cc dwarf_wrappers.cc elf_loader.cc elf_reader.cc fidelity.cc file_descriptor.cc filter.cc fingerprint.cc graph.cc input.cc naming.cc post_processing.cc proto_reader.cc proto_writer.cc reporting.cc runtime.cc stable_hash.cc type_normalisation.cc type_resolution.cc unification.cc ${PROTO_SRCS} ${PROTO_HDRS}) # Needed for generated .pb.h files target_include_directories(libstg PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(libstg PUBLIC ${COMMON_LIBRARIES}) set(STG_EXECUTABLE_TARGETS stg stgdiff) foreach(TARGET IN LISTS STG_EXECUTABLE_TARGETS) add_executable("${TARGET}" "${TARGET}.cc") target_link_libraries("${TARGET}" PRIVATE libstg) endforeach() # Testing find_package(Catch2 2 QUIET) if(NOT Catch2_FOUND) message(NOTICE "Catch2 v2 testing framework not found. Disabling tests.") else() enable_testing() add_custom_command(OUTPUT testdata COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/testdata/ ${CMAKE_BINARY_DIR}/testdata ) add_custom_target(testdata_symlink DEPENDS testdata) set(TEST_FILES abigail_reader_test elf_reader_test error_test file_descriptor_test filter_test order_test reporting_test runtime_test scc_test stgdiff_test ) foreach(test_file ${TEST_FILES}) add_executable(${test_file} ${test_file}.cc) target_link_libraries(${test_file} Catch2::Catch2WithMain libstg) add_test(NAME ${test_file} COMMAND ${test_file}) add_dependencies(${test_file} testdata_symlink) endforeach() endif() # Catch2_FOUND # Installation and packaging include(GNUInstallDirs) install( TARGETS ${STG_EXECUTABLE_TARGETS} COMPONENT Binaries RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")