summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2022-02-01 16:34:18 -0500
committerGlenn Smith <glenn@vector35.com>2022-02-02 19:22:08 -0500
commitb8af211f9a3647687c7e45c0fd04b0768df87ffe (patch)
tree64f13fe262399189d70aadf33e1c6e33f0a74c3e
parent5f5785fd2b1cee6bc9a082e1209de00b1497d410 (diff)
Fancier CMake: find scripts, out-of-tree example builds
-rw-r--r--CMakeLists.txt116
-rw-r--r--Makefile.win67
-rw-r--r--cmake/FindBinaryNinjaCore.cmake111
-rw-r--r--cmake/FindBinaryNinjaUI.cmake63
-rw-r--r--examples/bin-info/CMakeLists.txt13
-rw-r--r--examples/bin-info/Makefile.win9
-rw-r--r--examples/breakpoint/CMakeLists.txt13
-rw-r--r--examples/breakpoint/Makefile.win16
-rw-r--r--examples/cmdline_disasm/CMakeLists.txt13
-rw-r--r--examples/llil_parser/CMakeLists.txt13
-rw-r--r--examples/llil_parser/Makefile.win9
-rw-r--r--examples/mlil_parser/CMakeLists.txt13
-rw-r--r--examples/mlil_parser/Makefile.win9
-rw-r--r--examples/print_syscalls/CMakeLists.txt13
-rw-r--r--examples/print_syscalls/Makefile.win9
-rw-r--r--examples/triage/CMakeLists.txt13
-rw-r--r--examples/uinotification/CMakeLists.txt25
-rw-r--r--examples/workflows/inliner/CMakeLists.txt11
-rw-r--r--examples/workflows/objectivec/CMakeLists.txt11
-rw-r--r--examples/workflows/tailcall/CMakeLists.txt11
-rw-r--r--examples/x86_extension/CMakeLists.txt13
-rw-r--r--rust/examples/basic_script/CMakeLists.txt40
-rw-r--r--scripts/test_build_extern.py106
23 files changed, 492 insertions, 225 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b504c1b4..029c53c2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
-project(binaryninjaapi)
+project(binaryninjaapi CXX C)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
option(BN_API_BUILD_EXAMPLES "Builds example plugins" OFF)
@@ -14,35 +15,6 @@ if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
endif()
endif()
-if(WIN32)
- if(NOT BN_INSTALL_DIR)
- set(BN_INSTALL_DIR "C:\\Program Files\\Vector35\\BinaryNinja"
- CACHE PATH "Binary Ninja installation directory")
- endif()
- set(BN_INSTALL_BIN_DIR "${BN_INSTALL_DIR}"
- CACHE PATH "Binary Ninja binary directory")
- set(BN_USER_PLUGINS_DIR "$ENV{APPDATA}/Binary Ninja/plugins"
- CACHE PATH "Binary Ninja user plugins directory")
-elseif(APPLE)
- if(NOT BN_INSTALL_DIR)
- set(BN_INSTALL_DIR "/Applications/Binary Ninja.app"
- CACHE PATH "Binary Ninja installation directory")
- endif()
- set(BN_INSTALL_BIN_DIR "${BN_INSTALL_DIR}/Contents/MacOS"
- CACHE PATH "Binary Ninja binary directory")
- set(BN_USER_PLUGINS_DIR "$ENV{HOME}/Library/Application Support/Binary Ninja/plugins"
- CACHE PATH "Binary Ninja user plugins directory")
-else()
- if(NOT BN_INSTALL_DIR)
- set(BN_INSTALL_DIR "$ENV{HOME}/binaryninja"
- CACHE PATH "Binary Ninja installation directory")
- endif()
- set(BN_INSTALL_BIN_DIR "${BN_INSTALL_DIR}"
- CACHE PATH "Binary Ninja binary directory")
- set(BN_USER_PLUGINS_DIR "$ENV{HOME}/.binaryninja/plugins"
- CACHE PATH "Binary Ninja user plugins directory")
-endif()
-
file(GLOB BN_API_SOURCES *.cpp *.h json/json.h json/json-forwards.h)
if(NOT DEMO)
list(APPEND BN_API_SOURCES json/jsoncpp.cpp)
@@ -53,70 +25,64 @@ add_library(binaryninjaapi STATIC ${BN_API_SOURCES})
target_include_directories(binaryninjaapi
PUBLIC ${PROJECT_SOURCE_DIR})
-# We only need to find the core and UI when we also build the examples
-if((NOT BN_CORE_LIBRARY) AND (NOT BN_INTERNAL_BUILD))
- find_library(BN_CORE_LIBRARY REQUIRED
- NAMES binaryninjacore libbinaryninjacore.so.1
- PATHS ${BN_INSTALL_BIN_DIR})
+find_package(BinaryNinjaCore REQUIRED)
+target_link_libraries(binaryninjaapi PUBLIC ${BinaryNinjaCore_LIBRARIES})
+target_link_directories(binaryninjaapi PUBLIC ${BinaryNinjaCore_LIBRARY_DIRS})
+target_compile_definitions(binaryninjaapi PUBLIC ${BinaryNinjaCore_DEFINITIONS})
- if(BN_CORE_LIBRARY)
- message(STATUS "Binary Ninja Core: ${BN_CORE_LIBRARY}")
- else()
- message(FATAL_ERROR "Binary Ninja Core Not Found")
- endif()
-endif()
+set_target_properties(binaryninjaapi PROPERTIES
+ CXX_STANDARD 17
+ CXX_VISIBILITY_PRESET hidden
+ CXX_STANDARD_REQUIRED ON
+ VISIBILITY_INLINES_HIDDEN ON
+ POSITION_INDEPENDENT_CODE ON
+ ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/out)
if(NOT HEADLESS)
- if((NOT BN_UI_LIBRARY) AND (NOT BN_INTERNAL_BUILD))
- find_library(BN_UI_LIBRARY REQUIRED
- NAMES binaryninjaui libbinaryninjaui.so.1
- PATHS ${BN_INSTALL_BIN_DIR})
+ if(NOT BN_INTERNAL_BUILD)
+ # For backwards compatibility, include binaryninjaui in the api module
+ # If you don't need it, you can safely ignore these warnings
- if(BN_UI_LIBRARY)
- message(STATUS "Binary Ninja UI: ${BN_UI_LIBRARY}")
+ find_package(BinaryNinjaUI)
+ if(BinaryNinjaUI_FOUND)
+ # Precompiled ui library
+ add_library(binaryninjaui INTERFACE)
+ target_link_libraries(binaryninjaui INTERFACE ${BinaryNinjaUI_LIBRARIES})
+ target_link_directories(binaryninjaui INTERFACE ${BinaryNinjaUI_LIBRARY_DIRS})
+ target_compile_definitions(binaryninjaui INTERFACE ${BinaryNinjaUI_DEFINITIONS})
+
+ # UI headers are in here
+ target_include_directories(binaryninjaui INTERFACE ${PROJECT_SOURCE_DIR}/ui)
else()
- message(FATAL_ERROR "Binary Ninja UI Not Found")
+ # Add a fake target for binaryninjaui to intentionally break anything that tries to link against it,
+ # since the find script failed and your build would otherwise break in less obvious places.
+ add_custom_target(binaryninjaui
+ COMMAND ${CMAKE_COMMAND} -E false)
+ message(WARNING "Binary Ninja UI not found but -DHEADLESS was not specified. You will not be able to build UI plugins.")
endif()
- endif()
-endif()
-
-if(NOT BN_INTERNAL_BUILD)
- target_link_libraries(binaryninjaapi PUBLIC ${BN_CORE_LIBRARY})
- target_link_directories(binaryninjaapi PUBLIC ${BN_INSTALL_BIN_DIR})
-else()
- target_link_libraries(binaryninjaapi PUBLIC binaryninjacore)
-endif()
-
-if(NOT HEADLESS)
- target_include_directories(binaryninjaapi PUBLIC ${PROJECT_SOURCE_DIR}/ui)
-
- if(NOT BN_INTERNAL_BUILD)
- target_link_libraries(binaryninjaapi PUBLIC ${BN_UI_LIBRARY})
- target_link_directories(binaryninjaapi PUBLIC ${BN_INSTALL_BIN_DIR})
else()
# Nothing
endif()
endif()
-set_target_properties(binaryninjaapi PROPERTIES
- CXX_STANDARD 17
- CXX_VISIBILITY_PRESET hidden
- CXX_STANDARD_REQUIRED ON
- VISIBILITY_INLINES_HIDDEN ON
- POSITION_INDEPENDENT_CODE ON
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/out)
-
function(bn_install_plugin target)
if(NOT BN_INTERNAL_BUILD)
+ # Get API source directory so we can find BinaryNinjaCore
+ get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR)
+ message(STATUS "${BN_API_SOURCE_DIR}")
+ list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake")
+
+ # BinaryNinjaCore has the user plugins dir define that we want
+ find_package(BinaryNinjaCore REQUIRED)
if(WIN32)
install(TARGETS ${target} RUNTIME
- DESTINATION ${BN_USER_PLUGINS_DIR})
+ DESTINATION ${BinaryNinjaCore_USER_PLUGINS_DIR})
install(FILES $<TARGET_PDB_FILE:${target}>
- DESTINATION ${BN_USER_PLUGINS_DIR} OPTIONAL)
+ DESTINATION ${BinaryNinjaCore_USER_PLUGINS_DIR} OPTIONAL)
else()
install(TARGETS ${target} LIBRARY
- DESTINATION ${BN_USER_PLUGINS_DIR})
+ DESTINATION ${BinaryNinjaCore_USER_PLUGINS_DIR})
endif()
endif()
endfunction()
diff --git a/Makefile.win b/Makefile.win
deleted file mode 100644
index 6073acda..00000000
--- a/Makefile.win
+++ /dev/null
@@ -1,67 +0,0 @@
-CFLAGS = /EHsc /DWIN32 /nologo
-
-TARGETDIR = bin
-TARGETNAME = libbinaryninjaapi.lib
-TARGET = .\$(TARGETDIR)\$(TARGETNAME)
-
-OBJS = \
- architecture.obj \
- backgroundtask.obj \
- basicblock.obj \
- binaryninjaapi.obj \
- binaryreader.obj \
- binaryview.obj \
- binaryviewtype.obj \
- binarywriter.obj \
- callingconvention.obj \
- databuffer.obj \
- datarenderer.obj \
- downloadprovider.obj \
- demangle.obj \
- fileaccessor.obj \
- filemetadata.obj \
- flowgraph.obj \
- flowgraphnode.obj \
- function.obj \
- functionrecognizer.obj \
- highlevelil.obj \
- highlevelilinstruction.obj \
- interaction.obj \
- linearviewcursor.obj \
- linearviewobject.obj \
- log.obj \
- lowlevelil.obj \
- lowlevelilinstruction.obj \
- mainthread.obj \
- mediumlevelil.obj \
- mediumlevelilinstruction.obj \
- metadata.obj \
- platform.obj \
- plugin.obj \
- pluginmanager.obj \
- relocationhandler.obj \
- scriptingprovider.obj \
- settings.obj \
- tempfile.obj \
- transform.obj \
- type.obj \
- undoaction.obj \
- update.obj \
- user.obj \
- jsoncpp.obj
-
-$(TARGET): $(OBJS)
- if not exist $(TARGETDIR) mkdir $(TARGETDIR)
- lib $(OBJS) /OUT:$(TARGET)
-
-jsoncpp.obj: json\jsoncpp.cpp
- cl $(CFLAGS) /I. /c json\jsoncpp.cpp
-
-# nmake "inference rules" are gnu make "pattern rules"
-.cpp.obj:
- cl $(CFLAGS) /c $<
-
-clean:
- if exist *.obj del *.obj
- if exist $(TARGETDIR) del /Q /S $(TARGETDIR)
-
diff --git a/cmake/FindBinaryNinjaCore.cmake b/cmake/FindBinaryNinjaCore.cmake
new file mode 100644
index 00000000..e497e794
--- /dev/null
+++ b/cmake/FindBinaryNinjaCore.cmake
@@ -0,0 +1,111 @@
+# Try to find a Binary Ninja installation
+# Once done this will define
+# BinaryNinjaCore_FOUND - If Binary Ninja Core is found
+# BinaryNinjaCore_ROOT_DIR - The installation path of Binary Ninja
+# BinaryNinjaCore_USER_PLUGINS_DIR - The path for user plugins
+# BinaryNinjaCore_INCLUDE_DIRS - The directories to include for compiling core plugins
+# BinaryNinjaCore_LIBRARIES - The libraries for linking core plugins
+# BinaryNinjaCore_LIBRARY_DIRS - The link paths required for core plugins
+# BinaryNinjaCore_DEFINITIONS - Compiler switches required for core plugins
+#
+# According to Good CMake Hygiene, we should use BinaryNinjaCore_<VAR> named variables.
+# Existing plugins likely use BN_<VAR> names already, so both are provided.
+
+cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
+
+if(NOT BN_INTERNAL_BUILD)
+ set(PATH_HINTS "$ENV{BN_INSTALL_DIR}")
+ if(WIN32)
+ # System-wide install
+ list(APPEND PATH_HINTS "C:\\Program Files\\Vector35\\BinaryNinja")
+ # User install
+ list(APPEND PATH_HINTS "$ENV{LocalAppData}\\Vector35\\BinaryNinja")
+ elseif(APPLE)
+ list(APPEND PATH_HINTS "/Applications/Binary Ninja.app/Contents/MacOS")
+ list(APPEND PATH_HINTS "$ENV{HOME}/Applications/Binary Ninja.app/Contents/MacOS")
+ list(APPEND PATH_HINTS "$ENV{BN_INSTALL_DIR}/Contents/MacOS")
+ else()
+ list(APPEND PATH_HINTS "$ENV{HOME}/binaryninja")
+ endif()
+
+ find_library(CORE_LIBRARY
+ NAMES binaryninjacore libbinaryninjacore.so.1
+ HINTS ${PATH_HINTS})
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(BinaryNinjaCore
+ FOUND_VAR BinaryNinjaCore_FOUND
+ REQUIRED_VARS CORE_LIBRARY
+ FAIL_MESSAGE "Could NOT find Binary Ninja installation. Please configure with -DBN_INSTALL_DIR=<path to Binary Ninja> or set the BN_INSTALL_DIR environment variable.")
+
+ message(STATUS "Found Binary Ninja Core: ${CORE_LIBRARY}")
+
+ set(BinaryNinjaCore_INCLUDE_DIRS "")
+ set(BinaryNinjaCore_LIBRARIES "${CORE_LIBRARY}")
+ set(BinaryNinjaCore_DEFINITIONS "")
+
+ get_filename_component(INSTALL_BIN_DIR "${CORE_LIBRARY}" DIRECTORY)
+ message(STATUS "Binary Ninja Link Dirs: ${INSTALL_BIN_DIR}")
+
+ if(WIN32)
+ set(BinaryNinjaCore_LIBRARY_DIRS "${INSTALL_BIN_DIR}")
+ set(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}")
+ set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{APPDATA}\\Binary Ninja\\plugins")
+ elseif(APPLE)
+ set(BinaryNinjaCore_LIBRARY_DIRS "${INSTALL_BIN_DIR}")
+ # Binary Ninja.app/Contents/MacOS/binaryninja -> Binary Ninja.app/
+ get_filename_component(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}" DIRECTORY)
+ get_filename_component(BinaryNinjaCore_ROOT_DIR "${BinaryNinjaCore_ROOT_DIR}" DIRECTORY)
+ set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{HOME}/Library/Application Support/Binary Ninja/plugins")
+ else()
+ set(BinaryNinjaCore_LIBRARY_DIRS "${INSTALL_BIN_DIR}")
+ set(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}")
+ set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{HOME}/.binaryninja/plugins")
+ endif()
+
+ message(STATUS "Binary Ninja Install Dir: ${BinaryNinjaCore_ROOT_DIR}")
+ message(STATUS "Binary Ninja User Plugins Dir: ${BinaryNinjaCore_USER_PLUGINS_DIR}")
+
+ # Compatibility
+ set(BN_FOUND "${BinaryNinjaCore_FOUND}")
+ set(BN_INSTALL_DIR "${BinaryNinjaCore_ROOT_DIR}")
+ set(BN_INSTALL_BIN_DIR "${INSTALL_BIN_DIR}")
+ set(BN_USER_PLUGINS_DIR "${BinaryNinjaCore_USER_PLUGINS_DIR}")
+ set(BN_CORE_LIBRARY "${CORE_LIBRARY}")
+ set(BN_CORE_DEFINITIONS "${BinaryNinjaCore_DEFINITIONS}")
+else()
+ # Internal build
+ set(INSTALL_BIN_DIR "${BN_CORE_OUTPUT_DIR}")
+
+ if(WIN32)
+ set(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}")
+ set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{APPDATA}\\Binary Ninja\\plugins")
+ elseif(APPLE)
+ # Binary Ninja.app/Contents/MacOS/binaryninja -> Binary Ninja.app/
+ get_filename_component(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}" DIRECTORY)
+ get_filename_component(BinaryNinjaCore_ROOT_DIR "${BinaryNinjaCore_ROOT_DIR}" DIRECTORY)
+ set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{HOME}/Library/Application Support/Binary Ninja/plugins")
+ else()
+ set(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}")
+ set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{HOME}/.binaryninja/plugins")
+ endif()
+
+ set(BinaryNinjaCore_FOUND 1)
+ set(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}")
+ set(BinaryNinjaCore_INCLUDE_DIRS "")
+ set(BinaryNinjaCore_LIBRARIES binaryninjacore)
+ set(BinaryNinjaCore_LIBRARY_DIRS "${INSTALL_BIN_DIR}")
+ set(BinaryNinjaCore_DEFINITIONS "")
+
+ message(STATUS "Found Binary Ninja Core: binaryninjacore")
+ message(STATUS "Binary Ninja Link Dirs: ${INSTALL_BIN_DIR}")
+ message(STATUS "Binary Ninja Install Dir: ${BinaryNinjaCore_ROOT_DIR}")
+ message(STATUS "Binary Ninja User Plugins Dir: ${BinaryNinjaCore_USER_PLUGINS_DIR}")
+
+ set(BN_FOUND "${BinaryNinjaCore_FOUND}")
+ set(BN_INSTALL_DIR "${BinaryNinjaCore_ROOT_DIR}")
+ set(BN_INSTALL_BIN_DIR "${INSTALL_BIN_DIR}")
+ set(BN_USER_PLUGINS_DIR "${BinaryNinjaCore_USER_PLUGINS_DIR}")
+ set(BN_CORE_LIBRARY binaryninjacore)
+ set(BN_CORE_DEFINITIONS "${BinaryNinjaCore_DEFINITIONS}")
+endif()
diff --git a/cmake/FindBinaryNinjaUI.cmake b/cmake/FindBinaryNinjaUI.cmake
new file mode 100644
index 00000000..608d2d87
--- /dev/null
+++ b/cmake/FindBinaryNinjaUI.cmake
@@ -0,0 +1,63 @@
+# Try to find Binary Ninja UI
+# Once done this will define
+# BinaryNinjaUI_FOUND - If Binary Ninja UI is found
+# BinaryNinjaUI_INCLUDE_DIRS - The directories to include for compiling UI plugins
+# BinaryNinjaUI_LIBRARIES - The libraries for linking UI plugins
+# BinaryNinjaUI_LIBRARY_DIRS - The link paths required for ui plugins
+# BinaryNinjaUI_DEFINITIONS - Compiler switches required for UI plugins
+
+cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
+
+find_package(BinaryNinjaCore REQUIRED)
+
+find_library(UI_LIBRARY
+ NAMES binaryninjaui libbinaryninjaui.so.1
+ HINTS ${BinaryNinjaCore_LIBRARY_DIRS})
+
+# Use qmake to find the qt6 cmake libs, if we have it in PATH
+find_program(QMAKE_COMMAND qmake)
+if(QMAKE_COMMAND)
+ # qmake will tell us where the libs are!
+ execute_process(
+ COMMAND ${QMAKE_COMMAND} -query QT_INSTALL_LIBS
+ OUTPUT_VARIABLE QT_LIB_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ # Qt cmake files are in QT_INSTALL_LIBS/cmake
+ set(QT_CMAKE_PATH "${QT_LIB_PATH}/cmake")
+ message(STATUS "Found Qt CMake path: ${QT_CMAKE_PATH}")
+ list(APPEND CMAKE_MODULE_PATH ${QT_CMAKE_PATH})
+endif()
+
+# Also find Qt6 which is required
+find_package(Qt6 COMPONENTS Core Gui Widgets)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(BinaryNinjaUI
+ FOUND_VAR BinaryNinjaUI_FOUND
+ REQUIRED_VARS UI_LIBRARY Qt6_FOUND
+ FAIL_MESSAGE "Could NOT find Binary Ninja UI installation. Check that you are using a valid Binary Ninja, non-headless install, and qmake is in your PATH.")
+
+if(NOT Qt6_FOUND)
+ message(WARNING "Could not find Qt6! Make sure qmake is in your PATH.")
+else()
+ message(STATUS "Found Binary Ninja UI: ${UI_LIBRARY}")
+endif()
+
+# UI headers are added in the api cmake
+set(BinaryNinjaUI_INCLUDE_DIRS "")
+
+set(BinaryNinjaUI_LIBRARIES "${UI_LIBRARY}")
+list(APPEND BinaryNinjaUI_LIBRARIES Qt6::Core)
+list(APPEND BinaryNinjaUI_LIBRARIES Qt6::Gui)
+list(APPEND BinaryNinjaUI_LIBRARIES Qt6::Widgets)
+set(BinaryNinjaUI_DEFINITIONS "")
+set(BinaryNinjaUI_LIBRARY_DIRS "${BinaryNinjaCore_LIBRARY_DIRS}")
+
+# Compatibility
+set(BN_UI_LIBRARY "${UI_LIBRARY}")
+set(BN_UI_LIBRARY_DIRS "${BinaryNinjaUI_LIBRARY_DIRS}")
+set(BN_UI_DEFINITIONS "${BinaryNinjaUI_DEFINITIONS}")
+
+
+
diff --git a/examples/bin-info/CMakeLists.txt b/examples/bin-info/CMakeLists.txt
index 708136c0..4f0815ac 100644
--- a/examples/bin-info/CMakeLists.txt
+++ b/examples/bin-info/CMakeLists.txt
@@ -1,10 +1,21 @@
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
-project(bin-info CXX)
+project(bin-info CXX C)
add_executable(${PROJECT_NAME}
src/bin-info.cpp)
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
target_link_libraries(${PROJECT_NAME}
binaryninjaapi)
diff --git a/examples/bin-info/Makefile.win b/examples/bin-info/Makefile.win
deleted file mode 100644
index b65bfb86..00000000
--- a/examples/bin-info/Makefile.win
+++ /dev/null
@@ -1,9 +0,0 @@
-BINJA_API_INC_PATH = ..\..\
-BINJA_API_LIB = ..\..\bin\libbinaryninjaapi.lib
-BINJA_CORE_LIB = "c:\Program Files\Vector35\BinaryNinja\binaryninjacore.lib"
-
-FLAGS = /DWIN32 /D__WIN32__ /EHsc /I$(BINJA_API_INC_PATH) /link $(BINJA_API_LIB) $(BINJA_CORE_LIB)
-
-bininfo: ./src/bin-info.cpp
- if not exist bin mkdir bin
- cl ./src/bin-info.cpp $(FLAGS) /Fe:.\bin\bininfo
diff --git a/examples/breakpoint/CMakeLists.txt b/examples/breakpoint/CMakeLists.txt
index 0ec4cb0d..8ede6524 100644
--- a/examples/breakpoint/CMakeLists.txt
+++ b/examples/breakpoint/CMakeLists.txt
@@ -1,10 +1,21 @@
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
-project(breakpoint CXX)
+project(breakpoint CXX C)
add_library(${PROJECT_NAME} SHARED
src/breakpoint.cpp)
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
target_link_libraries(${PROJECT_NAME}
binaryninjaapi)
diff --git a/examples/breakpoint/Makefile.win b/examples/breakpoint/Makefile.win
deleted file mode 100644
index 00cbbfa1..00000000
--- a/examples/breakpoint/Makefile.win
+++ /dev/null
@@ -1,16 +0,0 @@
-BINJA_API_INC_PATH = ..\..\
-BINJA_API_LIB = ..\..\bin\libbinaryninjaapi.lib
-BINJA_CORE_LIB = "c:\Program Files\Vector35\BinaryNinja\binaryninjacore.lib"
-
-FLAGS = /DWIN32 /D__WIN32__ /EHsc /I$(BINJA_API_INC_PATH) /link $(BINJA_API_LIB) $(BINJA_CORE_LIB)
-
-bininfo.dll: ./src/breakpoint.cpp
- if not exist bin mkdir bin
- cl ./src/breakpoint.cpp /LD $(FLAGS) /OUT:.\bin\breakpoint.dll
-
-clean:
- if exist *.obj del *.obj
- if exist *.exp del *.exp
- if exist *.lib del *.lib
- if exist *.dll del *.dll
- if exist .\bin del /S /Q bin
diff --git a/examples/cmdline_disasm/CMakeLists.txt b/examples/cmdline_disasm/CMakeLists.txt
index e4b14da5..2657b920 100644
--- a/examples/cmdline_disasm/CMakeLists.txt
+++ b/examples/cmdline_disasm/CMakeLists.txt
@@ -1,10 +1,21 @@
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
-project(cmdline_disasm CXX)
+project(cmdline_disasm CXX C)
add_executable(${PROJECT_NAME}
src/disasm.cpp)
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
target_link_libraries(${PROJECT_NAME}
binaryninjaapi)
diff --git a/examples/llil_parser/CMakeLists.txt b/examples/llil_parser/CMakeLists.txt
index 899fc8d1..6c57dfd5 100644
--- a/examples/llil_parser/CMakeLists.txt
+++ b/examples/llil_parser/CMakeLists.txt
@@ -1,10 +1,21 @@
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
-project(llil_parser CXX)
+project(llil_parser CXX C)
add_executable(${PROJECT_NAME}
src/llil_parser.cpp)
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
target_link_libraries(${PROJECT_NAME}
binaryninjaapi)
diff --git a/examples/llil_parser/Makefile.win b/examples/llil_parser/Makefile.win
deleted file mode 100644
index fb714c0b..00000000
--- a/examples/llil_parser/Makefile.win
+++ /dev/null
@@ -1,9 +0,0 @@
-BINJA_API_INC_PATH = ..\..\
-BINJA_API_LIB = ..\..\bin\libbinaryninjaapi.lib
-BINJA_CORE_LIB = "c:\Program Files\Vector35\BinaryNinja\binaryninjacore.lib"
-
-FLAGS = /DWIN32 /D__WIN32__ /EHsc /I$(BINJA_API_INC_PATH) /link $(BINJA_API_LIB) $(BINJA_CORE_LIB)
-
-bininfo: ./src/llil_parser.cpp
- if not exist bin mkdir bin
- cl ./src/llil_parser.cpp $(FLAGS) /Fe:.\bin\bininfo
diff --git a/examples/mlil_parser/CMakeLists.txt b/examples/mlil_parser/CMakeLists.txt
index a06a8c8e..ae4947a7 100644
--- a/examples/mlil_parser/CMakeLists.txt
+++ b/examples/mlil_parser/CMakeLists.txt
@@ -1,10 +1,21 @@
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
-project(mlil_parser CXX)
+project(mlil_parser CXX C)
add_executable(${PROJECT_NAME}
src/mlil_parser.cpp)
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
target_link_libraries(${PROJECT_NAME}
binaryninjaapi)
diff --git a/examples/mlil_parser/Makefile.win b/examples/mlil_parser/Makefile.win
deleted file mode 100644
index 92718ac0..00000000
--- a/examples/mlil_parser/Makefile.win
+++ /dev/null
@@ -1,9 +0,0 @@
-BINJA_API_INC_PATH = ..\..\
-BINJA_API_LIB = ..\..\bin\libbinaryninjaapi.lib
-BINJA_CORE_LIB = "c:\Program Files\Vector35\BinaryNinja\binaryninjacore.lib"
-
-FLAGS = /DWIN32 /D__WIN32__ /EHsc /I$(BINJA_API_INC_PATH) /link $(BINJA_API_LIB) $(BINJA_CORE_LIB)
-
-bininfo: ./src/mlil_parser.cpp
- if not exist bin mkdir bin
- cl ./src/mlil_parser.cpp $(FLAGS) /Fe:.\bin\bininfo
diff --git a/examples/print_syscalls/CMakeLists.txt b/examples/print_syscalls/CMakeLists.txt
index 9ef029bb..acdc4073 100644
--- a/examples/print_syscalls/CMakeLists.txt
+++ b/examples/print_syscalls/CMakeLists.txt
@@ -1,10 +1,21 @@
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
-project(print_syscalls CXX)
+project(print_syscalls CXX C)
add_executable(${PROJECT_NAME}
src/arm-syscall.cpp)
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
target_link_libraries(${PROJECT_NAME}
binaryninjaapi)
diff --git a/examples/print_syscalls/Makefile.win b/examples/print_syscalls/Makefile.win
deleted file mode 100644
index afc0cbd8..00000000
--- a/examples/print_syscalls/Makefile.win
+++ /dev/null
@@ -1,9 +0,0 @@
-BINJA_API_INC_PATH = ..\..\
-BINJA_API_LIB = ..\..\bin\libbinaryninjaapi.lib
-BINJA_CORE_LIB = "c:\Program Files\Vector35\BinaryNinja\binaryninjacore.lib"
-
-FLAGS = /DWIN32 /D__WIN32__ /EHsc /I$(BINJA_API_INC_PATH) /link $(BINJA_API_LIB) $(BINJA_CORE_LIB)
-
-print_syscalls: ./src/arm-syscall.cpp
- if not exist bin mkdir bin
- cl ./src/arm-syscall.cpp $(FLAGS) /Fe:.\bin\print_syscalls
diff --git a/examples/triage/CMakeLists.txt b/examples/triage/CMakeLists.txt
index 05dd03ce..ca47f8f9 100644
--- a/examples/triage/CMakeLists.txt
+++ b/examples/triage/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
option(QT6 "Target Qt 6" OFF)
-project(triage)
+project(triage CXX C)
if(NOT QT6)
set(CMAKE_OSX_ARCHITECTURES x86_64)
@@ -18,6 +18,17 @@ else()
add_library(triage SHARED ${SOURCES})
endif()
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
target_link_libraries(triage binaryninjaapi binaryninjaui)
set_target_properties(triage PROPERTIES
diff --git a/examples/uinotification/CMakeLists.txt b/examples/uinotification/CMakeLists.txt
index df9bdbdc..552387dd 100644
--- a/examples/uinotification/CMakeLists.txt
+++ b/examples/uinotification/CMakeLists.txt
@@ -2,32 +2,31 @@ cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
option(QT6 "Target Qt 6" OFF)
-project(uinotification)
+project(uinotification CXX C)
if(NOT QT6)
set(CMAKE_OSX_ARCHITECTURES x86_64)
endif()
-if(QT6)
- find_package(Qt6 COMPONENTS Core Gui Widgets REQUIRED)
-else()
- find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)
-endif()
-
file(GLOB SOURCES
*.cpp
*.h)
add_library(uinotification SHARED ${SOURCES})
-if(QT6)
- target_link_libraries(uinotification binaryninjaapi binaryninjaui
- Qt6::Core Qt6::Gui Qt6::Widgets)
-else()
- target_link_libraries(uinotification binaryninjaapi binaryninjaui
- Qt5::Core Qt5::Gui Qt5::Widgets)
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
endif()
+target_link_libraries(uinotification binaryninjaapi binaryninjaui)
+
set_target_properties(uinotification PROPERTIES
CXX_STANDARD 17
CXX_VISIBILITY_PRESET hidden
diff --git a/examples/workflows/inliner/CMakeLists.txt b/examples/workflows/inliner/CMakeLists.txt
index c42d580e..0a271d4b 100644
--- a/examples/workflows/inliner/CMakeLists.txt
+++ b/examples/workflows/inliner/CMakeLists.txt
@@ -9,6 +9,17 @@ file(GLOB SOURCES
add_library(workflow_inliner SHARED ${SOURCES})
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
target_link_libraries(workflow_inliner binaryninjaapi)
set_target_properties(workflow_inliner PROPERTIES
diff --git a/examples/workflows/objectivec/CMakeLists.txt b/examples/workflows/objectivec/CMakeLists.txt
index f5f8ea5e..a4c0198a 100644
--- a/examples/workflows/objectivec/CMakeLists.txt
+++ b/examples/workflows/objectivec/CMakeLists.txt
@@ -9,6 +9,17 @@ file(GLOB SOURCES
add_library(workflow_objectivec SHARED ${SOURCES})
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
target_link_libraries(workflow_objectivec binaryninjaapi)
set_target_properties(workflow_objectivec PROPERTIES
diff --git a/examples/workflows/tailcall/CMakeLists.txt b/examples/workflows/tailcall/CMakeLists.txt
index fa322684..6d7e5eb0 100644
--- a/examples/workflows/tailcall/CMakeLists.txt
+++ b/examples/workflows/tailcall/CMakeLists.txt
@@ -9,6 +9,17 @@ file(GLOB SOURCES
add_library(workflow_tailcall SHARED ${SOURCES})
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
target_link_libraries(workflow_tailcall binaryninjaapi)
set_target_properties(workflow_tailcall PROPERTIES
diff --git a/examples/x86_extension/CMakeLists.txt b/examples/x86_extension/CMakeLists.txt
index 8980ca60..9faf9c88 100644
--- a/examples/x86_extension/CMakeLists.txt
+++ b/examples/x86_extension/CMakeLists.txt
@@ -1,12 +1,23 @@
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
-project(x86_extension CXX)
+project(x86_extension CXX C)
add_library(${PROJECT_NAME} SHARED
src/x86_extension.cpp
src/asmx86/asmx86.c
src/asmx86/asmx86.h)
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../.. binaryninjaapi $ENV{BN_API_DIR}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
target_link_libraries(${PROJECT_NAME}
binaryninjaapi)
diff --git a/rust/examples/basic_script/CMakeLists.txt b/rust/examples/basic_script/CMakeLists.txt
index a8b8e443..0aaa1a9c 100644
--- a/rust/examples/basic_script/CMakeLists.txt
+++ b/rust/examples/basic_script/CMakeLists.txt
@@ -25,9 +25,29 @@ endif()
set(OUTPUT_FILE basic_script${CMAKE_EXECUTABLE_SUFFIX})
set(OUTPUT_PATH ${CMAKE_BINARY_DIR}/out/bin/${OUTPUT_FILE})
+
+if(NOT BN_API_BUILD_EXAMPLES)
+ # Out-of-tree build
+ find_path(
+ BN_API_DIR
+ NAMES binaryninjaapi.h
+ HINTS ../../.. binaryninjaapi
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_DIR} api)
+endif()
+
add_custom_target(test_headless ALL DEPENDS ${OUTPUT_PATH})
add_dependencies(test_headless binaryninjaapi)
+# Get API source directory so we can find BinaryNinjaCore
+get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR)
+message(STATUS "${BN_API_SOURCE_DIR}")
+list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake")
+
+# BinaryNinjaCore has the user plugins dir define that we want
+find_package(BinaryNinjaCore REQUIRED)
+
find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin)
set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_API_VERSION} cargo build)
@@ -44,13 +64,13 @@ if(APPLE)
add_custom_command(
OUTPUT ${OUTPUT_PATH}
COMMAND ${CMAKE_COMMAND} -E env
- MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BN_CORE_OUTPUT_DIR}
+ MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BN_INSTALL_BIN_DIR}
${RUSTUP_COMMAND} --target=aarch64-apple-darwin ${CARGO_OPTS}
COMMAND ${CMAKE_COMMAND} -E env
- MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BN_CORE_OUTPUT_DIR}
+ MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BN_INSTALL_BIN_DIR}
${RUSTUP_COMMAND} --target=x86_64-apple-darwin ${CARGO_OPTS}
- COMMAND cp ${AARCH64_LIB_PATH} ${OUTPUT_PATH}-aarch
- COMMAND cp ${X86_64_LIB_PATH} ${OUTPUT_PATH}
+ COMMAND ${CMAKE_COMMAND} -E copy ${AARCH64_LIB_PATH} ${OUTPUT_PATH}-aarch
+ COMMAND ${CMAKE_COMMAND} -E copy ${X86_64_LIB_PATH} ${OUTPUT_PATH}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES})
else()
@@ -63,24 +83,24 @@ if(APPLE)
add_custom_command(
OUTPUT ${OUTPUT_PATH}
COMMAND ${CMAKE_COMMAND} -E env
- MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BN_CORE_OUTPUT_DIR}
+ MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BN_INSTALL_BIN_DIR}
${RUSTUP_COMMAND} ${CARGO_OPTS}
- COMMAND cp ${LIB_PATH} ${OUTPUT_PATH}
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIB_PATH} ${OUTPUT_PATH}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES})
endif()
elseif(WIN32)
add_custom_command(
OUTPUT ${OUTPUT_PATH}
- COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BN_CORE_OUTPUT_DIR} ${RUSTUP_COMMAND} ${CARGO_OPTS}
- COMMAND cp ${TARGET_DIR}/${OUTPUT_FILE} ${OUTPUT_PATH}
+ COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BN_INSTALL_BIN_DIR} ${RUSTUP_COMMAND} ${CARGO_OPTS}
+ COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE} ${OUTPUT_PATH}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES})
else()
add_custom_command(
OUTPUT ${OUTPUT_PATH}
- COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BN_CORE_OUTPUT_DIR} ${RUSTUP_COMMAND} ${CARGO_OPTS}
- COMMAND cp ${TARGET_DIR}/${OUTPUT_FILE} ${OUTPUT_PATH}
+ COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BN_INSTALL_BIN_DIR} ${RUSTUP_COMMAND} ${CARGO_OPTS}
+ COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE} ${OUTPUT_PATH}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES})
endif()
diff --git a/scripts/test_build_extern.py b/scripts/test_build_extern.py
new file mode 100644
index 00000000..876b1581
--- /dev/null
+++ b/scripts/test_build_extern.py
@@ -0,0 +1,106 @@
+import argparse
+import glob
+import os
+from pathlib import Path
+import platform
+import shutil
+import subprocess
+import sys
+import tempfile
+
+import argparse
+
+parser = argparse.ArgumentParser(
+ description='Test building the API repo and plugins out-of-tree (for CI checking of end-user workflow)'
+)
+parser.add_argument('--headless', default=False, action='store_true', help='Only include headless plugins')
+parser.add_argument('-j', '--parallel', default=4, help='Number of parallel jobs to tell cmake to run.')
+args = parser.parse_args()
+
+try:
+ # Make sure we have clang!
+ subprocess.check_call(['clang', '-v'])
+except subprocess.SubprocessError as e:
+ print("Clang not found! Please install clang and add it to PATH")
+ sys.exit(1)
+
+if not args.headless:
+ try:
+ # Also Qt
+ subprocess.check_call(['qmake', '--version'])
+ except subprocess.SubprocessError as e:
+ print("qmake not found! Please install Qt and add it to PATH")
+ sys.exit(1)
+
+api_base = Path(__file__).parent.parent.absolute()
+
+configure_args = []
+build_args = []
+configure_env = os.environ.copy()
+
+if platform.system() == "Windows":
+ configure_env['CXXFLAGS'] = f'/MP{args.parallel}'
+ configure_env['CFLAGS'] = f'/MP{args.parallel}'
+else:
+ build_args.extend(['-j', str(args.parallel)])
+
+if args.headless:
+ configure_args.extend(['-DHEADLESS=1'])
+else:
+ configure_args.extend(['-DQT6=1', ])
+
+# Copy api out of the source tree and build it externally
+with tempfile.TemporaryDirectory() as tempdir:
+ temp_api_base = Path(tempdir) / 'binaryninjaapi'
+ print(f'Copy {api_base} => {temp_api_base}')
+ shutil.copytree(api_base, temp_api_base)
+
+ # Clean up dirty repo
+ if (temp_api_base / 'build').exists():
+ shutil.rmtree(temp_api_base / 'build')
+
+ # Now try to build
+ try:
+ subprocess.check_call(['cmake', '-B', 'build'] + configure_args, cwd=temp_api_base, env=configure_env)
+ subprocess.check_call(['cmake', '--build', 'build'] + build_args, cwd=temp_api_base)
+ finally:
+ if (temp_api_base / 'build').exists():
+ shutil.rmtree(temp_api_base / 'build')
+
+ # Now try to build examples (in-tree)
+ try:
+ subprocess.check_call(['cmake', '-B', 'build', '-DBN_API_BUILD_EXAMPLES=1'] + configure_args, cwd=temp_api_base,
+ env=configure_env)
+ subprocess.check_call(['cmake', '--build', 'build'] + build_args, cwd=temp_api_base)
+ finally:
+ if (temp_api_base / 'build').exists():
+ shutil.rmtree(temp_api_base / 'build')
+
+ # Now try to build examples (out-of-tree)
+ for f in glob.glob(str(api_base / 'examples' / '**' / 'CMakeLists.txt'), recursive=True):
+ example_base = Path(f).parent
+ if example_base == api_base / 'examples':
+ continue
+
+ # Check for headless
+ if args.headless:
+ with open(f, 'r') as cmake_file:
+ # Assume any ui plugin has 'binaryninjaui' in its contents
+ if 'binaryninjaui' in cmake_file.read():
+ continue
+
+ with tempfile.TemporaryDirectory() as tempexdir:
+ temp_example_base = Path(tempexdir) / example_base.name
+ print(f'Copy {example_base} => {temp_example_base}')
+ shutil.copytree(example_base, temp_example_base)
+
+ if (temp_example_base / 'build').exists():
+ shutil.rmtree(temp_example_base / 'build')
+
+ try:
+ subprocess.check_call(['cmake', '-B', 'build', f'-DBN_API_DIR={temp_api_base}'] + configure_args,
+ cwd=temp_example_base, env=configure_env)
+ subprocess.check_call(['cmake', '--build', 'build'] + build_args, cwd=temp_example_base)
+ finally:
+ if (temp_example_base / 'build').exists():
+ shutil.rmtree(temp_example_base / 'build')