remill-master-remill-master-CMakeLists


[TOC]

1.操作概述

include文件

当前目录/cmake/vcpkg_helper.cmake

当前目录/cmake/ccache.cmake

当前目录/cmake/settings.cmake

当前目录/cmake/utils.cmake

当前目录/cmake/BCCompiler.cmake”

setup 包或模块

LLVM(只选取了其中静态的目录)

Intel XED

Google glog module

Google flags

windows SDK

不同系统的设置

是unix且不是苹果:

set(LINKER_START_GROUP "-Wl,--start-group")
set(LINKER_END_GROUP "-Wl,--end-group")

其他:

set(LINKER_START_GROUP "")
set(LINKER_END_GROUP "")

语义配置

REMILL_BARRIER_AS_NOP :关闭

REMILL_BUILD_SPARC32_RUNTIME :打开

target setting

  1. 给以下宏赋值:

REMILL_LLVM_VERSION
EXPR REMILL_LLVM_VERSION_NUMBER
REMILL_INSTALL_SEMANTICS_DIR
REMILL_BUILD_SEMANTICS_DIR_X86
REMILL_BUILD_SEMANTICS_DIR_AARCH32
REMILL_BUILD_SEMANTICS_DIR_AARCH64
REMILL_BUILD_SEMANTICS_DIR_SPARC32
REMILL_BUILD_SEMANTICS_DIR_SPARC64
REMILL_INCLUDE_DIR
REMILL_LIB_DIR

  1. 给remill_settings添加include目录

设置编译选项

win32的warnings 和 compiler 设置

特定于clang 的warnings/error选项

优化 flags和definitions

添加目录

add_subdirectory(lib/Arch)
add_subdirectory(lib/BC)
add_subdirectory(lib/OS)
add_subdirectory(lib/Version)

并连接到remill library

install

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/remillConfig.cmake"
              "${CMAKE_CURRENT_LIST_DIR}/cmake/vcpkg_helper.cmake"
  DESTINATION "${REMILL_INSTALL_LIB_DIR}/cmake/remill"
)

install(DIRECTORY "${REMILL_INCLUDE_DIR}/remill/"
  DESTINATION "${REMILL_INSTALL_INCLUDE_DIR}"
)

测试

主要是根据它的COMPILER_ID、platform、HOST_SYSTEM_PROCESSOR来创建文件夹

# tests
message("compiler ID ${CMAKE_C_COMPILER_ID}")
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
  # Tests require enabling exports on binaries
  # https://cmake.org/cmake/help/latest/variable/CMAKE_ENABLE_EXPORTS.html#variable:CMAKE_ENABLE_EXPORTS
  set(CMAKE_ENABLE_EXPORTS ON)

  find_package(Threads REQUIRED)
  add_custom_target(test_dependencies)

  if(NOT "${PLATFORM_NAME}" STREQUAL "windows")
    if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "AMD64" OR "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
      message(STATUS "X86 tests enabled")
      add_subdirectory(tests/X86)
    endif()
  endif()

  if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "aarch64" AND "${PLATFORM_NAME}" STREQUAL "linux")
    message(STATUS "aarch64 tests enabled")
    add_subdirectory(tests/AArch64)
  endif()
endif()

2.逐条解释

前期准备(include、set等)

cmake_minimum_required(VERSION 3.14)
# include 指令用来载入并运行来自于文件或模块的CMake代码
# CMAKE_CURRENT_SOURCE_DIR为当前目录,即:
# 当前目录/cmake/vcpkg_helper.cmake
# 当前目录/cmake/ccache.cmake
# 当前目录/cmake/settings.cmake
# 当前目录/cmake/utils.cmake
# 当前目录/cmake/BCCompiler.cmake"


include(cmake/vcpkg_helper.cmake)

include(GNUInstallDirs)

include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/ccache.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/settings.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/utils.cmake")

include(CTest)
# 同上

setup ccache

# 指定默认使用 c、c++、ASM语言
project(remill C CXX ASM)
# 这个命令用于给REMILL_SOURCE_DIR宏赋值,其中PROJECT_SOURCE_DIR是cmake内置宏,指向构建工程的全路径。

set(REMILL_SOURCE_DIR "${PROJECT_SOURCE_DIR}")

set(REMILL_INSTALL_LIB_DIR "${CMAKE_INSTALL_LIBDIR}" CACHE PATH "Directory in which remill libraries will be installed")
set(REMILL_INSTALL_BIN_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH "Directory in which remill binaries will be installed")
set(REMILL_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/remill" CACHE PATH "Directory in which remill headers will be installed")
set(REMILL_INSTALL_SHARE_DIR "${CMAKE_INSTALL_DATADIR}" CACHE PATH "Directory in which remill cmake files will be installed")
# list:提供一些列表操作 
# 添加新元素到列表中
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")

setup LLVM

find_package(LLVM CONFIG REQUIRED)
# 为用户显示一条 STATUS(非重要)消息
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
# 将LLVM_VERSION_LIST ${LLVM_PACKAGE_VERSION}出现的所有 "." 替换为";"
string(REPLACE "." ";" LLVM_VERSION_LIST ${LLVM_PACKAGE_VERSION})
# GET:返回列表中指定下标的元素
# 将 LLVM_VERSION_LIST 下标为0的给LLVM_MAJOR_VERSION
#将 LLVM_VERSION_LIST 下标为1的给LLVM_MINOR_VERSION
list(GET LLVM_VERSION_LIST 0 LLVM_MAJOR_VERSION)
list(GET LLVM_VERSION_LIST 1 LLVM_MINOR_VERSION)
# 添加名为 thirdparty_llvm的库
# INTERFACE 创建一个接口库
# 这类库有属性,能install(),export()和imported(),但没有build过程,像纯头文件库或完全针对target的设计。
add_library(thirdparty_llvm INTERFACE)
# target_include_directories和target_compile_definitions用来设置INTERFACE_*属性

#target_include_directories添加一个include目录到目标文件
target_include_directories(thirdparty_llvm SYSTEM INTERFACE
  $<BUILD_INTERFACE:${LLVM_INCLUDE_DIRS}>
)

#为目标增加编译定义
target_compile_definitions(thirdparty_llvm INTERFACE
  ${LLVM_DEFINITIONS}
)

include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/BCCompiler.cmake")
#将LLVM_AVAILABLE_LIBS里的静态库添加到LLVM_LIBRARIES中
foreach(LLVM_LIB IN LISTS LLVM_AVAILABLE_LIBS)
  get_target_property(LLVM_LIB_TYPE ${LLVM_LIB} TYPE)
  if(LLVM_LIB_TYPE STREQUAL "STATIC_LIBRARY")
    list(APPEND LLVM_LIBRARIES "${LLVM_LIB}")
  endif()
endforeach()

list(REMOVE_ITEM LLVM_LIBRARIES LLVMMC LLVMCore LLVMSupport)
list(APPEND LLVM_LIBRARIES LLVMMC LLVMCore LLVMSupport)

target_link_libraries(thirdparty_llvm INTERFACE
  ${LLVM_LIBRARIES}
)
#好像没有用的Z3
# Microsoft Z3 with LLVM. Not exactly used in remill, but LLVM doesn't link
# against it correctly
# NOTE: If changing this, also replicate in remillConfig file
if (LLVM_WITH_Z3)
  find_package(Z3 CONFIG REQUIRED 4.7.1)
  get_target_property(LLVMSupport_LIBS LLVMSupport INTERFACE_LINK_LIBRARIES)
  list(REMOVE_ITEM LLVMSupport_LIBS Z3)
  list(APPEND LLVMSupport_LIBS z3::libz3)
  set_target_properties(LLVMSupport PROPERTIES
    INTERFACE_LINK_LIBRARIES "${LLVMSupport_LIBS}")
endif()

message(STATUS "LLVM Libraries: ${LLVM_LIBRARIES}")

XED

# Intel XED
find_package(XED CONFIG REQUIRED)
add_library(thirdparty_xed INTERFACE)
target_link_libraries(thirdparty_xed INTERFACE
  XED::XED
)

Google glog module

# Google glog module
find_package(glog CONFIG REQUIRED)
add_library(thirdparty_glog INTERFACE)
target_link_libraries(thirdparty_glog INTERFACE
  glog::glog
)

windows SDK

# Windows SDK
add_library(thirdparty_win32 INTERFACE)
if(DEFINED WIN32)
  target_link_libraries(thirdparty_win32 INTERFACE
     "Kernel32.lib"
  )
endif()

系统

if(UNIX AND NOT APPLE)
  set(LINKER_START_GROUP "-Wl,--start-group")
  set(LINKER_END_GROUP "-Wl,--end-group")
else()
  set(LINKER_START_GROUP "")
  set(LINKER_END_GROUP "")
endif()

语义配置

# 语义的配置选项
#
# Configuration options for semantics
#
# REMILL_BARRIER_AS_NOP关闭
# REMILL_BUILD_SPARC32_RUNTIME打开
option(REMILL_BARRIER_AS_NOP "Remove compiler barriers (inline assembly) in semantics" OFF)
option(REMILL_BUILD_SPARC32_RUNTIME "Build the Runtime for SPARC32. Turn this off if you have include errors with <bits/c++config.h>, or read the README for a fix" ON)

target setting

set(REMILL_LLVM_VERSION "${LLVM_MAJOR_VERSION}")
message("Remill llvm version: ${REMILL_LLVM_VERSION}")

math(EXPR REMILL_LLVM_VERSION_NUMBER "${LLVM_MAJOR_VERSION} * 100 + ${LLVM_MINOR_VERSION}")

set(REMILL_INSTALL_SEMANTICS_DIR "${CMAKE_INSTALL_PREFIX}/${REMILL_INSTALL_SHARE_DIR}/remill/${REMILL_LLVM_VERSION}/semantics" CACHE PATH "Directory into which semantics are installed")

set(REMILL_BUILD_SEMANTICS_DIR_X86 "${CMAKE_CURRENT_BINARY_DIR}/lib/Arch/X86/Runtime")
set(REMILL_BUILD_SEMANTICS_DIR_AARCH32 "${CMAKE_CURRENT_BINARY_DIR}/lib/Arch/AArch32/Runtime")
set(REMILL_BUILD_SEMANTICS_DIR_AARCH64 "${CMAKE_CURRENT_BINARY_DIR}/lib/Arch/AArch64/Runtime")
set(REMILL_BUILD_SEMANTICS_DIR_SPARC32 "${CMAKE_CURRENT_BINARY_DIR}/lib/Arch/SPARC32/Runtime")
set(REMILL_BUILD_SEMANTICS_DIR_SPARC64 "${CMAKE_CURRENT_BINARY_DIR}/lib/Arch/SPARC64/Runtime")

# add everything as public.
set(REMILL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")
set(REMILL_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib")


add_library(remill_settings INTERFACE)

target_include_directories(remill_settings INTERFACE
  $<BUILD_INTERFACE:${REMILL_INCLUDE_DIR}>
  $<INSTALL_INTERFACE:include>)

设置编译选项

if(WIN32)
  # warnings and compiler settings
  target_compile_options(remill_settings INTERFACE
    "$<$<CONFIG:Debug>:/MDd>$<$<CONFIG:Release>:/MD>"
    /nologo /W3 /EHsc /wd4141 /wd4146 /wd4180 /wd4244
    /wd4258 /wd4267 /wd4291 /wd4345 /wd4351 /wd4355 /wd4456
    /wd4457 /wd4458 /wd4459 /wd4503 /wd4624 /wd4722 /wd4800
    /wd4100 /wd4127 /wd4512 /wd4505 /wd4610 /wd4510 /wd4702
    /wd4245 /wd4706 /wd4310 /wd4701 /wd4703 /wd4389 /wd4611
    /wd4805 /wd4204 /wd4577 /wd4091 /wd4592 /wd4324
  )

  target_compile_definitions(remill_settings INTERFACE
    _CRT_SECURE_NO_DEPRECATE
    _CRT_SECURE_NO_WARNINGS
    _CRT_NONSTDC_NO_DEPRECATE
    _CRT_NONSTDC_NO_WARNINGS
    _SCL_SECURE_NO_DEPRECATE
    _SCL_SECURE_NO_WARNINGS
    GOOGLE_PROTOBUF_NO_RTTI
  )

else()
  # warnings and compiler settings
  target_compile_options(remill_settings INTERFACE
    -Wall -Wextra -Wno-unused-parameter -Wno-c++98-compat
    -Wno-unreachable-code-return -Wno-nested-anon-types
    -Wno-extended-offsetof
    -Wno-variadic-macros -Wno-return-type-c-linkage
    -Wno-c99-extensions -Wno-ignored-attributes -Wno-unused-local-typedef
    -Wno-unknown-pragmas -Wno-unknown-warning-option -fPIC
    -fno-omit-frame-pointer -fvisibility-inlines-hidden
    -fno-asynchronous-unwind-tables
  )
 # 特定于clang 的警告/错误选项
  # Clang-specific warnings/error options
  if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
    target_compile_options(remill_settings INTERFACE
      -Wgnu-alignof-expression -Wno-gnu-anonymous-struct -Wno-gnu-designator
      -Wno-gnu-zero-variadic-macro-arguments -Wno-gnu-statement-expression
      -fno-aligned-allocation
    )
  endif()

  # debug symbols
  if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
    target_compile_options(remill_settings INTERFACE
      -gdwarf-2 -g3
    )
  endif()

  # optimization flags and definitions
  if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    target_compile_options(remill_settings INTERFACE
      -O0
    )
    target_compile_definitions(remill_settings INTERFACE
      "DEBUG"
    )
  else()
    target_compile_options(remill_settings INTERFACE
      -O2
    )
    target_compile_definitions(remill_settings INTERFACE
      "NDEBUG"
    )
  endif()
endif()
target_compile_definitions(remill_settings INTERFACE
  "REMILL_INSTALL_SEMANTICS_DIR=\"${REMILL_INSTALL_SEMANTICS_DIR}\""
  "REMILL_BUILD_SEMANTICS_DIR_X86=\"${REMILL_BUILD_SEMANTICS_DIR_X86}\""
  "REMILL_BUILD_SEMANTICS_DIR_AARCH32=\"${REMILL_BUILD_SEMANTICS_DIR_AARCH32}\""
  "REMILL_BUILD_SEMANTICS_DIR_AARCH64=\"${REMILL_BUILD_SEMANTICS_DIR_AARCH64}\""
  "REMILL_BUILD_SEMANTICS_DIR_SPARC32=\"${REMILL_BUILD_SEMANTICS_DIR_SPARC32}\""
  "REMILL_BUILD_SEMANTICS_DIR_SPARC64=\"${REMILL_BUILD_SEMANTICS_DIR_SPARC64}\""
)

set(THIRDPARTY_LIBRARY_LIST thirdparty_llvm thirdparty_xed thirdparty_glog thirdparty_gflags)
target_link_libraries(remill_settings INTERFACE
  ${THIRDPARTY_LIBRARY_LIST}
)
install(TARGETS remill_settings ${THIRDPARTY_LIBRARY_LIST}
  EXPORT remillTargets)
  
set(THIRDPARTY_LIBRARY_LIST thirdparty_llvm thirdparty_xed thirdparty_glog thirdparty_gflags)
target_link_libraries(remill_settings INTERFACE
  ${THIRDPARTY_LIBRARY_LIST}
)
install(TARGETS remill_settings ${THIRDPARTY_LIBRARY_LIST}
  EXPORT remillTargets)

add directory

#添加目录
add_subdirectory(lib/Arch)
add_subdirectory(lib/BC)
add_subdirectory(lib/OS)
add_subdirectory(lib/Version)

add_library(remill INTERFACE)
target_link_libraries(remill INTERFACE
  ${LINKER_START_GROUP}
  ${THIRDPARTY_LIBRARY_LIST}
  remill_bc
  remill_os
  remill_arch
  remill_version
  ${LINKER_END_GROUP}
)
install(TARGETS remill EXPORT remillTargets)

install

#
# Also install clang, libllvm and llvm-link
#

set(INSTALLED_CLANG_NAME "remill-clang-${REMILL_LLVM_VERSION}${CMAKE_EXECUTABLE_SUFFIX}")
set(INSTALLED_LLVMLINK_NAME "remill-llvm-link-${REMILL_LLVM_VERSION}${CMAKE_EXECUTABLE_SUFFIX}")

InstallExternalTarget("ext_clang" "${CLANG_PATH}" "BIN" "${INSTALLED_CLANG_NAME}")

InstallExternalTarget("ext_llvmlink" "${LLVMLINK_PATH}" "BIN" "${INSTALLED_LLVMLINK_NAME}")

GetTargetTree(THIRDPARTY_LIBRARIES ${THIRDPARTY_LIBRARY_LIST})
GetPublicIncludeFolders(THIRDPARTY_INCLUDE_DIRECTORIES ${THIRDPARTY_LIBRARIES})
foreach(THIRDPARTY_LIB IN LISTS THIRDPARTY_LIBRARIES)
  string(SUBSTRING "${THIRDPARTY_LIB}" 0 1 THIRDPARTY_LIB_PREFIX)
  if(TARGET ${THIRDPARTY_LIB})
    get_target_property(THIRDPARTY_LIB_TYPE ${THIRDPARTY_LIB} TYPE)
    if(THIRDPARTY_LIB_TYPE STREQUAL "STATIC_LIBRARY" OR THIRDPARTY_LIB_TYPE STREQUAL "SHARED_LIBRARY")
      list(APPEND THIRDPARTY_LIBRARY_FILES "$${}<TARGET_FILE:${THIRDPARTY_LIB}>")
    endif()
  elseif("${THIRDPARTY_LIB_PREFIX}" STREQUAL "$${}")
    # E.g. $<LINK_ONLY:...>
  else()
    list(APPEND THIRDPARTY_LIBRARY_FILES "${THIRDPARTY_LIB}")
  endif()
endforeach()

list(REMOVE_DUPLICATES THIRDPARTY_LIBRARY_FILES)

# First do the basic substitutions.
configure_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/remillConfig.cmake.in"
  "${CMAKE_CURRENT_BINARY_DIR}/remillConfig.cmake"
  @ONLY
)

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/remillConfig.cmake"
              "${CMAKE_CURRENT_LIST_DIR}/cmake/vcpkg_helper.cmake"
  DESTINATION "${REMILL_INSTALL_LIB_DIR}/cmake/remill"
)

install(DIRECTORY "${REMILL_INCLUDE_DIR}/remill/"
  DESTINATION "${REMILL_INSTALL_INCLUDE_DIR}"
)

#
# additional targets
#

add_custom_target(semantics)

# tools
add_subdirectory(bin)

install(EXPORT remillTargets
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/remill")

test

# tests
message("compiler ID ${CMAKE_C_COMPILER_ID}")
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
  # Tests require enabling exports on binaries
  # https://cmake.org/cmake/help/latest/variable/CMAKE_ENABLE_EXPORTS.html#variable:CMAKE_ENABLE_EXPORTS
  set(CMAKE_ENABLE_EXPORTS ON)

  find_package(Threads REQUIRED)
  add_custom_target(test_dependencies)

  if(NOT "${PLATFORM_NAME}" STREQUAL "windows")
    if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "AMD64" OR "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
      message(STATUS "X86 tests enabled")
      add_subdirectory(tests/X86)
    endif()
  endif()

  if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "aarch64" AND "${PLATFORM_NAME}" STREQUAL "linux")
    message(STATUS "aarch64 tests enabled")
    add_subdirectory(tests/AArch64)
  endif()
endif()

文章作者: Raina Jung
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Raina Jung !
  目录