1
0
mirror of synced 2024-11-28 01:20:51 +01:00

Support macOS

This allows building and running under macOS.
There is still some issues with dpi but the application compiles and run now.
This commit is contained in:
Mary 2020-12-18 21:44:13 +01:00
parent b5cc3b6f1b
commit 310059f274
12 changed files with 107 additions and 12 deletions

View File

@ -10,7 +10,7 @@ env:
jobs: jobs:
lin: linux:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
name: 🐧 Ubuntu 20.04 name: 🐧 Ubuntu 20.04
steps: steps:
@ -138,6 +138,26 @@ jobs:
with: with:
path: msys2/*.zst path: msys2/*.zst
macos-build:
runs-on: macos-11.0
name: 🍎 macOS 11.0
steps:
- name: 🧰 Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: ⬇️ Install dependencies
run: |
brew bundle --no-lock --file dist/Brewfile
- name: ✋ Build
run: |
mkdir build
cd build
CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++ PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" cmake ..
make -j 4
win-test: win-test:
needs: win-makepkg needs: win-makepkg

View File

@ -1,11 +1,14 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(HexEditor) project(HexEditor)
SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL) SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC) SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
# Enforce that we use non system Python 3 on macOS.
set(Python_FIND_FRAMEWORK NEVER)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3) pkg_search_module(GLFW REQUIRED glfw3)
@ -24,6 +27,11 @@ if(Python_VERSION LESS 3)
message(FATAL_ERROR "No valid version of Python 3 was found.") message(FATAL_ERROR "No valid version of Python 3 was found.")
endif() endif()
pkg_search_module(MAGIC libmagic)
if(NOT MAGIC_FOUND)
find_library(MAGIC magic REQUIRED)
endif()
include_directories(include ${GLFW_INCLUDE_DIRS} ${GLM_INCLUDE_DIRS} ${CRYPTO_INCLUDE_DIRS} ${CAPSTONE_INCLUDE_DIRS} ${FREETYPE_INCLUDE_DIRS} ${MAGIC_INCLUDE_DIRS} libs/ImGui/include libs/glad/include ${Python_INCLUDE_DIRS}) include_directories(include ${GLFW_INCLUDE_DIRS} ${GLM_INCLUDE_DIRS} ${CRYPTO_INCLUDE_DIRS} ${CAPSTONE_INCLUDE_DIRS} ${FREETYPE_INCLUDE_DIRS} ${MAGIC_INCLUDE_DIRS} libs/ImGui/include libs/glad/include ${Python_INCLUDE_DIRS})
# Get Python major and minor # Get Python major and minor
@ -89,6 +97,8 @@ add_executable(ImHex
resource.rc resource.rc
) )
set_target_properties(ImHex PROPERTIES CXX_VISIBILITY_PRESET hidden)
target_link_directories(ImHex PRIVATE ${GLFW_LIBRARY_DIRS} ${CRYPTO_LIBRARY_DIRS} ${CAPSTONE_LIBRARY_DIRS} ${MAGIC_LIBRARY_DIRS}) target_link_directories(ImHex PRIVATE ${GLFW_LIBRARY_DIRS} ${CRYPTO_LIBRARY_DIRS} ${CAPSTONE_LIBRARY_DIRS} ${MAGIC_LIBRARY_DIRS})
if (WIN32) if (WIN32)

View File

@ -100,6 +100,9 @@ You need a C++20 compatible compiler such as GCC 10.2.0 to compile ImHex. Moreov
- nlohmann json - nlohmann json
- Python3 - Python3
- freetype2 - freetype2
- Brew (macOS only)
### Windows and Linux
Find all-in-one dependency installation scripts for Arch Linux, Fedora, Debian/Ubuntu and/or MSYS2 in [dist](dist). Find all-in-one dependency installation scripts for Arch Linux, Fedora, Debian/Ubuntu and/or MSYS2 in [dist](dist).
@ -123,6 +126,18 @@ On both Windows and Linux:
- Place your patterns in the `pattern` folder next to your built executable - Place your patterns in the `pattern` folder next to your built executable
- Place your include pattern files in the `include` folder next to your built executable - Place your include pattern files in the `include` folder next to your built executable
### macOS
To build ImHex on macOS, run the following commands:
```sh
brew bundle --no-lock --file dist/Brewfile
mkdir build
cd build
CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++ PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" cmake ..
make -j
```
## Credits ## Credits
- Thanks a lot to ocornut for their amazing [Dear ImGui](https://github.com/ocornut/imgui) which is used for building the entire interface - Thanks a lot to ocornut for their amazing [Dear ImGui](https://github.com/ocornut/imgui) which is used for building the entire interface

12
dist/Brewfile vendored Normal file
View File

@ -0,0 +1,12 @@
brew "glfw3"
brew "openssl@1.1"
brew "capstone"
brew "nlohmann-json"
brew "glm"
brew "cmake"
brew "python3"
brew "freetype2"
brew "libmagic"
# TODO: Remove this when XCode version of clang will support the same level as LLVM 10
brew "llvm"

View File

@ -18,6 +18,33 @@
#include "lang/token.hpp" #include "lang/token.hpp"
#ifdef __APPLE__
#define off64_t off_t
#define fopen64 fopen
#define fseeko64 fseek
#define ftello64 ftell
#endif
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 12000
#if __has_include(<concepts>)
// Make sure we break when derived_from is implemented in libc++. Then we can fix a compatibility version above
#include <concepts>
#endif
// libcxx 12 still doesn't have derived_from implemented, as a result we need to define it ourself using clang built-ins.
// [concept.derived] (patch from https://reviews.llvm.org/D74292)
namespace hex {
template<class _Dp, class _Bp>
concept derived_from =
__is_base_of(_Bp, _Dp) && __is_convertible_to(const volatile _Dp*, const volatile _Bp*);
}
#else
// Assume supported
#include <concepts>
namespace hex {
using std::derived_from;
}
#endif
namespace hex { namespace hex {
template<typename ... Args> template<typename ... Args>
@ -99,6 +126,19 @@ namespace hex {
throw std::invalid_argument("Invalid value size!"); throw std::invalid_argument("Invalid value size!");
} }
template< class T >
constexpr T bit_width(T x) noexcept {
return std::numeric_limits<T>::digits - std::countl_zero(x);
}
template<typename T>
constexpr T bit_ceil(T x) noexcept {
if (x <= 1u)
return T(1);
return T(1) << bit_width(T(x - 1));
}
std::vector<u8> readFile(std::string_view path); std::vector<u8> readFile(std::string_view path);
class ScopeExit { class ScopeExit {

View File

@ -3,7 +3,6 @@
#include <hex.hpp> #include <hex.hpp>
#include <cmath> #include <cmath>
#include <concepts>
#include <map> #include <map>
#include <optional> #include <optional>
#include <string> #include <string>

View File

@ -7,7 +7,6 @@
#include "providers/provider.hpp" #include "providers/provider.hpp"
#include <concepts>
#include <cstring> #include <cstring>
#include <filesystem> #include <filesystem>

View File

@ -1,10 +1,10 @@
#pragma once #pragma once
#include <concepts>
#include <filesystem> #include <filesystem>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "helpers/utils.hpp"
#include "views/view.hpp" #include "views/view.hpp"
struct GLFWwindow; struct GLFWwindow;
@ -19,7 +19,7 @@ namespace hex {
void loop(); void loop();
template<std::derived_from<View> T, typename ... Args> template<derived_from<View> T, typename ... Args>
T* addView(Args&& ... args) { T* addView(Args&& ... args) {
this->m_views.emplace_back(new T(std::forward<Args>(args)...)); this->m_views.emplace_back(new T(std::forward<Args>(args)...));

View File

@ -1,6 +1,5 @@
#include "helpers/patches.hpp" #include "helpers/patches.hpp"
#include <concepts>
#include <cstring> #include <cstring>
#include <string_view> #include <string_view>
#include <type_traits> #include <type_traits>

View File

@ -36,7 +36,7 @@ namespace hex::lang {
const auto typeDeclNode = static_cast<ASTNodeTypeDecl*>(this->m_types[member->getCustomVariableTypeName()]); const auto typeDeclNode = static_cast<ASTNodeTypeDecl*>(this->m_types[member->getCustomVariableTypeName()]);
PatternData *pattern = nullptr; PatternData *pattern = nullptr;
u64 memberSize = 0; size_t memberSize = 0;
if (member->getVariableType() == Token::TypeToken::Type::Signed8Bit && member->getArraySize() > 1) { if (member->getVariableType() == Token::TypeToken::Type::Signed8Bit && member->getArraySize() > 1) {
std::tie(pattern, memberSize) = this->createStringPattern(member, memberOffset); std::tie(pattern, memberSize) = this->createStringPattern(member, memberOffset);
@ -128,7 +128,7 @@ namespace hex::lang {
const auto typeDeclNode = static_cast<ASTNodeTypeDecl*>(this->m_types[member->getCustomVariableTypeName()]); const auto typeDeclNode = static_cast<ASTNodeTypeDecl*>(this->m_types[member->getCustomVariableTypeName()]);
PatternData *pattern = nullptr; PatternData *pattern = nullptr;
u64 memberSize = 0; size_t memberSize = 0;
if (member->getVariableType() == Token::TypeToken::Type::Signed8Bit && member->getArraySize() > 1) { if (member->getVariableType() == Token::TypeToken::Type::Signed8Bit && member->getArraySize() > 1) {
std::tie(pattern, memberSize) = this->createStringPattern(member, memberOffset); std::tie(pattern, memberSize) = this->createStringPattern(member, memberOffset);
@ -222,7 +222,7 @@ namespace hex::lang {
for (auto &[fieldName, fieldSize] : bitfieldType->getFields()) for (auto &[fieldName, fieldSize] : bitfieldType->getFields())
size += fieldSize; size += fieldSize;
size = std::bit_ceil(size) / 8; size = bit_ceil(size) / 8;
return { new PatternDataBitfield(offset, size, varDeclNode->getVariableName(), bitfieldType->getName(), bitfieldType->getFields(), varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)), size }; return { new PatternDataBitfield(offset, size, varDeclNode->getVariableName(), bitfieldType->getName(), bitfieldType->getFields(), varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)), size };
} }

View File

@ -2,6 +2,7 @@
#include <vector> #include <vector>
#include <functional> #include <functional>
#include <optional>
namespace hex::lang { namespace hex::lang {

View File

@ -245,7 +245,7 @@ namespace hex {
lang::PatternData::resetPalette(); lang::PatternData::resetPalette();
} }
template<std::derived_from<lang::ASTNode> T> template<derived_from<lang::ASTNode> T>
static std::vector<T*> findNodes(const lang::ASTNode::Type type, const std::vector<lang::ASTNode*> &nodes) { static std::vector<T*> findNodes(const lang::ASTNode::Type type, const std::vector<lang::ASTNode*> &nodes) {
std::vector<T*> result; std::vector<T*> result;
@ -300,7 +300,7 @@ namespace hex {
return; return;
} }
hex::ScopeExit deleteAst([&ast]{ for(auto &node : ast) delete node; }); hex::ScopeExit deleteAst([&ast=ast]{ for(auto &node : ast) delete node; });
hex::lang::Validator validator; hex::lang::Validator validator;
auto validatorResult = validator.validate(ast); auto validatorResult = validator.validate(ast);