# # The MIT License (MIT) # # Copyright (c) 2014 athre0z # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # cmake_minimum_required(VERSION 2.8.12) project(REtypedef) option(IDA_ARCH_64 "Build plugin for 64 bit IDA" False) if (NOT DEFINED ida_sdk) set(ida_sdk $ENV{IDASDK}) endif () if (!WIN32) message(SEND_ERROR "Sorry, currently only Win32 platform is supported.") endif () if (NOT CONFIGURED_ONCE) # Compiler specific switches if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(compiler_specific "-m32 -std=c++0x -Werror") set(ida_lib_path_compiler "gcc") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(compiler_specific "/WX /wd4996 /MP /D__VC__") set(ida_lib_path_compiler "vc") # Hack for MSVC to always use /MD, even when generating debug code set(manipulated_vars CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO) foreach(cur_var ${manipulated_vars}) string(REGEX REPLACE "/(LD|(M(T|D)))d?( +|$)" "/MD " new_var ${${cur_var}}) string(REGEX REPLACE "(/|-)D *_DEBUG" "" new_var ${new_var}) set(${cur_var} ${new_var} CACHE STRING "" FORCE) endforeach() endif () # OS specific switches if (WIN32) set(os_specific "-D_WIN32_WINNT=0x0501 -D__NT__") set(ida_lib_path_platform "win") if (IDA_ARCH_64) set(plugin_extension ".p64") else() set(plugin_extension ".plw") endif() elseif (UNIX) set(os_specific "-D__LINUX__") set(ida_lib_path_platform "linux") if (IDA_ARCH_64) message(SEND_ERROR "FIXME: What is the file extension here?") else() set(plugin_extension ".plx") endif() elseif (APPLE) # Untested! set(os_specific "-D__MAC__ -D_FORTIFY_SOURCE=0") set(ida_lib_path_platform "mac") if (IDA_ARCH_64) message(SEND_ERROR "FIXME: What is the file extension here?") else() set(plugin_extension ".pmc") endif() endif () # IDA target architecture specific if (IDA_ARCH_64) set(ida_lib_path_arch "64") set(arch_specific "-D__EA64__") else () set(ida_lib_path_arch "32") endif () # Check if we are inside a GIT repo set(git_scan_cur_dir ${CMAKE_CURRENT_LIST_DIR}) set(git_scan_counter 0) while (git_scan_counter LESS 32) if (EXISTS "${git_scan_cur_dir}/.git") # Yep, we are. Obtain SHA1 of current head message(STATUS "git root located at ${git_scan_cur_dir}") execute_process(COMMAND git rev-parse HEAD RESULT_VARIABLE git_return_val OUTPUT_VARIABLE git_head_sha1 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" OUTPUT_STRIP_TRAILING_WHITESPACE) if (NOT git_return_val EQUAL 0) set(git_head_sha1 "unknown") endif () message(STATUS "git revision SHA-1: ${git_head_sha1}") set(git_defs "-DGIT_HEAD_SHA1=\\\"${git_head_sha1}\\\"") break() endif () set(git_scan_cur_dir "${git_scan_cur_dir}/..") math(EXPR git_scan_counter "${git_scan_counter}+1") endwhile () set(IDA_LIB_DIR "${ida_sdk}/lib/x86_${ida_lib_path_platform}_${ida_lib_path_compiler}_${ida_lib_path_arch}" CACHE PATH "IDA SDK library path" FORCE) message(STATUS "IDA library path: ${IDA_LIB_DIR}") if (NOT EXISTS ${IDA_LIB_DIR}) set(IDA_LIB_DIR, NOTFOUND) endif() set(plugin_extension "${plugin_extension}" CACHE INTERNAL "Plugin file extension" FORCE) set(other_defs "-DQT_NAMESPACE=QT -DNO_OBSOLETE_FUNCS -D__IDP__ -DQPROJECT_LIBRARY") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${compiler_specific} ${os_specific} ${arch_specific} ${git_defs} ${other_defs}" CACHE STRING "Flags used by the compiler during all build types." FORCE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${compiler_specific} ${os_specific} ${arch_specific} ${git_defs} ${other_defs}" CACHE STRING "Flags used by the compiler during all build types." FORCE) endif () # Locate relevant files set(project_headers Core.hpp Config.hpp InlineDetour.hpp Settings.hpp Utils.hpp Ui.hpp SubstitutionManager.hpp ImportExport.hpp REtypedef.hpp) set(project_sources Core.cpp InlineDetour.cpp REtypedef.cpp Settings.cpp Utils.cpp Ui.cpp SubstitutionManager.cpp ImportExport.cpp) set(project_forms ui/SubstitutionEditor.ui ui/AboutDialog.ui) set(project_resources resources/rsrc.qrc) # Qt set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) find_package(Qt4 REQUIRED QtCore QtGui) QT4_WRAP_UI(project_forms_headers ${project_forms}) QT4_ADD_RESOURCES(project_resources_rcc ${project_resources}) # Hack Qt to use release libraries even when generating debug binaries # for compatibility with IDA. get_cmake_property(all_vars VARIABLES) foreach(cur_var ${all_vars}) string(REGEX MATCH "^(QT_.*LIBRARY)$" lib_match ${cur_var}) if (lib_match) set(${lib_match} "${lib_match}_RELEASE") endif() endforeach() # udis86 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}) include(FindUdis86.cmake) find_package(Udis86 REQUIRED) include_directories(${UDIS86_INCLUDE_DIRS}) # Other dependencies if (WIN32) find_library(ida_ida_library NAMES "ida" PATHS ${IDA_LIB_DIR} REQUIRED) list(APPEND ida_libraries ${ida_ida_library}) find_library(ida_pro_library NAMES "pro" PATHS ${IDA_LIB_DIR}) if (ida_pro_library) list(APPEND ida_libraries ${ida_pro_library}) endif () elseif (UNIX OR APPLE) # We hardwire the path here as the lib lacks the "lib" prefix, making # find_library ignoring it. list(APPEND ida_pro_library "${IDA_LIB_DIR}/pro.a") endif () include_directories("${ida_sdk}/include") # Build target add_library(${CMAKE_PROJECT_NAME} SHARED ${project_headers} ${project_sources} ${project_forms_headers} ${project_resources_rcc}) set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX "${plugin_extension}" OUTPUT_NAME ${CMAKE_PROJECT_NAME}) target_link_libraries(${CMAKE_PROJECT_NAME} Qt4::QtCore Qt4::QtGui) target_link_libraries(${CMAKE_PROJECT_NAME} ${ida_libraries}) target_link_libraries(${CMAKE_PROJECT_NAME} ${UDIS86_LIBRARIES}) # Define install rules file(TO_CMAKE_PATH $ENV{IDADIR} ida_dir) if (ida_dir) set(PLUGIN_INSTALL_PREFIX "${ida_dir}" CACHE STRING "Customizable install prefix") set(CMAKE_INSTALL_PREFIX "${PLUGIN_INSTALL_PREFIX}" CACHE STRING "(see PLUGIN_INSTALL_PREFIX)" FORCE) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") file(TO_NATIVE_PATH "${ida_dir}" IDA_NATIVE_DIR) # When generating for Visual Studio, # generate user file for convenient debugging support. configure_file("template.vcxproj.user" "${CMAKE_PROJECT_NAME}.vcxproj.user" @ONLY) endif () endif () install(TARGETS ${CMAKE_PROJECT_NAME} DESTINATION plugins) set(CONFIGURED_ONCE TRUE CACHE INTERNAL "CMake has configured at least once.")