diff --git a/Ladybird/.gitignore b/Ladybird/.gitignore index a656279ac76..84bbdd10cfd 100644 --- a/Ladybird/.gitignore +++ b/Ladybird/.gitignore @@ -3,3 +3,5 @@ Makefile ladybird *.o moc_* +Build +build diff --git a/Ladybird/CMakeLists.txt b/Ladybird/CMakeLists.txt new file mode 100644 index 00000000000..e801b2c46b7 --- /dev/null +++ b/Ladybird/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 3.16...3.22) + +project(ladybird + VERSION 0.0.1 + LANGUAGES CXX + DESCRIPTION "Ladybird Web Browser" +) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(CMAKE_SKIP_BUILD_RPATH FALSE) +set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) +# See slide 100 of the following ppt :^) +# https://crascit.com/wp-content/uploads/2019/09/Deep-CMake-For-Library-Authors-Craig-Scott-CppCon-2019.pdf +if (NOT APPLE) + set(CMAKE_INSTALL_RPATH $ORIGIN) +endif() +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +include(cmake/EnableLLD.cmake) + +# Lagom +include(FetchContent) +include(cmake/FetchLagom.cmake) + +# Lagom warnings +include(${Lagom_SOURCE_DIR}/../CMake/lagom_compile_options.cmake) +add_compile_options(-Wno-expansion-to-defined) + +set(CMAKE_AUTOMOC ON) +find_package(Qt6 REQUIRED COMPONENTS Core Widgets) + +# FIXME: Stop using deprecated declarations from QT :^) +add_compile_options(-Wno-deprecated-declarations) + +set(SOURCES + BrowserWindow.cpp + main.cpp + WebView.cpp +) + +add_executable(ladybird ${SOURCES}) +target_link_libraries(ladybird PRIVATE Qt6::Widgets Lagom::Web Lagom::HTTP Lagom::WebSocket Lagom::Main) + +get_filename_component( + SERENITY_SOURCE_DIR "${Lagom_SOURCE_DIR}/../.." + ABSOLUTE +) + +add_custom_target(run + COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SERENITY_SOURCE_DIR}" "$" + USES_TERMINAL +) + +add_custom_target(debug + COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SERENITY_SOURCE_DIR}" gdb "$" + USES_TERMINAL +) + diff --git a/Ladybird/README.md b/Ladybird/README.md new file mode 100644 index 00000000000..3963839868e --- /dev/null +++ b/Ladybird/README.md @@ -0,0 +1,51 @@ +# Ladybird Web Browser + +The Ladybird Web Browser is a browser using the SerenityOS LibWeb engine with a QT GUI. + +## Build Prerequisites + +QT6 development packages and a c++20-enabled compiler are required. On Debian/Ubuntu required packages include, but are not limited to: + +``` +sudo apt install build-essential cmake ninja-build qt6-base-dev qt6-tools-dev-tools +``` + +For the c++ compiler, gcc-11 or clang-13 are required at a minimum for c++20 support. + +For Ubuntu 20.04 and above, ensure that the QT6 Wayland packages are available: + +``` +sudo apt install qt6-wayland +``` + + +## Build steps + +Basic workflow, using serenity source dir cloned from github: + +``` +cmake -GNinja -B Build +cmake --build Build +ninja -C Build run +``` + +Advanced workflow, using pre-existing serenity checkout. + +If you previously didn't set SERENITY_SOURCE_DIR, probably want to blast the Build directory before doing this: + +``` +cmake -GNinja -B Build -DSERENITY_SOURCE_DIR=/path/to/serenity +ninja -C Build run +``` + +To automatically run in gdb: +``` +ninja -C Build debug +``` + +To run without ninja rule: +``` +# or your existing serenity checkout /path/to/serenity +export SERENITY_SOURCE_DIR=${PWD}/Build/serenity +./Build/ladybird +``` diff --git a/Ladybird/WebView.cpp b/Ladybird/WebView.cpp index 04d1bd33a6e..5084ff84232 100644 --- a/Ladybird/WebView.cpp +++ b/Ladybird/WebView.cpp @@ -52,6 +52,17 @@ #include #include #include +#include + +String s_serenity_resource_root = [] { + auto const* source_dir = getenv("SERENITY_SOURCE_DIR"); + if (source_dir) { + return String::formatted("{}/Base", source_dir); + } + auto* home = getenv("XDG_CONFIG_HOME") ?: getenv("HOME"); + VERIFY(home); + return String::formatted("{}/.lagom", home); +}(); class HeadlessBrowserPageClient final : public Web::PageClient { public: @@ -271,7 +282,7 @@ WebView::WebView() m_page_client = HeadlessBrowserPageClient::create(*this); - m_page_client->setup_palette(Gfx::load_system_theme("/home/kling/src/serenity/Base/res/themes/Default.ini")); + m_page_client->setup_palette(Gfx::load_system_theme(String::formatted("{}/res/themes/Default.ini", s_serenity_resource_root))); // FIXME: Allow passing these values as arguments m_page_client->set_viewport_rect({ 0, 0, 800, 600 }); @@ -794,12 +805,13 @@ void initialize_web_engine() Web::ResourceLoader::initialize(HeadlessRequestServer::create()); Web::WebSockets::WebSocketClientManager::initialize(HeadlessWebSocketClientManager::create()); - Web::FrameLoader::set_default_favicon_path("/home/kling/src/serenity/Base/res/icons/16x16/app-browser.png"); + Web::FrameLoader::set_default_favicon_path(String::formatted("{}/res/icons/16x16/app-browser.png", s_serenity_resource_root)); + dbgln("Set favoicon path to {}", String::formatted("{}/res/icons/16x16/app-browser.png", s_serenity_resource_root)); - Gfx::FontDatabase::set_default_fonts_lookup_path("/home/kling/src/serenity/Base/res/fonts"); + Gfx::FontDatabase::set_default_fonts_lookup_path(String::formatted("{}/res/fonts", s_serenity_resource_root)); Gfx::FontDatabase::set_default_font_query("Katica 10 400 0"); Gfx::FontDatabase::set_fixed_width_font_query("Csilla 10 400 0"); - Web::FrameLoader::set_error_page_url("file:///home/kling/src/serenity/Base/res/html/error.html"); + Web::FrameLoader::set_error_page_url(String::formatted("file://{}/res/html/error.html", s_serenity_resource_root)); } diff --git a/Ladybird/cmake/EnableLLD.cmake b/Ladybird/cmake/EnableLLD.cmake new file mode 100644 index 00000000000..52416a404d7 --- /dev/null +++ b/Ladybird/cmake/EnableLLD.cmake @@ -0,0 +1,14 @@ + +option(LADYBIRD_USE_LLD "Use llvm lld to link application" ON) +if (LADYBIRD_USE_LLD AND NOT APPLE) + find_program(LLD_LINKER NAMES "ld.lld") + if (NOT LLD_LINKER) + message(INFO "LLD not found, cannot use to link. Disabling option...") + set(LADYBIRD_USE_LLD OFF CACHE BOOL "" FORCE) + endif() +endif() +if (LADYBIRD_USE_LLD AND NOT APPLE) + add_link_options(-fuse-ld=lld) + add_compile_options(-ggnu-pubnames) + add_link_options(LINKER:--gdb-index) +endif() diff --git a/Ladybird/cmake/FetchLagom.cmake b/Ladybird/cmake/FetchLagom.cmake new file mode 100644 index 00000000000..ef5abeb46de --- /dev/null +++ b/Ladybird/cmake/FetchLagom.cmake @@ -0,0 +1,33 @@ +# Copyright (c) 2021, Andrew Kaster +# +# SPDX-License-Identifier: MIT + +# Fetch serenity, so that we can build Lagom from it +FetchContent_Declare(lagom + GIT_REPOSITORY https://github.com/SerenityOS/serenity.git + GIT_TAG origin/master + GIT_SHALLOW TRUE + SOURCE_DIR serenity +) + +# Allow developers to skip download/update steps with local checkout +if (SERENITY_SOURCE_DIR) + set(FETCHCONTENT_SOURCE_DIR_LAGOM ${SERENITY_SOURCE_DIR} CACHE PATH "Developer's pre-existing serenity source directory" FORCE) + message(STATUS "Using pre-existing SERENITY_SOURCE_DIR: ${SERENITY_SOURCE_DIR}") +endif() + +# Can't use FetchContent_MakeAvailable b/c we want to use the Lagom build, not the main build +# Populate source directory for lagom +FetchContent_GetProperties(lagom) +if (NOT lagom_POPULATED) + FetchContent_Populate(lagom) + set(BUILD_LAGOM ON CACHE INTERNAL "Build all Lagom targets") + + # FIXME: Setting target_include_directories on Lagom libraries might make this unecessary? + include_directories(${lagom_SOURCE_DIR}/Userland/Libraries) + include_directories(${lagom_SOURCE_DIR}) + include_directories(${lagom_BINARY_DIR}) + + # We set EXCLUDE_FROM_ALL to make sure that only required Lagom libraries are built + add_subdirectory(${lagom_SOURCE_DIR}/Meta/Lagom ${lagom_BINARY_DIR} EXCLUDE_FROM_ALL) +endif() diff --git a/Ladybird/ladybird.pro b/Ladybird/ladybird.pro deleted file mode 100644 index 5adbe0db141..00000000000 --- a/Ladybird/ladybird.pro +++ /dev/null @@ -1,39 +0,0 @@ -###################################################################### -# Automatically generated by qmake (3.1) Sun Jul 3 19:48:59 2022 -###################################################################### - -QT += widgets -TEMPLATE = app -TARGET = ladybird -INCLUDEPATH += \ - /home/kling/src/serenity/ \ - /home/kling/src/serenity/Userland/Libraries/ \ - /home/kling/src/serenity/Build/x86_64/Userland/Libraries/ \ - /home/kling/src/serenity/Build/x86_64/ \ - . - -# You can make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# Please consult the documentation of the deprecated API in order to know -# how to port your code away from it. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -# Input -HEADERS += WebView.h BrowserWindow.h -SOURCES += main.cpp WebView.cpp BrowserWindow.cpp - -QMAKE_LIBDIR += /home/kling/src/serenity/Build/lagom/ - -LIBS += \ - -llagom-web \ - -llagom-gemini \ - -llagom-gfx \ - -llagom-crypto \ - -llagom-core \ - -llagom-http \ - -llagom-tls \ - -llagom-websocket \ - -llagom-main - -QMAKE_CXXFLAGS += -std=c++20 -Wno-expansion-to-defined -Wno-literal-suffix -Wno-deprecated-enum-enum-conversion