CMakeLists.txt 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. cmake_minimum_required(VERSION 3.5)
  2. cmake_policy(SET CMP0048 NEW)
  3. if(POLICY CMP0091)
  4. cmake_policy(SET CMP0091 NEW)
  5. endif()
  6. project (Bloaty VERSION 1.1)
  7. include(CTest)
  8. set(CMAKE_CXX_STANDARD 17)
  9. set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Group projects in visual studio
  10. # Options we define for users.
  11. option(BLOATY_ENABLE_ASAN "Enable address sanitizer." OFF)
  12. option(BLOATY_ENABLE_UBSAN "Enable undefined behavior sanitizer." OFF)
  13. option(BLOATY_ENABLE_CMAKETARGETS "Enable installing cmake target files." ON)
  14. option(BLOATY_ENABLE_BUILDID "Enable build id." ON)
  15. option(BLOATY_ENABLE_RE2 "Enable the support for regular expression functions." ON)
  16. if(UNIX)
  17. find_package(PkgConfig)
  18. find_package(ZLIB)
  19. if(BLOATY_ENABLE_RE2)
  20. pkg_search_module(RE2 re2)
  21. endif()
  22. pkg_search_module(CAPSTONE capstone)
  23. pkg_search_module(PROTOBUF protobuf)
  24. if(BLOATY_ENABLE_RE2)
  25. if(RE2_FOUND)
  26. MESSAGE(STATUS "System re2 found, using")
  27. else()
  28. MESSAGE(STATUS "System re2 not found, using bundled version")
  29. endif()
  30. endif()
  31. if(CAPSTONE_FOUND)
  32. MESSAGE(STATUS "System capstone found, using")
  33. else()
  34. MESSAGE(STATUS "System capstone not found, using bundled version")
  35. endif()
  36. if(PROTOBUF_FOUND)
  37. MESSAGE(STATUS "System protobuf found, using")
  38. else()
  39. MESSAGE(STATUS "System protobuf not found, using bundled version")
  40. endif()
  41. if (ZLIB_FOUND)
  42. MESSAGE(STATUS "System zlib found, using")
  43. else()
  44. MESSAGE(STATUS "System zlib not found, using bundled version")
  45. endif()
  46. endif()
  47. # Set default build type.
  48. if(NOT CMAKE_BUILD_TYPE)
  49. message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
  50. set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
  51. "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
  52. FORCE)
  53. endif()
  54. # Check out Git submodules.
  55. if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.gitmodules")
  56. execute_process (COMMAND git submodule update --init --recursive
  57. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
  58. endif()
  59. # Add third_party libraries, disabling as much as we can of their builds.
  60. add_definitions(-D_LIBCXXABI_FUNC_VIS=) # For Demumble.
  61. if(BLOATY_ENABLE_RE2)
  62. add_definitions(-DUSE_RE2)
  63. endif()
  64. # Set MSVC runtime before including thirdparty libraries
  65. if(MSVC)
  66. if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15)
  67. set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>)
  68. else()
  69. # Link also the runtime library statically so that MSVCR*.DLL is not required at runtime.
  70. # https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx
  71. # This is achieved by replacing msvc option /MD with /MT and /MDd with /MTd
  72. # http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
  73. foreach(flag_var
  74. CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
  75. CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
  76. if (flag_var MATCHES "/MD")
  77. string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
  78. endif()
  79. endforeach()
  80. endif()
  81. endif()
  82. set(THREADS_PREFER_PTHREAD_FLAG TRUE)
  83. find_package(Threads REQUIRED)
  84. if(UNIX)
  85. if(BLOATY_ENABLE_RE2)
  86. if(RE2_FOUND)
  87. include_directories(${RE2_INCLUDE_DIRS})
  88. else()
  89. set(RE2_BUILD_TESTING OFF CACHE BOOL "enable testing for RE2" FORCE)
  90. add_subdirectory(third_party/re2)
  91. include_directories(third_party/re2)
  92. endif()
  93. endif()
  94. if(CAPSTONE_FOUND)
  95. include_directories(${CAPSTONE_INCLUDE_DIRS})
  96. else()
  97. set(CAPSTONE_BUILD_SHARED OFF CACHE BOOL "Build shared library" FORCE)
  98. set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "Build tests" FORCE)
  99. add_subdirectory(third_party/capstone)
  100. include_directories(third_party/capstone/include)
  101. endif()
  102. if(PROTOBUF_FOUND)
  103. include_directories(${PROTOBUF_INCLUDE_DIRS})
  104. else()
  105. set(protobuf_BUILD_TESTS OFF CACHE BOOL "enable tests for proto2" FORCE)
  106. set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "enable shared libs for proto2" FORCE)
  107. add_subdirectory(third_party/protobuf/cmake)
  108. include_directories(SYSTEM third_party/protobuf/src)
  109. endif()
  110. if(NOT ZLIB_FOUND)
  111. add_subdirectory(third_party/zlib)
  112. include_directories(SYSTEM third_party/zlib)
  113. endif()
  114. else()
  115. if(BLOATY_ENABLE_RE2)
  116. set(RE2_BUILD_TESTING OFF CACHE BOOL "enable testing for RE2" FORCE)
  117. add_subdirectory(third_party/re2)
  118. include_directories(third_party/re2)
  119. set_property(TARGET re2 PROPERTY FOLDER "third_party")
  120. endif()
  121. set(CAPSTONE_BUILD_SHARED OFF CACHE BOOL "Build shared library" FORCE)
  122. set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "Build tests" FORCE)
  123. add_subdirectory(third_party/capstone)
  124. include_directories(third_party/capstone/include)
  125. set_property(TARGET capstone-static PROPERTY FOLDER "third_party")
  126. set(protobuf_BUILD_TESTS OFF CACHE BOOL "enable tests for proto2" FORCE)
  127. set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "enable shared libs for proto2" FORCE)
  128. add_subdirectory(third_party/protobuf/cmake)
  129. include_directories(SYSTEM third_party/protobuf/src)
  130. add_subdirectory(third_party/zlib)
  131. include_directories(third_party/zlib)
  132. include_directories(${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib)
  133. set_property(TARGET example PROPERTY FOLDER "third_party")
  134. set_property(TARGET minigzip PROPERTY FOLDER "third_party")
  135. set_property(TARGET zlib PROPERTY FOLDER "third_party")
  136. set_property(TARGET zlibstatic PROPERTY FOLDER "third_party")
  137. set_property(TARGET libprotobuf PROPERTY FOLDER "third_party")
  138. set_property(TARGET libprotobuf-lite PROPERTY FOLDER "third_party")
  139. set_property(TARGET libprotoc PROPERTY FOLDER "third_party")
  140. set_property(TARGET protoc PROPERTY FOLDER "third_party")
  141. endif()
  142. include_directories(.)
  143. include_directories(src)
  144. include_directories(third_party/abseil-cpp)
  145. include_directories("${CMAKE_CURRENT_BINARY_DIR}/src")
  146. # Baseline build flags.
  147. if(MSVC)
  148. set(CMAKE_CXX_FLAGS "/EHsc /wd4018 /D_CRT_SECURE_NO_WARNINGS /DNOMINMAX")
  149. else()
  150. set(CMAKE_CXX_FLAGS "-W -Wall -Wno-sign-compare")
  151. set(CMAKE_CXX_FLAGS_DEBUG "-g1")
  152. set(CMAKE_CXX_FLAGS_RELEASE "-O2")
  153. set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g1")
  154. set_source_files_properties(third_party/demumble/third_party/libcxxabi/cxa_demangle.cpp PROPERTIES COMPILE_FLAGS -Wno-implicit-fallthrough)
  155. endif()
  156. if(APPLE)
  157. elseif(UNIX)
  158. if(BLOATY_ENABLE_BUILDID)
  159. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id")
  160. endif()
  161. endif()
  162. # When using Ninja, compiler output won't be colorized without this.
  163. include(CheckCXXCompilerFlag)
  164. CHECK_CXX_COMPILER_FLAG(-fdiagnostics-color=always SUPPORTS_COLOR_ALWAYS)
  165. if(SUPPORTS_COLOR_ALWAYS)
  166. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
  167. endif()
  168. # Implement ASAN/UBSAN options
  169. if(BLOATY_ENABLE_ASAN)
  170. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
  171. set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fsanitize=address")
  172. endif()
  173. if(BLOATY_ENABLE_UBSAN)
  174. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
  175. set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fsanitize=undefined")
  176. endif()
  177. if(DEFINED ENV{CXXFLAGS})
  178. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{CXXFLAGS}")
  179. endif()
  180. file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src)
  181. if(PROTOC_FOUND)
  182. add_custom_command(
  183. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/bloaty.pb.cc
  184. DEPENDS protoc ${CMAKE_CURRENT_SOURCE_DIR}/src/bloaty.proto
  185. COMMAND protoc ${CMAKE_CURRENT_SOURCE_DIR}/src/bloaty.proto
  186. --cpp_out=${CMAKE_CURRENT_BINARY_DIR}/src
  187. -I${CMAKE_CURRENT_SOURCE_DIR}/src
  188. )
  189. else()
  190. add_custom_command(
  191. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/bloaty.pb.cc
  192. COMMAND protoc ${CMAKE_CURRENT_SOURCE_DIR}/src/bloaty.proto
  193. --cpp_out=${CMAKE_CURRENT_BINARY_DIR}/src
  194. -I${CMAKE_CURRENT_SOURCE_DIR}/src
  195. )
  196. endif()
  197. file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/bloaty_package.bloaty
  198. DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
  199. add_library(libbloaty STATIC
  200. src/bloaty.cc
  201. src/bloaty.h
  202. src/disassemble.cc
  203. ${CMAKE_CURRENT_BINARY_DIR}/src/bloaty.pb.cc
  204. src/dwarf/attr.h
  205. src/dwarf/attr.cc
  206. src/dwarf/dwarf_util.cc
  207. src/dwarf/debug_info.cc
  208. src/dwarf/line_info.cc
  209. src/dwarf.cc
  210. src/dwarf_constants.h
  211. src/eh_frame.cc
  212. src/elf.cc
  213. src/macho.cc
  214. src/pe.cc
  215. third_party/lief_pe/pe_structures.h
  216. src/range_map.cc
  217. src/range_map.h
  218. src/re.h
  219. src/util.cc
  220. src/util.h
  221. src/webassembly.cc
  222. # Until Abseil has a proper CMake build system
  223. third_party/abseil-cpp/absl/base/internal/raw_logging.cc # Grrrr...
  224. third_party/abseil-cpp/absl/base/internal/throw_delegate.cc
  225. third_party/abseil-cpp/absl/debugging/internal/demangle.cc
  226. third_party/abseil-cpp/absl/numeric/int128.cc
  227. third_party/abseil-cpp/absl/strings/ascii.cc
  228. third_party/abseil-cpp/absl/strings/charconv.cc
  229. third_party/abseil-cpp/absl/strings/escaping.cc
  230. third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc
  231. third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc
  232. third_party/abseil-cpp/absl/strings/internal/escaping.cc
  233. third_party/abseil-cpp/absl/strings/internal/memutil.cc
  234. third_party/abseil-cpp/absl/strings/internal/utf8.cc
  235. third_party/abseil-cpp/absl/strings/match.cc
  236. third_party/abseil-cpp/absl/strings/numbers.cc
  237. third_party/abseil-cpp/absl/strings/str_cat.cc
  238. third_party/abseil-cpp/absl/strings/string_view.cc
  239. third_party/abseil-cpp/absl/strings/str_split.cc
  240. third_party/abseil-cpp/absl/strings/substitute.cc
  241. third_party/abseil-cpp/absl/types/bad_optional_access.cc
  242. # One source file, no special build system needed.
  243. third_party/demumble/third_party/libcxxabi/cxa_demangle.cpp
  244. )
  245. set_property(TARGET libbloaty PROPERTY FOLDER "bloaty")
  246. if(UNIX)
  247. set(LIBBLOATY_LIBS libbloaty)
  248. if(PROTOBUF_FOUND)
  249. list(APPEND LIBBLOATY_LIBS ${PROTOBUF_LIBRARIES})
  250. else()
  251. list(APPEND LIBBLOATY_LIBS libprotoc)
  252. endif()
  253. if(BLOATY_ENABLE_RE2)
  254. if(RE2_FOUND)
  255. list(APPEND LIBBLOATY_LIBS ${RE2_LIBRARIES})
  256. else()
  257. list(APPEND LIBBLOATY_LIBS re2)
  258. endif()
  259. endif()
  260. if(CAPSTONE_FOUND)
  261. list(APPEND LIBBLOATY_LIBS ${CAPSTONE_LIBRARIES})
  262. else()
  263. list(APPEND LIBBLOATY_LIBS capstone-static)
  264. endif()
  265. if(ZLIB_FOUND)
  266. list(APPEND LIBBLOATY_LIBS ZLIB::ZLIB)
  267. else()
  268. list(APPEND LIBBLOATY_LIBS zlibstatic)
  269. endif()
  270. else()
  271. set(LIBBLOATY_LIBS libbloaty libprotoc capstone-static)
  272. if(BLOATY_ENABLE_RE2)
  273. list(APPEND LIBBLOATY_LIBS re2)
  274. endif()
  275. list(APPEND LIBBLOATY_LIBS zlibstatic)
  276. endif()
  277. if(UNIX)
  278. if(BLOATY_ENABLE_RE2)
  279. if(RE2_FOUND)
  280. link_directories(${RE2_LIBRARY_DIRS})
  281. endif()
  282. endif()
  283. if(CAPSTONE_FOUND)
  284. link_directories(${CAPSTONE_LIBRARY_DIRS})
  285. endif()
  286. if(PROTOBUF_FOUND)
  287. link_directories(${PROTOBUF_LIBRARY_DIRS})
  288. endif()
  289. endif()
  290. list(APPEND LIBBLOATY_LIBS Threads::Threads)
  291. if(DEFINED ENV{LIB_FUZZING_ENGINE})
  292. message("LIB_FUZZING_ENGINE set, building fuzz_target instead of Bloaty")
  293. add_executable(fuzz_target tests/fuzz_target.cc)
  294. target_link_libraries(fuzz_target ${LIBBLOATY_LIBS} $ENV{LIB_FUZZING_ENGINE})
  295. else()
  296. add_executable(bloaty src/main.cc)
  297. target_link_libraries(bloaty ${LIBBLOATY_LIBS})
  298. set_property(TARGET bloaty PROPERTY FOLDER "bloaty")
  299. if(BLOATY_ENABLE_CMAKETARGETS)
  300. install(
  301. TARGETS bloaty
  302. EXPORT ${PROJECT_NAME}Targets
  303. RUNTIME DESTINATION bin
  304. )
  305. else()
  306. install(
  307. TARGETS bloaty
  308. RUNTIME DESTINATION bin
  309. )
  310. endif()
  311. if (IS_DIRECTORY "${PROJECT_SOURCE_DIR}/tests")
  312. enable_testing()
  313. find_package(Python COMPONENTS Interpreter)
  314. find_program(LIT_EXECUTABLE NAMES lit-script.py lit.py lit)
  315. find_program(FILECHECK_EXECUTABLE FileCheck)
  316. find_program(YAML2OBJ_EXECUTABLE yaml2obj)
  317. if(Python_FOUND AND LIT_EXECUTABLE AND FILECHECK_EXECUTABLE AND YAML2OBJ_EXECUTABLE)
  318. set(BLOATY_SRC_DIR ${PROJECT_SOURCE_DIR})
  319. set(BLOATY_OBJ_DIR ${PROJECT_BINARY_DIR})
  320. configure_file(tests/lit.site.cfg.in tests/lit.site.cfg @ONLY)
  321. add_custom_target(check-bloaty
  322. COMMAND ${Python_EXECUTABLE} ${LIT_EXECUTABLE} -sv ${PROJECT_BINARY_DIR}/tests --param bloaty=$<TARGET_FILE:bloaty>
  323. DEPENDS
  324. bloaty
  325. ${CMAKE_CURRENT_SOURCE_DIR}/tests/lit.cfg
  326. ${CMAKE_CURRENT_BINARY_DIR}/tests/lit.site.cfg
  327. COMMENT "Running bloaty tests..."
  328. USES_TERMINAL)
  329. set_property(TARGET check-bloaty PROPERTY FOLDER "tests")
  330. endif()
  331. if(BUILD_TESTING)
  332. option(INSTALL_GTEST "" OFF)
  333. add_subdirectory(third_party/googletest)
  334. include_directories(third_party/googletest/googletest/include)
  335. include_directories(third_party/googletest/googlemock/include)
  336. set(TEST_TARGETS
  337. bloaty_test
  338. bloaty_test_pe
  339. bloaty_misc_test
  340. range_map_test
  341. )
  342. foreach(target ${TEST_TARGETS})
  343. add_executable(${target} tests/${target}.cc)
  344. target_link_libraries(${target} ${LIBBLOATY_LIBS} gtest_main gmock)
  345. set_property(TARGET ${target} PROPERTY FOLDER "tests")
  346. endforeach(target)
  347. add_executable(fuzz_test tests/fuzz_target.cc tests/fuzz_driver.cc)
  348. target_link_libraries(fuzz_test ${LIBBLOATY_LIBS})
  349. set_property(TARGET fuzz_test PROPERTY FOLDER "tests")
  350. foreach(testlib gmock gmock_main gtest gtest_main)
  351. set_property(TARGET ${testlib} PROPERTY FOLDER "tests/libs")
  352. endforeach(testlib)
  353. file(GLOB fuzz_corpus tests/testdata/fuzz_corpus/*)
  354. add_test(NAME range_map_test COMMAND range_map_test)
  355. add_test(NAME bloaty_test_x86-64 COMMAND bloaty_test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/linux-x86_64)
  356. add_test(NAME bloaty_test_x86 COMMAND bloaty_test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/linux-x86)
  357. add_test(NAME bloaty_test_pe_x64 COMMAND bloaty_test_pe WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/PE/x64)
  358. add_test(NAME bloaty_test_pe_x86 COMMAND bloaty_test_pe WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/PE/x86)
  359. add_test(NAME bloaty_misc_test COMMAND bloaty_misc_test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/misc)
  360. add_test(NAME fuzz_test COMMAND fuzz_test ${fuzz_corpus} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/fuzz_corpus)
  361. endif()
  362. endif()
  363. if(BLOATY_ENABLE_CMAKETARGETS)
  364. install(EXPORT ${PROJECT_NAME}Targets NAMESPACE ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME})
  365. endif()
  366. endif()