aboutsummaryrefslogtreecommitdiff
path: root/CMakeLists.txt
blob: f28e0d51a3dddd4e5f16d2c1f35d3899af240576 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# 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}")