mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-02 13:37:42 -05:00
build: Switch to GCC on MacOS (#552)
* build: Experimentally switch to gcc on macOS * build: Corrected gcc paths * build: Enable objective c support on macOS * build: Enable ObjC and ObjC++ on macOS * build: Add ObjC and ObjC++ flags * build: Try compiling objc with clang * build: Remove invalid flags again * fix: Let's not include objc headers in C++ code * sys: Move macos utils code to its own file * fix: Missing unistd include on mac * sys: Removed loader script stuff since it's currently unused and broken * fix: Missing include * fix: Another missing include * fix: CFURLCreateWithBytes wants a pointer to mutable data * fix: Try disabling name mangling of ObjC functions * sys: Move macos utils declarations to its own header file * fix: C Linkage * fix: Move objc function prototypes to C++ headers * fix: More missing includes * fix: Warning error * sys: Call ObjC with C ABI instead of trying to use C++ * build: Update libraries * sys: Fixed build errors * sys: No const correctness I guess * sys: Fixed prototypes * sys: This is C now * sys: More nullptr -> NULL * sys: Fix crash on exit * sys: Try using proper std concepts instead of custom ones * sys: Replaced another hex::is_signed * build: Upgrade to gcc 12 and MacOS Monterey * build: Fixed MacOS runner name * build: Cache correct ccache folder on macOS
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
|
||||
#include <mbedtls/version.h>
|
||||
#include <mbedtls/base64.h>
|
||||
@@ -15,7 +16,6 @@
|
||||
|
||||
#include <array>
|
||||
#include <span>
|
||||
#include <concepts>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/helpers/fs_macos.h>
|
||||
#include <hex/helpers/fs_macos.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
#include <hex/helpers/intrinsics.hpp>
|
||||
|
||||
@@ -34,7 +34,15 @@ namespace hex::fs {
|
||||
|
||||
return exePath;
|
||||
#elif defined(OS_MACOS)
|
||||
return getMacExecutableDirectoryPath();
|
||||
std::string result;
|
||||
|
||||
{
|
||||
auto string = getMacExecutableDirectoryPath();
|
||||
result = string;
|
||||
macFree(string);
|
||||
}
|
||||
|
||||
return result;
|
||||
#else
|
||||
return std::nullopt;
|
||||
#endif
|
||||
@@ -183,25 +191,31 @@ namespace hex::fs {
|
||||
}
|
||||
#elif defined(OS_MACOS)
|
||||
// Get path to special directories
|
||||
const std::fs::path applicationSupportDir(getMacApplicationSupportDirectoryPath());
|
||||
std::string applicationSupportDir;
|
||||
{
|
||||
auto string = getMacApplicationSupportDirectoryPath();
|
||||
applicationSupportDir = string;
|
||||
macFree(string);
|
||||
}
|
||||
const std::fs::path applicationSupportDirPath(applicationSupportDir);
|
||||
|
||||
std::vector<std::fs::path> paths = { applicationSupportDir };
|
||||
std::vector<std::fs::path> paths = { applicationSupportDirPath };
|
||||
|
||||
if (exePath.has_value())
|
||||
paths.push_back(exePath.value());
|
||||
|
||||
switch (path) {
|
||||
case ImHexPath::Patterns:
|
||||
result.push_back((applicationSupportDir / "patterns").string());
|
||||
result.push_back((applicationSupportDirPath / "patterns").string());
|
||||
break;
|
||||
case ImHexPath::PatternsInclude:
|
||||
result.push_back((applicationSupportDir / "includes").string());
|
||||
result.push_back((applicationSupportDirPath / "includes").string());
|
||||
break;
|
||||
case ImHexPath::Magic:
|
||||
result.push_back((applicationSupportDir / "magic").string());
|
||||
result.push_back((applicationSupportDirPath / "magic").string());
|
||||
break;
|
||||
case ImHexPath::Python:
|
||||
result.push_back((applicationSupportDir / "python").string());
|
||||
result.push_back((applicationSupportDirPath / "python").string());
|
||||
break;
|
||||
case ImHexPath::Plugins:
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
@@ -209,22 +223,22 @@ namespace hex::fs {
|
||||
});
|
||||
break;
|
||||
case ImHexPath::Yara:
|
||||
result.push_back((applicationSupportDir / "yara").string());
|
||||
result.push_back((applicationSupportDirPath / "yara").string());
|
||||
break;
|
||||
case ImHexPath::Config:
|
||||
result.push_back((applicationSupportDir / "config").string());
|
||||
result.push_back((applicationSupportDirPath / "config").string());
|
||||
break;
|
||||
case ImHexPath::Resources:
|
||||
result.push_back((applicationSupportDir / "resources").string());
|
||||
result.push_back((applicationSupportDirPath / "resources").string());
|
||||
break;
|
||||
case ImHexPath::Constants:
|
||||
result.push_back((applicationSupportDir / "constants").string());
|
||||
result.push_back((applicationSupportDirPath / "constants").string());
|
||||
break;
|
||||
case ImHexPath::Encodings:
|
||||
result.push_back((applicationSupportDir / "encodings").string());
|
||||
result.push_back((applicationSupportDirPath / "encodings").string());
|
||||
break;
|
||||
case ImHexPath::Logs:
|
||||
result.push_back((applicationSupportDir / "logs").string());
|
||||
result.push_back((applicationSupportDirPath / "logs").string());
|
||||
break;
|
||||
default:
|
||||
hex::unreachable();
|
||||
|
||||
44
lib/libimhex/source/helpers/fs_macos.m
Normal file
44
lib/libimhex/source/helpers/fs_macos.m
Normal file
@@ -0,0 +1,44 @@
|
||||
#if defined(OS_MACOS)
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
char* getMacExecutableDirectoryPath() {
|
||||
@autoreleasepool {
|
||||
const char *pathString = [[[[[NSBundle mainBundle] executableURL] URLByDeletingLastPathComponent] path] UTF8String];
|
||||
|
||||
char *result = malloc(strlen(pathString) + 1);
|
||||
strcpy(result, pathString);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
char* getMacApplicationSupportDirectoryPath() {
|
||||
@autoreleasepool {
|
||||
NSError* error = nil;
|
||||
NSURL* dirUrl = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory
|
||||
inDomain:NSUserDomainMask
|
||||
appropriateForURL:nil
|
||||
create:YES
|
||||
error:&error];
|
||||
|
||||
if (error != nil) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *pathString = [[[dirUrl URLByAppendingPathComponent:(@"imhex")] path] UTF8String];
|
||||
|
||||
char *result = malloc(strlen(pathString) + 1);
|
||||
strcpy(result, pathString);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void macFree(void *ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
#if defined(OS_MACOS)
|
||||
#include <hex/helpers/fs_macos.h>
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
namespace hex {
|
||||
std::string getMacExecutableDirectoryPath() {
|
||||
@autoreleasepool {
|
||||
return {[[[[[NSBundle mainBundle] executableURL] URLByDeletingLastPathComponent] path] UTF8String]};
|
||||
}
|
||||
}
|
||||
|
||||
std::string getMacApplicationSupportDirectoryPath() {
|
||||
@autoreleasepool {
|
||||
NSError* error = nil;
|
||||
NSURL* dirUrl = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory
|
||||
inDomain:NSUserDomainMask
|
||||
appropriateForURL:nil
|
||||
create:YES
|
||||
error:&error];
|
||||
|
||||
if (error != nil) {
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
return {[[[dirUrl URLByAppendingPathComponent:(@"imhex")] path] UTF8String]};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,248 +0,0 @@
|
||||
#include <hex/helpers/loader_script_handler.hpp>
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fs.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/helpers/intrinsics.hpp>
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
#include <structmember.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
namespace hex {
|
||||
|
||||
PyObject *LoaderScript::Py_getFilePath(PyObject *self, PyObject *args) {
|
||||
hex::unused(self, args);
|
||||
|
||||
return PyUnicode_FromString(LoaderScript::s_filePath.string().c_str());
|
||||
}
|
||||
|
||||
PyObject *LoaderScript::Py_addPatch(PyObject *self, PyObject *args) {
|
||||
hex::unused(self);
|
||||
|
||||
u64 address;
|
||||
u8 *patches;
|
||||
Py_ssize_t count;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "K|y#", &address, &patches, &count)) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (patches == nullptr || count == 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "Invalid patch provided");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (address >= LoaderScript::s_dataProvider->getActualSize()) {
|
||||
PyErr_SetString(PyExc_IndexError, "address out of range");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LoaderScript::s_dataProvider->write(address, patches, count);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *LoaderScript::Py_addBookmark(PyObject *self, PyObject *args) {
|
||||
hex::unused(self);
|
||||
|
||||
u64 address;
|
||||
size_t size;
|
||||
|
||||
char *name = nullptr;
|
||||
char *comment = nullptr;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "K|n|s|s", &address, &size, &name, &comment)) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (name == nullptr || comment == nullptr) {
|
||||
PyErr_SetString(PyExc_IndexError, "address out of range");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ImHexApi::Bookmarks::add(address, size, name, comment);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *createStructureType(const std::string &keyword, PyObject *args) {
|
||||
if (args == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto type = PyTuple_GetItem(args, 0);
|
||||
if (type == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto instance = PyObject_CallObject(type, nullptr);
|
||||
if (instance == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ON_SCOPE_EXIT { Py_DECREF(instance); };
|
||||
|
||||
if (instance->ob_type->tp_base == nullptr || instance->ob_type->tp_base->tp_name != "ImHexType"s) {
|
||||
PyErr_SetString(PyExc_TypeError, "class type must extend from ImHexType");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto dict = instance->ob_type->tp_dict;
|
||||
if (dict == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto annotations = PyDict_GetItemString(dict, "__annotations__");
|
||||
if (annotations == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto list = PyDict_Items(annotations);
|
||||
if (list == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ON_SCOPE_EXIT { Py_DECREF(list); };
|
||||
|
||||
std::string code = keyword + " " + instance->ob_type->tp_name + " {\n";
|
||||
|
||||
for (Py_ssize_t i = 0; i < PyList_Size(list); i++) {
|
||||
auto item = PyList_GetItem(list, i);
|
||||
if (item == nullptr) {
|
||||
PyErr_SetString(PyExc_TypeError, "failed to get item from list");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto memberName = PyUnicode_AsUTF8(PyTuple_GetItem(item, 0));
|
||||
if (memberName == nullptr) {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid member name");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto memberType = PyTuple_GetItem(item, 1);
|
||||
if (!PyTuple_Check(memberType) || memberType == nullptr) {
|
||||
PyErr_SetString(PyExc_TypeError, "member needs to have a annotation extending from ImHexType");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Array already is an object
|
||||
if (memberType->ob_type->tp_name == "array"s) {
|
||||
|
||||
auto arrayType = PyObject_GetAttrString(memberType, "array_type");
|
||||
if (arrayType == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
code += " "s + arrayType->ob_type->tp_name + " " + memberName;
|
||||
|
||||
auto arraySize = PyObject_GetAttrString(memberType, "size");
|
||||
if (arraySize == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (PyUnicode_Check(arraySize))
|
||||
code += "["s + PyUnicode_AsUTF8(arraySize) + "];\n";
|
||||
else if (PyLong_Check(arraySize))
|
||||
code += "["s + std::to_string(PyLong_AsLong(arraySize)) + "];\n";
|
||||
} else {
|
||||
auto memberTypeInstance = PyObject_CallObject(memberType, nullptr);
|
||||
if (memberTypeInstance == nullptr || memberTypeInstance->ob_type->tp_base == nullptr || memberTypeInstance->ob_type->tp_base->tp_name != "ImHexType"s) {
|
||||
PyErr_SetString(PyExc_TypeError, "member needs to have a annotation extending from ImHexType");
|
||||
if (memberTypeInstance != nullptr)
|
||||
Py_DECREF(memberTypeInstance);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
code += " "s + memberTypeInstance->ob_type->tp_name + " "s + memberName + ";\n";
|
||||
|
||||
Py_DECREF(memberTypeInstance);
|
||||
}
|
||||
}
|
||||
|
||||
code += "};\n";
|
||||
|
||||
EventManager::post<RequestSetPatternLanguageCode>(code);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *LoaderScript::Py_addStruct(PyObject *self, PyObject *args) {
|
||||
hex::unused(self);
|
||||
|
||||
return createStructureType("struct", args);
|
||||
}
|
||||
|
||||
PyObject *LoaderScript::Py_addUnion(PyObject *self, PyObject *args) {
|
||||
hex::unused(self);
|
||||
|
||||
return createStructureType("union", args);
|
||||
}
|
||||
|
||||
bool LoaderScript::processFile(const std::fs::path &scriptPath) {
|
||||
Py_SetProgramName(Py_DecodeLocale("ImHex", nullptr));
|
||||
|
||||
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Python)) {
|
||||
if (fs::exists(std::fs::path(dir / "lib" / "python" PYTHON_VERSION_MAJOR_MINOR))) {
|
||||
Py_SetPythonHome(Py_DecodeLocale(dir.string().c_str(), nullptr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PyImport_AppendInittab("_imhex", []() -> PyObject * {
|
||||
static PyMethodDef ImHexMethods[] = {
|
||||
{"get_file_path", &LoaderScript::Py_getFilePath, METH_NOARGS, "Returns the path of the file being loaded."},
|
||||
{ "patch", &LoaderScript::Py_addPatch, METH_VARARGS, "Patches a region of memory" },
|
||||
{ "add_bookmark", &LoaderScript::Py_addBookmark, METH_VARARGS, "Adds a bookmark" },
|
||||
{ "add_struct", &LoaderScript::Py_addStruct, METH_VARARGS, "Adds a struct" },
|
||||
{ "add_union", &LoaderScript::Py_addUnion, METH_VARARGS, "Adds a union" },
|
||||
{ nullptr, nullptr, 0, nullptr }
|
||||
};
|
||||
|
||||
static PyModuleDef ImHexModule = {
|
||||
PyModuleDef_HEAD_INIT, "imhex", nullptr, -1, ImHexMethods, nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
auto module = PyModule_Create(&ImHexModule);
|
||||
if (module == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return module;
|
||||
});
|
||||
|
||||
Py_Initialize();
|
||||
|
||||
{
|
||||
auto sysPath = PySys_GetObject("path");
|
||||
auto path = PyUnicode_FromString("lib");
|
||||
|
||||
PyList_Insert(sysPath, 0, path);
|
||||
}
|
||||
|
||||
fs::File scriptFile(scriptPath, fs::File::Mode::Read);
|
||||
PyRun_SimpleFile(scriptFile.getHandle(), scriptFile.getPath().string().c_str());
|
||||
|
||||
Py_Finalize();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <filesystem>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
@@ -18,13 +16,10 @@
|
||||
#elif defined(OS_LINUX)
|
||||
#include <unistd.h>
|
||||
#elif defined(OS_MACOS)
|
||||
#include <CoreFoundation/CFBundle.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <hex/helpers/utils_macos.hpp>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
long double operator""_scaled(long double value) {
|
||||
@@ -252,13 +247,14 @@ namespace hex {
|
||||
|
||||
void runCommand(const std::string &command) {
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
auto result = system(hex::format("start {0}", command).c_str());
|
||||
#elif defined(OS_MACOS)
|
||||
auto result = system(hex::format("open {0}", command).c_str());
|
||||
#elif defined(OS_LINUX)
|
||||
auto result = system(hex::format("xdg-open {0}", command).c_str());
|
||||
#endif
|
||||
#if defined(OS_WINDOWS)
|
||||
auto result = system(hex::format("start {0}", command).c_str());
|
||||
#elif defined(OS_MACOS)
|
||||
auto result = system(hex::format("open {0}", command).c_str());
|
||||
#elif defined(OS_LINUX)
|
||||
auto result = system(hex::format("xdg-open {0}", command).c_str());
|
||||
#endif
|
||||
|
||||
hex::unused(result);
|
||||
}
|
||||
|
||||
@@ -267,18 +263,16 @@ namespace hex {
|
||||
if (url.find("://") == std::string::npos)
|
||||
url = "https://" + url;
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
ShellExecute(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
#elif defined(OS_MACOS)
|
||||
CFURLRef urlRef = CFURLCreateWithBytes(nullptr, reinterpret_cast<u8 *>(url.data()), url.length(), kCFStringEncodingASCII, nullptr);
|
||||
LSOpenCFURLRef(urlRef, nullptr);
|
||||
CFRelease(urlRef);
|
||||
#elif defined(OS_LINUX)
|
||||
auto result = system(hex::format("xdg-open {0}", url).c_str());
|
||||
hex::unused(result);
|
||||
#else
|
||||
#warning "Unknown OS, can't open webpages"
|
||||
#endif
|
||||
#if defined(OS_WINDOWS)
|
||||
ShellExecute(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
#elif defined(OS_MACOS)
|
||||
openWebpageMacos(url.c_str());
|
||||
#elif defined(OS_LINUX)
|
||||
auto result = system(hex::format("xdg-open {0}", url).c_str());
|
||||
hex::unused(result);
|
||||
#else
|
||||
#warning "Unknown OS, can't open webpages"
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string encodeByteString(const std::vector<u8> &bytes) {
|
||||
|
||||
16
lib/libimhex/source/helpers/utils_macos.m
Normal file
16
lib/libimhex/source/helpers/utils_macos.m
Normal file
@@ -0,0 +1,16 @@
|
||||
#if defined(OS_MACOS)
|
||||
|
||||
#include <CoreFoundation/CFBundle.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void openWebpageMacos(const char *url) {
|
||||
CFURLRef urlRef = CFURLCreateWithBytes(NULL, (uint8_t*)(url), strlen(url), kCFStringEncodingASCII, NULL);
|
||||
LSOpenCFURLRef(urlRef, NULL);
|
||||
CFRelease(urlRef);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user