Skip to content

Commit b8af211

Browse files
committed
Fancier CMake: find scripts, out-of-tree example builds
1 parent 5f5785f commit b8af211

File tree

23 files changed

+493
-226
lines changed

23 files changed

+493
-226
lines changed

CMakeLists.txt

+42-76
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
22

3-
project(binaryninjaapi)
3+
project(binaryninjaapi CXX C)
4+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
45

56
option(BN_API_BUILD_EXAMPLES "Builds example plugins" OFF)
67

@@ -14,35 +15,6 @@ if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
1415
endif()
1516
endif()
1617

17-
if(WIN32)
18-
if(NOT BN_INSTALL_DIR)
19-
set(BN_INSTALL_DIR "C:\\Program Files\\Vector35\\BinaryNinja"
20-
CACHE PATH "Binary Ninja installation directory")
21-
endif()
22-
set(BN_INSTALL_BIN_DIR "${BN_INSTALL_DIR}"
23-
CACHE PATH "Binary Ninja binary directory")
24-
set(BN_USER_PLUGINS_DIR "$ENV{APPDATA}/Binary Ninja/plugins"
25-
CACHE PATH "Binary Ninja user plugins directory")
26-
elseif(APPLE)
27-
if(NOT BN_INSTALL_DIR)
28-
set(BN_INSTALL_DIR "/Applications/Binary Ninja.app"
29-
CACHE PATH "Binary Ninja installation directory")
30-
endif()
31-
set(BN_INSTALL_BIN_DIR "${BN_INSTALL_DIR}/Contents/MacOS"
32-
CACHE PATH "Binary Ninja binary directory")
33-
set(BN_USER_PLUGINS_DIR "$ENV{HOME}/Library/Application Support/Binary Ninja/plugins"
34-
CACHE PATH "Binary Ninja user plugins directory")
35-
else()
36-
if(NOT BN_INSTALL_DIR)
37-
set(BN_INSTALL_DIR "$ENV{HOME}/binaryninja"
38-
CACHE PATH "Binary Ninja installation directory")
39-
endif()
40-
set(BN_INSTALL_BIN_DIR "${BN_INSTALL_DIR}"
41-
CACHE PATH "Binary Ninja binary directory")
42-
set(BN_USER_PLUGINS_DIR "$ENV{HOME}/.binaryninja/plugins"
43-
CACHE PATH "Binary Ninja user plugins directory")
44-
endif()
45-
4618
file(GLOB BN_API_SOURCES *.cpp *.h json/json.h json/json-forwards.h)
4719
if(NOT DEMO)
4820
list(APPEND BN_API_SOURCES json/jsoncpp.cpp)
@@ -53,70 +25,64 @@ add_library(binaryninjaapi STATIC ${BN_API_SOURCES})
5325
target_include_directories(binaryninjaapi
5426
PUBLIC ${PROJECT_SOURCE_DIR})
5527

56-
# We only need to find the core and UI when we also build the examples
57-
if((NOT BN_CORE_LIBRARY) AND (NOT BN_INTERNAL_BUILD))
58-
find_library(BN_CORE_LIBRARY REQUIRED
59-
NAMES binaryninjacore libbinaryninjacore.so.1
60-
PATHS ${BN_INSTALL_BIN_DIR})
28+
find_package(BinaryNinjaCore REQUIRED)
29+
target_link_libraries(binaryninjaapi PUBLIC ${BinaryNinjaCore_LIBRARIES})
30+
target_link_directories(binaryninjaapi PUBLIC ${BinaryNinjaCore_LIBRARY_DIRS})
31+
target_compile_definitions(binaryninjaapi PUBLIC ${BinaryNinjaCore_DEFINITIONS})
6132

62-
if(BN_CORE_LIBRARY)
63-
message(STATUS "Binary Ninja Core: ${BN_CORE_LIBRARY}")
64-
else()
65-
message(FATAL_ERROR "Binary Ninja Core Not Found")
66-
endif()
67-
endif()
33+
set_target_properties(binaryninjaapi PROPERTIES
34+
CXX_STANDARD 17
35+
CXX_VISIBILITY_PRESET hidden
36+
CXX_STANDARD_REQUIRED ON
37+
VISIBILITY_INLINES_HIDDEN ON
38+
POSITION_INDEPENDENT_CODE ON
39+
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/out)
6840

6941
if(NOT HEADLESS)
70-
if((NOT BN_UI_LIBRARY) AND (NOT BN_INTERNAL_BUILD))
71-
find_library(BN_UI_LIBRARY REQUIRED
72-
NAMES binaryninjaui libbinaryninjaui.so.1
73-
PATHS ${BN_INSTALL_BIN_DIR})
74-
75-
if(BN_UI_LIBRARY)
76-
message(STATUS "Binary Ninja UI: ${BN_UI_LIBRARY}")
42+
if(NOT BN_INTERNAL_BUILD)
43+
# For backwards compatibility, include binaryninjaui in the api module
44+
# If you don't need it, you can safely ignore these warnings
45+
46+
find_package(BinaryNinjaUI)
47+
if(BinaryNinjaUI_FOUND)
48+
# Precompiled ui library
49+
add_library(binaryninjaui INTERFACE)
50+
target_link_libraries(binaryninjaui INTERFACE ${BinaryNinjaUI_LIBRARIES})
51+
target_link_directories(binaryninjaui INTERFACE ${BinaryNinjaUI_LIBRARY_DIRS})
52+
target_compile_definitions(binaryninjaui INTERFACE ${BinaryNinjaUI_DEFINITIONS})
53+
54+
# UI headers are in here
55+
target_include_directories(binaryninjaui INTERFACE ${PROJECT_SOURCE_DIR}/ui)
7756
else()
78-
message(FATAL_ERROR "Binary Ninja UI Not Found")
57+
# Add a fake target for binaryninjaui to intentionally break anything that tries to link against it,
58+
# since the find script failed and your build would otherwise break in less obvious places.
59+
add_custom_target(binaryninjaui
60+
COMMAND ${CMAKE_COMMAND} -E false)
61+
message(WARNING "Binary Ninja UI not found but -DHEADLESS was not specified. You will not be able to build UI plugins.")
7962
endif()
80-
endif()
81-
endif()
82-
83-
if(NOT BN_INTERNAL_BUILD)
84-
target_link_libraries(binaryninjaapi PUBLIC ${BN_CORE_LIBRARY})
85-
target_link_directories(binaryninjaapi PUBLIC ${BN_INSTALL_BIN_DIR})
86-
else()
87-
target_link_libraries(binaryninjaapi PUBLIC binaryninjacore)
88-
endif()
89-
90-
if(NOT HEADLESS)
91-
target_include_directories(binaryninjaapi PUBLIC ${PROJECT_SOURCE_DIR}/ui)
92-
93-
if(NOT BN_INTERNAL_BUILD)
94-
target_link_libraries(binaryninjaapi PUBLIC ${BN_UI_LIBRARY})
95-
target_link_directories(binaryninjaapi PUBLIC ${BN_INSTALL_BIN_DIR})
9663
else()
9764
# Nothing
9865
endif()
9966
endif()
10067

101-
set_target_properties(binaryninjaapi PROPERTIES
102-
CXX_STANDARD 17
103-
CXX_VISIBILITY_PRESET hidden
104-
CXX_STANDARD_REQUIRED ON
105-
VISIBILITY_INLINES_HIDDEN ON
106-
POSITION_INDEPENDENT_CODE ON
107-
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/out)
108-
10968
function(bn_install_plugin target)
11069
if(NOT BN_INTERNAL_BUILD)
70+
# Get API source directory so we can find BinaryNinjaCore
71+
get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR)
72+
message(STATUS "${BN_API_SOURCE_DIR}")
73+
list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake")
74+
75+
# BinaryNinjaCore has the user plugins dir define that we want
76+
find_package(BinaryNinjaCore REQUIRED)
11177
if(WIN32)
11278
install(TARGETS ${target} RUNTIME
113-
DESTINATION ${BN_USER_PLUGINS_DIR})
79+
DESTINATION ${BinaryNinjaCore_USER_PLUGINS_DIR})
11480

11581
install(FILES $<TARGET_PDB_FILE:${target}>
116-
DESTINATION ${BN_USER_PLUGINS_DIR} OPTIONAL)
82+
DESTINATION ${BinaryNinjaCore_USER_PLUGINS_DIR} OPTIONAL)
11783
else()
11884
install(TARGETS ${target} LIBRARY
119-
DESTINATION ${BN_USER_PLUGINS_DIR})
85+
DESTINATION ${BinaryNinjaCore_USER_PLUGINS_DIR})
12086
endif()
12187
endif()
12288
endfunction()

Makefile.win

-67
This file was deleted.

cmake/FindBinaryNinjaCore.cmake

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Try to find a Binary Ninja installation
2+
# Once done this will define
3+
# BinaryNinjaCore_FOUND - If Binary Ninja Core is found
4+
# BinaryNinjaCore_ROOT_DIR - The installation path of Binary Ninja
5+
# BinaryNinjaCore_USER_PLUGINS_DIR - The path for user plugins
6+
# BinaryNinjaCore_INCLUDE_DIRS - The directories to include for compiling core plugins
7+
# BinaryNinjaCore_LIBRARIES - The libraries for linking core plugins
8+
# BinaryNinjaCore_LIBRARY_DIRS - The link paths required for core plugins
9+
# BinaryNinjaCore_DEFINITIONS - Compiler switches required for core plugins
10+
#
11+
# According to Good CMake Hygiene, we should use BinaryNinjaCore_<VAR> named variables.
12+
# Existing plugins likely use BN_<VAR> names already, so both are provided.
13+
14+
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
15+
16+
if(NOT BN_INTERNAL_BUILD)
17+
set(PATH_HINTS "$ENV{BN_INSTALL_DIR}")
18+
if(WIN32)
19+
# System-wide install
20+
list(APPEND PATH_HINTS "C:\\Program Files\\Vector35\\BinaryNinja")
21+
# User install
22+
list(APPEND PATH_HINTS "$ENV{LocalAppData}\\Vector35\\BinaryNinja")
23+
elseif(APPLE)
24+
list(APPEND PATH_HINTS "/Applications/Binary Ninja.app/Contents/MacOS")
25+
list(APPEND PATH_HINTS "$ENV{HOME}/Applications/Binary Ninja.app/Contents/MacOS")
26+
list(APPEND PATH_HINTS "$ENV{BN_INSTALL_DIR}/Contents/MacOS")
27+
else()
28+
list(APPEND PATH_HINTS "$ENV{HOME}/binaryninja")
29+
endif()
30+
31+
find_library(CORE_LIBRARY
32+
NAMES binaryninjacore libbinaryninjacore.so.1
33+
HINTS ${PATH_HINTS})
34+
35+
include(FindPackageHandleStandardArgs)
36+
find_package_handle_standard_args(BinaryNinjaCore
37+
FOUND_VAR BinaryNinjaCore_FOUND
38+
REQUIRED_VARS CORE_LIBRARY
39+
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.")
40+
41+
message(STATUS "Found Binary Ninja Core: ${CORE_LIBRARY}")
42+
43+
set(BinaryNinjaCore_INCLUDE_DIRS "")
44+
set(BinaryNinjaCore_LIBRARIES "${CORE_LIBRARY}")
45+
set(BinaryNinjaCore_DEFINITIONS "")
46+
47+
get_filename_component(INSTALL_BIN_DIR "${CORE_LIBRARY}" DIRECTORY)
48+
message(STATUS "Binary Ninja Link Dirs: ${INSTALL_BIN_DIR}")
49+
50+
if(WIN32)
51+
set(BinaryNinjaCore_LIBRARY_DIRS "${INSTALL_BIN_DIR}")
52+
set(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}")
53+
set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{APPDATA}\\Binary Ninja\\plugins")
54+
elseif(APPLE)
55+
set(BinaryNinjaCore_LIBRARY_DIRS "${INSTALL_BIN_DIR}")
56+
# Binary Ninja.app/Contents/MacOS/binaryninja -> Binary Ninja.app/
57+
get_filename_component(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}" DIRECTORY)
58+
get_filename_component(BinaryNinjaCore_ROOT_DIR "${BinaryNinjaCore_ROOT_DIR}" DIRECTORY)
59+
set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{HOME}/Library/Application Support/Binary Ninja/plugins")
60+
else()
61+
set(BinaryNinjaCore_LIBRARY_DIRS "${INSTALL_BIN_DIR}")
62+
set(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}")
63+
set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{HOME}/.binaryninja/plugins")
64+
endif()
65+
66+
message(STATUS "Binary Ninja Install Dir: ${BinaryNinjaCore_ROOT_DIR}")
67+
message(STATUS "Binary Ninja User Plugins Dir: ${BinaryNinjaCore_USER_PLUGINS_DIR}")
68+
69+
# Compatibility
70+
set(BN_FOUND "${BinaryNinjaCore_FOUND}")
71+
set(BN_INSTALL_DIR "${BinaryNinjaCore_ROOT_DIR}")
72+
set(BN_INSTALL_BIN_DIR "${INSTALL_BIN_DIR}")
73+
set(BN_USER_PLUGINS_DIR "${BinaryNinjaCore_USER_PLUGINS_DIR}")
74+
set(BN_CORE_LIBRARY "${CORE_LIBRARY}")
75+
set(BN_CORE_DEFINITIONS "${BinaryNinjaCore_DEFINITIONS}")
76+
else()
77+
# Internal build
78+
set(INSTALL_BIN_DIR "${BN_CORE_OUTPUT_DIR}")
79+
80+
if(WIN32)
81+
set(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}")
82+
set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{APPDATA}\\Binary Ninja\\plugins")
83+
elseif(APPLE)
84+
# Binary Ninja.app/Contents/MacOS/binaryninja -> Binary Ninja.app/
85+
get_filename_component(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}" DIRECTORY)
86+
get_filename_component(BinaryNinjaCore_ROOT_DIR "${BinaryNinjaCore_ROOT_DIR}" DIRECTORY)
87+
set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{HOME}/Library/Application Support/Binary Ninja/plugins")
88+
else()
89+
set(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}")
90+
set(BinaryNinjaCore_USER_PLUGINS_DIR "$ENV{HOME}/.binaryninja/plugins")
91+
endif()
92+
93+
set(BinaryNinjaCore_FOUND 1)
94+
set(BinaryNinjaCore_ROOT_DIR "${INSTALL_BIN_DIR}")
95+
set(BinaryNinjaCore_INCLUDE_DIRS "")
96+
set(BinaryNinjaCore_LIBRARIES binaryninjacore)
97+
set(BinaryNinjaCore_LIBRARY_DIRS "${INSTALL_BIN_DIR}")
98+
set(BinaryNinjaCore_DEFINITIONS "")
99+
100+
message(STATUS "Found Binary Ninja Core: binaryninjacore")
101+
message(STATUS "Binary Ninja Link Dirs: ${INSTALL_BIN_DIR}")
102+
message(STATUS "Binary Ninja Install Dir: ${BinaryNinjaCore_ROOT_DIR}")
103+
message(STATUS "Binary Ninja User Plugins Dir: ${BinaryNinjaCore_USER_PLUGINS_DIR}")
104+
105+
set(BN_FOUND "${BinaryNinjaCore_FOUND}")
106+
set(BN_INSTALL_DIR "${BinaryNinjaCore_ROOT_DIR}")
107+
set(BN_INSTALL_BIN_DIR "${INSTALL_BIN_DIR}")
108+
set(BN_USER_PLUGINS_DIR "${BinaryNinjaCore_USER_PLUGINS_DIR}")
109+
set(BN_CORE_LIBRARY binaryninjacore)
110+
set(BN_CORE_DEFINITIONS "${BinaryNinjaCore_DEFINITIONS}")
111+
endif()

cmake/FindBinaryNinjaUI.cmake

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Try to find Binary Ninja UI
2+
# Once done this will define
3+
# BinaryNinjaUI_FOUND - If Binary Ninja UI is found
4+
# BinaryNinjaUI_INCLUDE_DIRS - The directories to include for compiling UI plugins
5+
# BinaryNinjaUI_LIBRARIES - The libraries for linking UI plugins
6+
# BinaryNinjaUI_LIBRARY_DIRS - The link paths required for ui plugins
7+
# BinaryNinjaUI_DEFINITIONS - Compiler switches required for UI plugins
8+
9+
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
10+
11+
find_package(BinaryNinjaCore REQUIRED)
12+
13+
find_library(UI_LIBRARY
14+
NAMES binaryninjaui libbinaryninjaui.so.1
15+
HINTS ${BinaryNinjaCore_LIBRARY_DIRS})
16+
17+
# Use qmake to find the qt6 cmake libs, if we have it in PATH
18+
find_program(QMAKE_COMMAND qmake)
19+
if(QMAKE_COMMAND)
20+
# qmake will tell us where the libs are!
21+
execute_process(
22+
COMMAND ${QMAKE_COMMAND} -query QT_INSTALL_LIBS
23+
OUTPUT_VARIABLE QT_LIB_PATH
24+
OUTPUT_STRIP_TRAILING_WHITESPACE)
25+
26+
# Qt cmake files are in QT_INSTALL_LIBS/cmake
27+
set(QT_CMAKE_PATH "${QT_LIB_PATH}/cmake")
28+
message(STATUS "Found Qt CMake path: ${QT_CMAKE_PATH}")
29+
list(APPEND CMAKE_MODULE_PATH ${QT_CMAKE_PATH})
30+
endif()
31+
32+
# Also find Qt6 which is required
33+
find_package(Qt6 COMPONENTS Core Gui Widgets)
34+
35+
include(FindPackageHandleStandardArgs)
36+
find_package_handle_standard_args(BinaryNinjaUI
37+
FOUND_VAR BinaryNinjaUI_FOUND
38+
REQUIRED_VARS UI_LIBRARY Qt6_FOUND
39+
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.")
40+
41+
if(NOT Qt6_FOUND)
42+
message(WARNING "Could not find Qt6! Make sure qmake is in your PATH.")
43+
else()
44+
message(STATUS "Found Binary Ninja UI: ${UI_LIBRARY}")
45+
endif()
46+
47+
# UI headers are added in the api cmake
48+
set(BinaryNinjaUI_INCLUDE_DIRS "")
49+
50+
set(BinaryNinjaUI_LIBRARIES "${UI_LIBRARY}")
51+
list(APPEND BinaryNinjaUI_LIBRARIES Qt6::Core)
52+
list(APPEND BinaryNinjaUI_LIBRARIES Qt6::Gui)
53+
list(APPEND BinaryNinjaUI_LIBRARIES Qt6::Widgets)
54+
set(BinaryNinjaUI_DEFINITIONS "")
55+
set(BinaryNinjaUI_LIBRARY_DIRS "${BinaryNinjaCore_LIBRARY_DIRS}")
56+
57+
# Compatibility
58+
set(BN_UI_LIBRARY "${UI_LIBRARY}")
59+
set(BN_UI_LIBRARY_DIRS "${BinaryNinjaUI_LIBRARY_DIRS}")
60+
set(BN_UI_DEFINITIONS "${BinaryNinjaUI_DEFINITIONS}")
61+
62+
63+

0 commit comments

Comments
 (0)