diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b9cf63eb..811c5ae47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ cmake_minimum_required(VERSION 3.14) include(GNUInstallDirs) include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/settings.cmake") -include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/utils_vcpkg.cmake") +include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/utils.cmake") include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/ccache.cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") include(CTest) @@ -51,7 +51,7 @@ list(GET LLVM_VERSION_LIST 1 LLVM_MINOR_VERSION) add_library(thirdparty_llvm INTERFACE) target_include_directories(thirdparty_llvm SYSTEM INTERFACE - ${LLVM_INCLUDE_DIRS} + $ ) target_compile_definitions(thirdparty_llvm INTERFACE ${LLVM_DEFINITIONS} @@ -293,7 +293,7 @@ list(REMOVE_DUPLICATES THIRDPARTY_LIBRARY_FILES) # First do the basic substitutions. configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/remillConfig_vcpkg.cmake.in" + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/remillConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/remillConfig.cmake" @ONLY ) diff --git a/cmake/remillConfig.cmake.in b/cmake/remillConfig.cmake.in index d488b78f0..074ed39dd 100644 --- a/cmake/remillConfig.cmake.in +++ b/cmake/remillConfig.cmake.in @@ -12,79 +12,60 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.2) +@PACKAGE_INIT@ -if(NOT TARGET remill) - if(WIN32) - set(REMILL_LIBRARY_LOCATION "@CMAKE_INSTALL_PREFIX@/remill/lib/remill.lib") - set(REMILL_INCLUDE_LOCATION "@CMAKE_INSTALL_PREFIX@/remill/include") - else() - set(REMILL_LIBRARY_LOCATION "@CMAKE_INSTALL_PREFIX@/lib/libremill.a") - set(REMILL_INCLUDE_LOCATION "@CMAKE_INSTALL_PREFIX@/include") +foreach(_comp ${remill_FIND_COMPONENTS}) + if (NOT "VCPKG_DEPS" STREQUAL _comp) + set(remill_FOUND False) + set(remill_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}. Only VCPKG_DEPS") endif() - - # For Linux builds, group LLVM libraries into a single group - # that avoids frustrating library ordering issues. - 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 "") + + if ("VCPKG_DEPS" STREQUAL _comp) + set(remill_setup_vcpkg True) + if(NOT "x@VCPKG_ROOT@x" STREQUAL "xx" AND NOT USE_SYSTEM_DEPENDENCIES) + if (EXISTS "@VCPKG_ROOT@") + set(VCPKG_ROOT "@VCPKG_ROOT@" + CACHE PATH "Location of dependency libraries" + ) + include(${CMAKE_CURRENT_LIST_DIR}/vcpkg_helper.cmake) + message(STATUS "Found VCPKG_ROOT: ${VCPKG_ROOT}") + set(vcpkgdeps_FOUND) + endif() + endif() endif() +endforeach() +if(NOT remill_setup_vcpkg AND NOT TARGET remill) set(LLVM_MAJOR_VERSION @LLVM_MAJOR_VERSION@) set(LLVM_MINOR_VERSION @LLVM_MINOR_VERSION@) set(REMILL_LLVM_VERSION "@LLVM_MAJOR_VERSION@.@LLVM_MINOR_VERSION@") - - add_library(remill_bc STATIC IMPORTED) - set_property(TARGET remill_bc PROPERTY IMPORTED_LOCATION "@REMILL_BC_LIBRARY_LOCATION@") - - add_library(remill_os STATIC IMPORTED) - set_property(TARGET remill_os PROPERTY IMPORTED_LOCATION "@REMILL_OS_LIBRARY_LOCATION@") - - add_library(remill_arch STATIC IMPORTED) - set_property(TARGET remill_arch PROPERTY IMPORTED_LOCATION "@REMILL_ARCH_LIBRARY_LOCATION@") - - add_library(remill_arch_x86 STATIC IMPORTED) - set_property(TARGET remill_arch_x86 PROPERTY IMPORTED_LOCATION "@REMILL_ARCH_X86_LIBRARY_LOCATION@") - - add_library(remill_arch_aarch32 STATIC IMPORTED) - set_property(TARGET remill_arch_aarch32 PROPERTY IMPORTED_LOCATION "@REMILL_ARCH_AARCH32_LIBRARY_LOCATION@") - - add_library(remill_arch_aarch64 STATIC IMPORTED) - set_property(TARGET remill_arch_aarch64 PROPERTY IMPORTED_LOCATION "@REMILL_ARCH_AARCH64_LIBRARY_LOCATION@") - - add_library(remill_arch_sparc32 STATIC IMPORTED) - set_property(TARGET remill_arch_sparc32 PROPERTY IMPORTED_LOCATION "@REMILL_ARCH_SPARC32_LIBRARY_LOCATION@") - - add_library(remill_arch_sparc64 STATIC IMPORTED) - set_property(TARGET remill_arch_sparc64 PROPERTY IMPORTED_LOCATION "@REMILL_ARCH_SPARC64_LIBRARY_LOCATION@") - - add_library(remill_version STATIC IMPORTED) - set_property(TARGET remill_version PROPERTY IMPORTED_LOCATION "@REMILL_VERSION_LIBRARY_LOCATION@") - - add_library(remill INTERFACE) - target_link_libraries(remill INTERFACE - ${LINKER_START_GROUP} - remill_bc - remill_os - remill_arch - remill_arch_x86 - remill_arch_aarch32 - remill_arch_aarch64 - remill_arch_sparc32 - remill_arch_sparc64 - remill_version - @THIRDPARTY_LIBRARY_FILES@ - ${LINKER_END_GROUP} - ) - - target_include_directories(remill INTERFACE @THIRDPARTY_INCLUDE_DIRECTORIES@) - target_include_directories(remill INTERFACE @REMILL_INCLUDE_LOCATION@) - target_compile_options(remill INTERFACE @REMILL_COMPILE_OPTIONS@) - target_compile_definitions(remill INTERFACE @REMILL_COMPILE_DEFINITIONS@) - # Add a dummy 'semantics' target to satisfy the protobuf generator - add_custom_target(semantics) + # External libs + include(CMakeFindDependencyMacro) + find_dependency(XED) + find_dependency(glog) + find_dependency(LLVM) + # NOTE: If changing this, also replicate in CMakeLists.txt + if (LLVM_WITH_Z3) + find_dependency(Z3) + 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() + + # Exported Targets + include("${CMAKE_CURRENT_LIST_DIR}/remillTargets.cmake") + + if(TARGET thirdparty_llvm) + # Need this so that LLVM doesn't hardcode it's include directories + set_target_properties(thirdparty_llvm PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${LLVM_INCLUDE_DIRS}" + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${LLVM_INCLUDE_DIRS}" + ) + endif() + endif() + +set(remill_setup_vcpkg False) diff --git a/cmake/remillConfig_vcpkg.cmake.in b/cmake/remillConfig_vcpkg.cmake.in deleted file mode 100644 index bff71bd52..000000000 --- a/cmake/remillConfig_vcpkg.cmake.in +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (c) 2020 Trail of Bits, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -@PACKAGE_INIT@ - -foreach(_comp ${remill_FIND_COMPONENTS}) - if (NOT "VCPKG_DEPS" STREQUAL _comp) - set(remill_FOUND False) - set(remill_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}. Only VCPKG_DEPS") - endif() - - if ("VCPKG_DEPS" STREQUAL _comp) - set(remill_setup_vcpkg True) - if(NOT "x@VCPKG_ROOT@x" STREQUAL "xx" AND NOT USE_SYSTEM_DEPENDENCIES) - if (EXISTS "@VCPKG_ROOT@") - set(VCPKG_ROOT "@VCPKG_ROOT@" - CACHE PATH "Location of dependency libraries" - ) - include(${CMAKE_CURRENT_LIST_DIR}/vcpkg_helper.cmake) - message(STATUS "Found VCPKG_ROOT: ${VCPKG_ROOT}") - set(vcpkgdeps_FOUND) - endif() - endif() - endif() -endforeach() - -if(NOT remill_setup_vcpkg AND NOT TARGET remill) - set(LLVM_MAJOR_VERSION @LLVM_MAJOR_VERSION@) - set(LLVM_MINOR_VERSION @LLVM_MINOR_VERSION@) - set(REMILL_LLVM_VERSION "@LLVM_MAJOR_VERSION@.@LLVM_MINOR_VERSION@") - - # External libs - include(CMakeFindDependencyMacro) - find_dependency(XED) - find_dependency(glog) - find_dependency(LLVM) - # NOTE: If changing this, also replicate in CMakeLists.txt - if (LLVM_WITH_Z3) - find_dependency(Z3) - 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() - - # Exported Targets - include("${CMAKE_CURRENT_LIST_DIR}/remillTargets.cmake") - -endif() - -set(remill_setup_vcpkg False) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 94ed7c41b..3b42912fb 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -158,7 +158,7 @@ function(GetPublicIncludeFolders output_variable) set("${output_variable}" ${collected_include_dirs} PARENT_SCOPE) endfunction() -function(InstallExternalTarget target_name target_path install_directory installed_file_name) +function(InstallExternalTarget target_name target_path install_type installed_file_name) # Get the optional rpath parameter set(additional_arguments ${ARGN}) list(LENGTH additional_arguments additional_argument_count) @@ -195,8 +195,8 @@ function(InstallExternalTarget target_name target_path install_directory install message(FATAL_ERROR "InstallExternalTarget: The following target already exists: ${target_name}") endif() - if("${install_directory}" STREQUAL "") - message(FATAL_ERROR "InstallExternalTarget: Invalid install directory specified") + if("${install_type}" STREQUAL "") + message(FATAL_ERROR "InstallExternalTarget: Invalid install type specified") endif() # Generate the target @@ -218,7 +218,7 @@ function(InstallExternalTarget target_name target_path install_directory install add_custom_target("${target_name}" ALL DEPENDS "${output_file_path}") install(FILES "${output_file_path}" - DESTINATION "${install_directory}" + TYPE ${install_type} PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE diff --git a/cmake/utils_vcpkg.cmake b/cmake/utils_vcpkg.cmake deleted file mode 100644 index 3b42912fb..000000000 --- a/cmake/utils_vcpkg.cmake +++ /dev/null @@ -1,227 +0,0 @@ -cmake_minimum_required(VERSION 3.2) - -function(FindAndSelectClangCompiler) - if(DEFINED ENV{LLVM_INSTALL_PREFIX}) - set(LLVM_INSTALL_PREFIX $ENV{LLVM_INSTALL_PREFIX} PARENT_SCOPE) - endif() - - if(DEFINED LLVM_INSTALL_PREFIX) - list(APPEND FINDPACKAGE_LLVM_HINTS "${LLVM_INSTALL_PREFIX}/lib/cmake/llvm/") - list(APPEND FINDPACKAGE_LLVM_HINTS "${LLVM_INSTALL_PREFIX}/share/llvm/cmake/") - set(FINDPACKAGE_LLVM_HINTS ${FINDPACKAGE_LLVM_HINTS} PARENT_SCOPE) - - message(STATUS "Using LLVM_INSTALL_PREFIX hints for find_package(LLVM): ${FINDPACKAGE_LLVM_HINTS}") - endif() - - if(DEFINED WIN32) - set(executable_extension ".exe") - else() - set(executable_extension "") - endif() - - # it is important to avoid re-defining these variables if they have been already - # set or you risk ending up in a configure loop! - if(NOT DEFINED CMAKE_C_COMPILER) - if(DEFINED LLVM_INSTALL_PREFIX) - set(CMAKE_C_COMPILER "${LLVM_INSTALL_PREFIX}/bin/clang${executable_extension}" - CACHE PATH "Path to clang binary." FORCE) - else() - set(CMAKE_C_COMPILER "clang" PARENT_SCOPE) - endif() - endif() - - if(NOT DEFINED CMAKE_CXX_COMPILER) - if(DEFINED LLVM_INSTALL_PREFIX) - set(CMAKE_CXX_COMPILER "${LLVM_INSTALL_PREFIX}/bin/clang++${executable_extension}" - CACHE PATH "Path to clang++ binary." FORCE) - else() - set(CMAKE_CXX_COMPILER "clang++${executable_extension}" PARENT_SCOPE) - endif() - endif() - - if(NOT DEFINED CMAKE_ASM_COMPILER) - if(DEFINED LLVM_INSTALL_PREFIX) - set(CMAKE_ASM_COMPILER "${LLVM_INSTALL_PREFIX}/bin/clang++${executable_extension}" - CACHE PATH "Path to assembler (aka clang) binary." FORCE) - else() - set(CMAKE_ASM_COMPILER ${CMAKE_CXX_COMPILER} PARENT_SCOPE) - endif() - endif() - - if(NOT DEFINED CMAKE_LLVM_LINK) - if(DEFINED LLVM_INSTALL_PREFIX) - set(CMAKE_LLVM_LINK "${LLVM_INSTALL_PREFIX}/bin/llvm-link${executable_extension}" - CACHE PATH "Path to llvm-link binary." FORCE) - else() - set(CMAKE_LLVM_LINK "llvm-link${executable_extension}" PARENT_SCOPE) - endif() - endif() -endfunction() - -function(GetTargetTree output_variable) - if(${ARGC} LESS 1) - message(FATAL_ERROR "Usage: GetTargetTree output_var target1 target2 ...") - endif() - - foreach(target ${ARGN}) - list(APPEND queue "${target}") - endforeach() - - while(true) - # Update the queue - unset(new_queue) - - foreach(target ${queue}) - list(APPEND visited_dependencies "${target}") - - if (NOT TARGET "${target}") - continue() - endif() - - # Always reset to empty value - set(target_link_libs "target_link_libs-NOTFOUND") - set(target_interface_link_libs "target_interface_link_libs-NOTFOUND") - - # Skip utility targets - get_target_property(target_type "${target}" TYPE) - if("${target_type}" STREQUAL "UTILITY") - continue() - endif() - - # Collect the results - unset(new_queue_candidates) - - # We can only get LINK_LIBRARIES from normal targets - if(NOT "${target_type}" STREQUAL "INTERFACE_LIBRARY") - get_target_property(target_link_libs "${target}" LINK_LIBRARIES) - if(NOT "${target_link_libs}" STREQUAL "target_link_libs-NOTFOUND") - list(APPEND new_queue_candidates ${target_link_libs}) - endif() - endif() - - # INTERFACE_LINK_LIBRARIES are potentially always present - get_target_property(target_interface_link_libs "${target}" INTERFACE_LINK_LIBRARIES) - if(NOT "${target_interface_link_libs}" STREQUAL "target_interface_link_libs-NOTFOUND") - list(APPEND new_queue_candidates ${target_interface_link_libs}) - endif() - - # Try to find the actual file - if ("${target_type}" STREQUAL "UNKNOWN_LIBRARY" OR - "${target_type}" STREQUAL "STATIC_LIBRARY" OR - "${target_type}" STREQUAL "SHARED_LIBRARY" OR - "${target_type}" STREQUAL "IMPORTED_LIBRARY") - get_target_property(target_imported_loc "${target}" IMPORTED_LOCATION) - if(NOT "${target_imported_loc}" STREQUAL "target_imported_loc-NOTFOUND") - list(APPEND new_queue_candidates "${target_imported_loc}") - endif() - endif() - - foreach(queue_candidate ${new_queue_candidates}) - list(FIND visited_dependencies "${queue_candidate}" visited) - if(visited EQUAL -1) - list(APPEND new_queue "${queue_candidate}") - endif() - endforeach() - endforeach() - - list(LENGTH new_queue new_queue_size) - if(${new_queue_size} EQUAL 0) - break() - endif() - - set(queue ${new_queue}) - endwhile() - - list(REVERSE visited_dependencies) - list(REMOVE_DUPLICATES visited_dependencies) - list(REVERSE visited_dependencies) - set("${output_variable}" ${visited_dependencies} PARENT_SCOPE) -endfunction() - -function(GetPublicIncludeFolders output_variable) - if(${ARGC} LESS 1) - message(FATAL_ERROR "Usage: GetPublicIncludeFolders output_var target1 target2 ...") - endif() - - foreach(target ${ARGN}) - if (NOT TARGET "${target}") - continue() - endif() - - get_target_property(include_dir_list "${target}" INTERFACE_INCLUDE_DIRECTORIES) - if(NOT "${include_dir_list}" STREQUAL "include_dir_list-NOTFOUND") - list(APPEND collected_include_dirs "${include_dir_list}") - endif() - endforeach() - - list(REMOVE_DUPLICATES collected_include_dirs) - set("${output_variable}" ${collected_include_dirs} PARENT_SCOPE) -endfunction() - -function(InstallExternalTarget target_name target_path install_type installed_file_name) - # Get the optional rpath parameter - set(additional_arguments ${ARGN}) - list(LENGTH additional_arguments additional_argument_count) - - if("${additional_argument_count}" EQUAL 0) - elseif("${additional_argument_count}" EQUAL 1) - list(GET additional_arguments 0 rpath) - else() - message(FATAL_ERROR "InstallExternalTarget: Invalid argument count") - endif() - - # We need to locate the patchelf executable to fix the rpath; search for it - # only once, and then export the variable with PARENT_SCOPE so that we can - # re-use it in the next calls - if(NOT "${rpath}" STREQUAL "") - if("${PATCHELF_LOCATION}" STREQUAL "") - find_program("program_location" "patchelf") - if("${program_location}" STREQUAL "program_location-NOTFOUND") - message(FATAL_ERROR "InstallExternalTarget: Failed to locate the patchelf executable") - endif() - - # We need to set it both in local and in parent scope - set("PATCHELF_LOCATION" "${program_location}" PARENT_SCOPE) - set("PATCHELF_LOCATION" "${program_location}") - endif() - endif() - - # Make sure the parameters are correct - if(NOT EXISTS "${target_path}") - message(FATAL_ERROR "InstallExternalTarget: The following path does not exists: ${target_path}") - endif() - - if("${target_name}") - message(FATAL_ERROR "InstallExternalTarget: The following target already exists: ${target_name}") - endif() - - if("${install_type}" STREQUAL "") - message(FATAL_ERROR "InstallExternalTarget: Invalid install type specified") - endif() - - # Generate the target - set("output_file_path" "${CMAKE_CURRENT_BINARY_DIR}/${installed_file_name}") - - if(NOT "${rpath}" STREQUAL "") - set(CHRPATH_COMMAND ${PATCHELF_LOCATION} --set-rpath ${rpath} ${output_file_path}) - else() - set(CHRPATH_COMMAND ${CMAKE_COMMAND} -E echo 'No rpath patch needed for ${target_name}') - endif() - - add_custom_command( - OUTPUT "${output_file_path}" - - COMMAND "${CMAKE_COMMAND}" -E copy ${target_path} ${output_file_path} - COMMAND ${CHRPATH_COMMAND} - ) - - add_custom_target("${target_name}" ALL DEPENDS "${output_file_path}") - - install(FILES "${output_file_path}" - TYPE ${install_type} - PERMISSIONS OWNER_READ OWNER_EXECUTE - GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE - ) -endfunction() -