Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drafting MacOS support #35

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 67 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,67 @@ if(NOT BOLT_DEV_LAUNCHER_DIRECTORY)
endif()

# This line needs to be updated manually with any new/deleted object files; cmake discourages GLOBbing source files
add_executable(bolt
set(BOLT_SRCS
modules/fmt/src/format.cc src/main.cxx src/browser.cxx src/browser/app.cxx src/browser/client.cxx
src/browser/resource_handler.cxx src/browser/window_launcher.cxx ${WINDOW_LAUNCHER_OS_SPECIFIC}
src/mime.cxx src/file_manager/directory.cxx client_cmake_gen.cxx ${BOLT_FILE_MANAGER_LAUNCHER_GEN}
)

if(APPLE)
add_executable(bolt MACOSX_BUNDLE ${BOLT_SRCS})
# Copy the CEF framework into the Frameworks directory.
add_custom_command(
TARGET bolt
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CEF_ROOT}/${CMAKE_BUILD_TYPE}/Chromium Embedded Framework.framework"
"${CMAKE_BINARY_DIR}/bolt.app/Contents/Frameworks/Chromium Embedded Framework.framework"
VERBATIM
)

set(BOLT_HELPER_SRCS
mac/process_helper.cc
)

# Create the multiple Helper app bundle targets.
foreach(_suffix_list ${CEF_HELPER_APP_SUFFIXES})
# Convert to a list and extract the suffix values.
string(REPLACE ":" ";" _suffix_list ${_suffix_list})
list(GET _suffix_list 0 _name_suffix)
list(GET _suffix_list 1 _target_suffix)
list(GET _suffix_list 2 _plist_suffix)

# Define Helper target and output names.
set(_helper_target "Bolt_Helper${_target_suffix}")
set(_helper_output_name "Bolt Helper${_name_suffix}")

# Create Helper executable target.
add_executable(${_helper_target} MACOSX_BUNDLE ${BOLT_HELPER_SRCS})
add_dependencies(${_helper_target} libcef_dll_wrapper)
target_include_directories(${_helper_target} PUBLIC "${CEF_ROOT}")
set_target_properties(${_helper_target} PROPERTIES CXX_STANDARD 20 CXX_EXTENSIONS OFF)
target_link_libraries(${_helper_target} libcef_dll_wrapper ${CEF_STANDARD_LIBS})
set_target_properties(${_helper_target} PROPERTIES
OUTPUT_NAME ${_helper_output_name}
)

# Add the Helper as a dependency of the main executable target.
add_dependencies(bolt "${_helper_target}")

# Copy the Helper app bundle into the Frameworks directory.
add_custom_command(
TARGET bolt
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_BINARY_DIR}/${_helper_output_name}.app"
"${CMAKE_BINARY_DIR}/bolt.app/Contents/Frameworks/${_helper_output_name}.app"
VERBATIM
)
endforeach()
else()
add_executable(bolt ${BOLT_SRCS})
endif()

# Various build properties
target_include_directories(bolt PUBLIC ${CEF_ROOT} modules/fmt/include)
set_target_properties(bolt PROPERTIES CXX_STANDARD 20 CXX_EXTENSIONS OFF)
Expand All @@ -224,7 +279,15 @@ elseif(WIN32)
target_link_libraries(bolt PUBLIC "${CEF_ROOT}/${CMAKE_BUILD_TYPE}/libcef.lib")
target_link_libraries(bolt PUBLIC "${CEF_ROOT}/${CMAKE_BUILD_TYPE}/cef_sandbox.lib")
elseif(APPLE)
# TODO: mac support
execute_process(
COMMAND brew --prefix libarchive
OUTPUT_VARIABLE LIBARCHIVE_PREFIX
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY
)
set(LibArchive_INCLUDE_DIR "${LIBARCHIVE_PREFIX}/include")
find_package(LibArchive REQUIRED)
target_link_libraries(bolt PRIVATE LibArchive::LibArchive)
endif()

# compilation setting for enabling chromium dev tools
Expand Down Expand Up @@ -256,15 +319,14 @@ find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
target_include_directories(bolt PUBLIC ${GTK3_INCLUDE_DIRS})
target_link_libraries(bolt PUBLIC ${GTK3_LIBRARIES})
if(MSVC)
if(MSVC OR APPLE)
target_link_directories(bolt PUBLIC ${GTK3_LIBRARY_DIRS})
endif()

install(TARGETS bolt DESTINATION ${BOLT_CEF_INSTALLDIR}/bolt-launcher)
# Install commands for target dir layout - as per https://bitbucket.org/chromiumembedded/cef/wiki/Tutorial.md
if(APPLE)
# TODO: mac support
else()
install(TARGETS bolt DESTINATION ${BOLT_CEF_INSTALLDIR}/bolt-launcher)
install(DIRECTORY "${CEF_ROOT}/${CMAKE_BUILD_TYPE}/" "${CEF_ROOT}/Resources/" DESTINATION ${BOLT_CEF_INSTALLDIR}/bolt-launcher USE_SOURCE_PERMISSIONS)
endif()

Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ Windows builds have only been tested using Visual Studio 2022 (a.k.a. Visual Stu
### Mac
Not yet supported

<https://cef-builds.spotifycdn.com/index.html#macosarm64>

```bash
brew install cmake pkg-config gtk+3 libarchive
cmake -S . -B build -D BOLT_SKIP_LIBRARIES=True -D CMAKE_BUILD_TYPE=Release -D CEF_ROOT=$HOME/Downloads/cef_binary_122.1.13+gde5b724+chromium-122.0.6261.130_macosarm64_minimal
cmake --build build
```

## Maintenance
When doing the initial cmake setup step, the following options exist which you may find useful. These are to be used for local development only.
- `-D BOLT_HTML_DIR=/some/directory`: the location of the launcher's internal webpage content, `html/` by default
Expand Down
12 changes: 12 additions & 0 deletions entitlements-helper.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
</dict>
</plist>
33 changes: 33 additions & 0 deletions mac/process_helper.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "include/cef_app.h"
#include "include/wrapper/cef_library_loader.h"

// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line to disable
// use of the sandbox.
#if defined(CEF_USE_SANDBOX)
#include "include/cef_sandbox_mac.h"
#endif

// Entry point function for sub-processes.
int main(int argc, char* argv[]) {
#if defined(CEF_USE_SANDBOX)
// Initialize the macOS sandbox for this helper process.
CefScopedSandboxContext sandbox_context;
if (!sandbox_context.Initialize(argc, argv)) {
return 1;
}
#endif

// Load the CEF framework library at runtime instead of linking directly
// as required by the macOS sandbox implementation.
CefScopedLibraryLoader library_loader;
if (!library_loader.LoadInHelper()) {
return 1;
}

// Provide CEF with command-line arguments.
CefMainArgs main_args(argc, argv);

// Execute the sub-process.
return CefExecuteProcess(main_args, nullptr, nullptr);
}
23 changes: 23 additions & 0 deletions src/main.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
#include <sys/stat.h>
#endif

#if defined(__APPLE__)
#include "include/wrapper/cef_library_loader.h"
#endif

#if defined(CEF_X11)
#include <X11/Xlib.h>
int XErrorHandlerImpl(Display* display, XErrorEvent* event) {
Expand Down Expand Up @@ -313,6 +317,25 @@ bool LockXdgDirectories(std::filesystem::path& config_dir, std::filesystem::path
}
#endif

#if defined(__APPLE__)
int main(int argc, char* argv[]) {
// Dynamically load the CEF framework library.
CefScopedLibraryLoader library_loader;
if (!library_loader.LoadInMain())
return 1;

// Provide CEF with command-line arguments.
CefMainArgs main_args(argc, argv);
Browser::App cef_app_;
CefRefPtr<Browser::App> cef_app = &cef_app_;

return BoltRunBrowserProcess(main_args, cef_app);
}
bool LockXdgDirectories(std::filesystem::path& config_dir, std::filesystem::path& data_dir) {
return true;
}
#endif

// all these features exist in gtk3 and are deprecated for no reason at all, so ignore deprecation warnings
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
Expand Down