├── .gitignore ├── LICENSE ├── README.md ├── build.py └── cmake ├── IDA.cmake └── template.vcxproj.user /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Joel Höner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | IDA plugin CMake build-script 2 | ============================= 3 | 4 | This repository holds CMake build scripts and a Python helper allowing 5 | compilation of C++ IDA plugins for Windows, macOS and Linux without 6 | much user effort. 7 | 8 | ## Simple plugin example usage: 9 | 10 | ##### Create plugin repo 11 | ```bash 12 | git init myplugin 13 | cd myplugin 14 | git submodule add https://github.com/zyantific/ida-cmake.git ida-cmake 15 | mkdir src 16 | touch src/myplugin.cpp CMakeLists.txt 17 | ``` 18 | 19 | ##### CMakeLists.txt 20 | ```CMake 21 | cmake_minimum_required(VERSION 3.1) 22 | project(myplugin) 23 | 24 | include("ida-cmake/cmake/IDA.cmake") 25 | 26 | set(sources "src/myplugin.cpp") 27 | add_ida_plugin(${CMAKE_PROJECT_NAME} ${sources}) 28 | ``` 29 | 30 | ##### src/myplugin.cpp 31 | ```cpp 32 | #include 33 | #include 34 | #include 35 | 36 | /** 37 | * @brief Initialization callback for IDA. 38 | * @return A @c PLUGIN_ constant from loader.hpp. 39 | */ 40 | int idaapi init() 41 | { 42 | msg("%s", "Hello, IDA plugin world!\n"); 43 | return PLUGIN_KEEP; 44 | } 45 | 46 | /** 47 | * @brief Run callback for IDA. 48 | */ 49 | void idaapi run(int /*arg*/) {} 50 | 51 | /** 52 | * @brief Shutdown callback for IDA. 53 | */ 54 | void idaapi term() {} 55 | 56 | plugin_t PLUGIN = 57 | { 58 | IDP_INTERFACE_VERSION, 59 | 0, 60 | &init, 61 | &term, 62 | &run, 63 | "My plugin name", 64 | "My plugin description", 65 | "My plugin menu entry text", 66 | nullptr, // plugin hotkey, e.g. "Ctrl-Shift-A" 67 | }; 68 | ``` 69 | 70 | ##### Building and installing the plugin for IDA 6.95 on macOS 71 | ```bash 72 | ida-cmake/build.py -i -t 6.95 \ 73 | --idaq-path '/Applications/IDA Pro 6.95.app/Contents/MacOS/' 74 | ``` 75 | Substitute `` with a directory of the IDA SDK corresponding to your IDA version. 76 | -------------------------------------------------------------------------------- /build.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | The MIT License (MIT) 5 | 6 | Copyright (c) 2017 Joel Hoener 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from __future__ import absolute_import, division, print_function, unicode_literals 26 | 27 | import os 28 | import errno 29 | import argparse 30 | import glob 31 | 32 | from subprocess import Popen, PIPE 33 | from distutils.spawn import find_executable 34 | 35 | 36 | def get_build_cmd(): 37 | return {'posix': 'make', 'nt': 'MSBuild'}[os.name] 38 | 39 | def get_cmake_gen(target_version): 40 | if os.name == 'posix': 41 | return 'Unix Makefiles' 42 | elif os.name == 'nt': 43 | gen = 'Visual Studio ' + ( 44 | '10' if target_version[0] <= 6 and target_version[1] <= 8 else '14' 45 | ) 46 | return (gen + ' Win64') if target_version >= (7, 0) else gen 47 | else: 48 | assert False 49 | 50 | def get_build_solution_arguments(build_dir): 51 | build_bin = get_build_cmd() 52 | if os.name == 'nt': 53 | sln, = glob.glob(os.path.join(build_dir, '*.sln')) 54 | sln = os.path.basename(sln) 55 | return [build_bin, sln, '/p:Configuration=Release'] 56 | elif os.name == 'posix': 57 | # Speed things up a little. 58 | from multiprocessing import cpu_count 59 | return [build_bin, '-j%d' % cpu_count()] 60 | else: 61 | assert False 62 | 63 | def get_install_solution_arguments(): 64 | build_bin = get_build_cmd() 65 | if os.name == 'nt': 66 | return [build_bin, 'INSTALL.vcxproj', '/p:Configuration=Release'] 67 | elif os.name == 'posix': 68 | return [build_bin, 'install', 'VERBOSE=1'] 69 | else: 70 | assert False 71 | 72 | 73 | if __name__ == '__main__': 74 | # 75 | # Parse arguments 76 | # 77 | parser = argparse.ArgumentParser( 78 | description='Build script compiling and installing the plugin.' 79 | ) 80 | 81 | target_args = parser.add_argument_group('target configuration') 82 | target_args.add_argument( 83 | '--ida-sdk', '-i', type=str, required=True, 84 | help='Path to the IDA SDK' 85 | ) 86 | target_args.add_argument( 87 | '--target-version', '-t', required=True, 88 | help='IDA versions to build for (e.g. 6.9).' 89 | ) 90 | target_args.add_argument( 91 | '--idaq-path', type=str, required=False, 92 | help='Path with idaq binary, used for installing the plugin. ' 93 | 'On unix-like platforms, also required for linkage.' 94 | 95 | ) 96 | target_args.add_argument( 97 | '--ea', required=False, choices=[32, 64], type=int, 98 | help='The IDA variant (ida/ida64, sizeof(ea_t) == 4/8) to build for. ' 99 | 'If omitted, build both.' 100 | ) 101 | 102 | parser.add_argument( 103 | '--skip-install', action='store_true', default=False, 104 | help='Do not execute install target' 105 | ) 106 | parser.add_argument( 107 | 'cmake_args', default='', type=str, nargs=argparse.REMAINDER, 108 | help='Additional arguments passed to CMake' 109 | ) 110 | args = parser.parse_args() 111 | 112 | def print_usage(error=None): 113 | parser.print_usage() 114 | if error: 115 | print(error) 116 | exit() 117 | 118 | # Parse target version 119 | target_version = args.target_version.strip().split('.') 120 | try: 121 | target_version = int(target_version[0]), int(target_version[1]) 122 | except (ValueError, IndexError): 123 | print_usage('[-] Invalid version format, expected something like "6.5"') 124 | 125 | # Supported platform? 126 | if os.name not in ('nt', 'posix'): 127 | print('[-] Unsupported platform') 128 | 129 | # Unix specific sanity checks 130 | if os.name == 'posix' and not args.idaq_path: 131 | print_usage('[-] On unix-like platforms, --idaq-path is required.') 132 | 133 | # 134 | # Find tools 135 | # 136 | cmake_bin = find_executable('cmake') 137 | build_bin = find_executable(get_build_cmd()) 138 | if not cmake_bin: 139 | print_usage('[-] Unable to find CMake binary') 140 | if not build_bin: 141 | print_usage('[-] Unable to find build (please use Visual Studio MSBuild CMD or make)') 142 | 143 | # 144 | # Build targets 145 | # 146 | for ea in (args.ea,) if args.ea else (32, 64): 147 | build_dir = 'build-{}.{}-{}'.format(*(target_version + (ea,))) 148 | try: 149 | os.mkdir(build_dir) 150 | except OSError as e: 151 | if e.errno != errno.EEXIST: 152 | raise 153 | 154 | # Run cmake 155 | cmake_cmd = [ 156 | cmake_bin, 157 | '-DIDA_SDK=' + args.ida_sdk, 158 | '-G', get_cmake_gen(target_version), 159 | '-DIDA_VERSION={}{:02}'.format(*target_version), 160 | '-DIDA_BINARY_64=' + ('ON' if target_version >= (7, 0) else 'OFF') 161 | ] 162 | 163 | if args.idaq_path: 164 | cmake_cmd.append('-DIDA_INSTALL_DIR=' + args.idaq_path) 165 | cmake_cmd.append('-DCMAKE_INSTALL_PREFIX=' + args.idaq_path) 166 | 167 | if ea == 64: 168 | cmake_cmd.append('-DIDA_EA_64=TRUE') 169 | 170 | cmake_cmd.append('..') 171 | 172 | print('CMake command:') 173 | print(' '.join("'%s'" % x if ' ' in x else x for x in cmake_cmd)) 174 | 175 | proc = Popen(cmake_cmd, cwd=build_dir) 176 | if proc.wait() != 0: 177 | print('[-] CMake failed, giving up.') 178 | exit() 179 | 180 | # Build plugin 181 | proc = Popen(get_build_solution_arguments(build_dir), cwd=build_dir) 182 | if proc.wait() != 0: 183 | print('[-] Build failed, giving up.') 184 | exit() 185 | 186 | if not args.skip_install and args.idaq_path: 187 | # Install plugin 188 | proc = Popen(get_install_solution_arguments(), cwd=build_dir) 189 | if proc.wait() != 0: 190 | print('[-] Install failed, giving up.') 191 | exit() 192 | 193 | print('[+] Done!') 194 | -------------------------------------------------------------------------------- /cmake/IDA.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # The MIT License (MIT) 3 | # 4 | # Copyright (c) 2017 Joel Höner 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | # THE SOFTWARE. 23 | # 24 | 25 | cmake_minimum_required(VERSION 3.1) 26 | cmake_policy(SET CMP0054 NEW) 27 | 28 | # =============================================================================================== # 29 | # Overridable options # 30 | # =============================================================================================== # 31 | 32 | set(IDA_BINARY_64 OFF CACHE BOOL "Build a 64 bit binary (IDA >= 7.0)" ) 33 | set(IDA_EA_64 OFF CACHE BOOL "Build for 64 bit IDA (ida64, sizeof(ea_t) == 8)") 34 | set(IDA_SDK "" CACHE PATH "Path to IDA SDK" ) 35 | set(IDA_INSTALL_DIR "" CACHE PATH "Install path of IDA" ) 36 | set(IDA_VERSION 690 CACHE INT "IDA Version to build for (e.g. 6.9 is 690)." ) 37 | set(IDA_ENABLE_QT_SUPPORT OFF CACHE BOOL "Enable support for building plugins with Qt" ) 38 | 39 | # =============================================================================================== # 40 | # General preparation # 41 | # =============================================================================================== # 42 | 43 | if (IDA_VERSION LESS 690) 44 | message(FATAL_ERROR "IDA versions below 6.9 are no longer supported.") 45 | endif () 46 | 47 | # We need to save our path here so we have it available in functions later on. 48 | set(ida_cmakelist_path ${CMAKE_CURRENT_LIST_DIR}) 49 | 50 | # Library dependencies and include pathes 51 | if (WIN32) 52 | if (IDA_EA_64) 53 | set(ida_lib_path_ea "64") 54 | else () 55 | set(ida_lib_path_ea "32") 56 | endif () 57 | 58 | if (IDA_BINARY_64) 59 | set(ida_lib_path_binarch "x64") 60 | else () 61 | set(ida_lib_path_binarch "x64") 62 | endif () 63 | 64 | # On Windows, we use HR's lib files shipped with the SDK. 65 | set(IDA_LIB_DIR "${IDA_SDK}/lib/${ida_lib_path_binarch}_win_vc_${ida_lib_path_ea}" 66 | CACHE PATH "IDA SDK library path" FORCE) 67 | 68 | message(STATUS "IDA library path: ${IDA_LIB_DIR}") 69 | 70 | if (NOT EXISTS ${IDA_LIB_DIR}) 71 | set(IDA_LIB_DIR NOTFOUND) 72 | endif () 73 | 74 | find_library(IDA_IDA_LIBRARY NAMES "ida" PATHS ${IDA_LIB_DIR} REQUIRED) 75 | list(APPEND ida_libraries ${IDA_IDA_LIBRARY}) 76 | find_library(IDA_PRO_LIBRARY NAMES "pro" PATHS ${IDA_LIB_DIR}) 77 | if (IDA_PRO_LIBRARY) 78 | list(APPEND ida_libraries ${IDA_PRO_LIBRARY}) 79 | endif () 80 | elseif (UNIX) 81 | if (NOT IDA_BINARY_64) 82 | set(CMAKE_C_FLAGS "-m32" CACHE STRING "C compiler flags" FORCE) 83 | set(CMAKE_CXX_FLAGS "-m32" CACHE STRING "C++ compiler flags" FORCE) 84 | endif () 85 | 86 | # On unixoid platforms, we link against IDA directly. 87 | if (IDA_EA_64) 88 | find_library(IDA_IDA_LIBRARY NAMES "ida64" PATHS ${IDA_INSTALL_DIR} REQUIRED) 89 | else () 90 | find_library(IDA_IDA_LIBRARY NAMES "ida" PATHS ${IDA_INSTALL_DIR} REQUIRED) 91 | endif () 92 | list(APPEND ida_libraries ${IDA_IDA_LIBRARY}) 93 | endif () 94 | 95 | set(ida_libraries ${ida_libraries} CACHE INTERNAL "IDA libraries" FORCE) 96 | 97 | # =============================================================================================== # 98 | # Qt support # 99 | # =============================================================================================== # 100 | 101 | if (IDA_ENABLE_QT_SUPPORT) 102 | set(CMAKE_AUTOMOC ON) 103 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 104 | 105 | set(ida_qt_libs "Gui;Core;Widgets") 106 | 107 | # Locate Qt. 108 | find_package(Qt5Widgets REQUIRED) 109 | 110 | # On unixes, we link against the Qt libs that ship with IDA. 111 | # On Windows with IDA versions >= 7.0, link against .libs in IDA SDK. 112 | if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR 113 | (${CMAKE_SYSTEM_NAME} STREQUAL "Windows" AND NOT ${IDA_VERSION} LESS 700)) 114 | 115 | if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") 116 | set(ida_qt_glob_path "${IDA_INSTALL_DIR}/../Frameworks/Qt@QTLIB@") 117 | elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") 118 | set(ida_qt_glob_path "${IDA_INSTALL_DIR}/libQt5@QTLIB@.so*") 119 | elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") 120 | set(ida_qt_glob_path "${IDA_SDK}/lib/x64_win_qt/Qt5@QTLIB@.lib") 121 | endif () 122 | 123 | foreach(cur_lib ${ida_qt_libs}) 124 | string(REPLACE "@QTLIB@" ${cur_lib} cur_glob_path ${ida_qt_glob_path}) 125 | file(GLOB_RECURSE qtlibpaths ${cur_glob_path}) 126 | # On some platforms, we will find more than one libfile here. 127 | # Either one is fine, just pick the first. 128 | foreach(p ${qtlibpaths}) 129 | set(IDA_Qt${cur_lib}_LIBRARY ${p} CACHE FILEPATH "Path to IDA's Qt${cur_lib}") 130 | break() 131 | endforeach() 132 | endforeach() 133 | 134 | # On Windows, we hack Qt's "IMPLIB"s, on unix the .so location. 135 | if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") 136 | set(lib_property "IMPORTED_IMPLIB_RELEASE") 137 | else () 138 | set(lib_property "IMPORTED_LOCATION_RELEASE") 139 | endif () 140 | 141 | foreach (cur_lib ${ida_qt_libs}) 142 | set_target_properties( 143 | "Qt5::${cur_lib}" 144 | PROPERTIES 145 | ${lib_property} "${IDA_Qt${cur_lib}_LIBRARY}") 146 | endforeach() 147 | endif () 148 | endif () 149 | 150 | # =============================================================================================== # 151 | # Functions for adding IDA plugin targets # 152 | # =============================================================================================== # 153 | 154 | function (add_ida_plugin plugin_name) 155 | set(sources ${ARGV}) 156 | if (sources) 157 | list(REMOVE_AT sources 0) 158 | endif () 159 | 160 | # Define target 161 | string(STRIP "${sources}" sources) 162 | add_library(${plugin_name} SHARED ${sources}) 163 | 164 | # Compiler specific properties. 165 | if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 166 | target_compile_definitions(${plugin_name} PUBLIC "__VC__") 167 | target_compile_options(${plugin_name} PUBLIC "/wd4996" "/MP") 168 | endif () 169 | 170 | # General definitions required throughout all kind of IDA modules. 171 | target_compile_definitions(${plugin_name} PUBLIC 172 | "NO_OBSOLETE_FUNCS" 173 | "__IDP__") 174 | 175 | target_include_directories(${plugin_name} PUBLIC "${IDA_SDK}/include") 176 | 177 | if (IDA_BINARY_64) 178 | target_compile_definitions(${plugin_name} PUBLIC "__X64__") 179 | endif () 180 | 181 | # OS specific stuff. 182 | if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") 183 | target_compile_definitions(${plugin_name} PUBLIC "__NT__") 184 | 185 | if (IDA_BINARY_64) 186 | if (IDA_EA_64) 187 | set(plugin_extension "64.dll") 188 | else () 189 | set(plugin_extension ".dll") 190 | endif () 191 | else () 192 | if (IDA_EA_64) 193 | set(plugin_extension ".p64") 194 | else() 195 | set(plugin_extension ".plw") 196 | endif() 197 | endif () 198 | elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") 199 | target_compile_definitions(${plugin_name} PUBLIC "__MAC__") 200 | 201 | if (IDA_BINARY_64) 202 | if (IDA_EA_64) 203 | set(plugin_extension "64.dylib") 204 | else () 205 | set(plugin_extension ".dylib") 206 | endif () 207 | else () 208 | if (IDA_EA_64) 209 | set(plugin_extension ".pmc64") 210 | else() 211 | set(plugin_extension ".pmc") 212 | endif() 213 | endif () 214 | elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") 215 | target_compile_definitions(${plugin_name} PUBLIC "__LINUX__") 216 | 217 | if (IDA_BINARY_64) 218 | if (IDA_EA_64) 219 | set(plugin_extension "64.so") 220 | else () 221 | set(plugin_extension ".so") 222 | endif () 223 | else () 224 | if (IDA_EA_64) 225 | set(plugin_extension ".plx64") 226 | else() 227 | set(plugin_extension ".plx") 228 | endif() 229 | endif () 230 | endif () 231 | 232 | # Suppress "lib" prefix on Unix and alter the file extension. 233 | set_target_properties(${plugin_name} PROPERTIES 234 | PREFIX "" 235 | SUFFIX ${plugin_extension} 236 | OUTPUT_NAME ${plugin_name}) 237 | 238 | if (IDA_EA_64) 239 | target_compile_definitions(${plugin_name} PUBLIC "__EA64__") 240 | endif () 241 | 242 | # Link against IDA (or the SDKs libs on Windows). 243 | target_link_libraries(${plugin_name} ${ida_libraries}) 244 | 245 | # Define install rule 246 | install(TARGETS ${plugin_name} DESTINATION plugins) 247 | 248 | # When generating for Visual Studio, 249 | # generate user file for convenient debugging support. 250 | if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 251 | if (IDA_VERSION LESS 700) 252 | if (IDA_EA_64) 253 | set(idaq_exe "idaq64.exe") 254 | else () 255 | set(idaq_exe "idaq.exe") 256 | endif () 257 | else () 258 | if (IDA_EA_64) 259 | set(idaq_exe "ida64.exe") 260 | else () 261 | set(idaq_exe "ida.exe") 262 | endif () 263 | endif () 264 | 265 | file( 266 | TO_NATIVE_PATH 267 | "${IDA_INSTALL_DIR}/${idaq_exe}" 268 | idaq_exe_native_path) 269 | configure_file( 270 | "${ida_cmakelist_path}/template.vcxproj.user" 271 | "${plugin_name}.vcxproj.user" 272 | @ONLY) 273 | endif () 274 | endfunction (add_ida_plugin) 275 | 276 | # =============================================================================================== # 277 | # Functions for adding IDA plugin targets with Qt support # 278 | # =============================================================================================== # 279 | 280 | function (add_ida_qt_plugin plugin_name) 281 | set(sources ${ARGV}) 282 | if (sources) 283 | list(REMOVE_AT sources 0) 284 | endif () 285 | 286 | # Divide between UI and resource files and regular C/C++ sources. 287 | foreach (cur_file ${sources}) 288 | if (${cur_file} MATCHES ".*\\.ui") 289 | list(APPEND ui_sources ${cur_file}) 290 | elseif (${cur_file} MATCHES ".*\\.qrc") 291 | list(APPEND rsrc_sources ${cur_file}) 292 | else () 293 | list(APPEND non_ui_sources ${cur_file}) 294 | endif () 295 | endforeach () 296 | 297 | # Compile UI files. 298 | QT5_WRAP_UI(form_headers ${ui_sources}) 299 | 300 | # Compile resources. 301 | QT5_ADD_RESOURCES(rsrc_headers ${rsrc_sources}) 302 | 303 | # Add plugin. 304 | add_ida_plugin(${plugin_name} ${non_ui_sources} ${form_headers} ${rsrc_headers}) 305 | target_compile_definitions(${plugin_name} PUBLIC "QT_NAMESPACE=QT") 306 | 307 | # Link against Qt. 308 | foreach (qtlib Core;Gui;Widgets) 309 | if (DEFINED IDA_QtCore_LIBRARY) 310 | set_target_properties( 311 | "Qt5::${qtlib}" 312 | PROPERTIES 313 | IMPORTED_LOCATION_RELEASE "${IDA_Qt${qtlib}_LIBRARY}") 314 | endif () 315 | target_link_libraries(${CMAKE_PROJECT_NAME} "Qt5::${qtlib}") 316 | endforeach() 317 | endfunction () 318 | -------------------------------------------------------------------------------- /cmake/template.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @idaq_exe_native_path@ 5 | WindowsLocalDebugger 6 | 7 | 8 | @idaq_exe_native_path@ 9 | WindowsLocalDebugger 10 | 11 | 12 | @idaq_exe_native_path@ 13 | WindowsLocalDebugger 14 | 15 | 16 | @idaq_exe_native_path@ 17 | WindowsLocalDebugger 18 | 19 | --------------------------------------------------------------------------------