From 2e2f4bf3d8ee5ded5dfbf3c82b7d9f7fd59714bb Mon Sep 17 00:00:00 2001 From: Huseyn Ismayilov Date: Wed, 27 Nov 2024 20:52:57 +0400 Subject: [PATCH] feat: Add global Linux build support and configurations --- CMakeLists.txt | 17 ++++ editor/CMakeLists.txt | 5 +- editor/resources/ferx.desktop | 11 +++ engine/CMakeLists.txt | 5 +- engine/core/Window.cpp | 29 +++++++ engine/core/Window.h | 3 +- engine/resources/icons/icon.png | Bin 0 -> 2678 bytes scripts/BuildProject.sh | 30 +++++-- scripts/InstallLinux.sh | 135 ++++++++++++++++++++++++++++++++ scripts/Makefile | 82 +++++++++++++++++-- 10 files changed, 298 insertions(+), 19 deletions(-) create mode 100755 editor/resources/ferx.desktop create mode 100644 engine/resources/icons/icon.png create mode 100755 scripts/InstallLinux.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 91f0595..bec84a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,3 +21,20 @@ add_subdirectory(${THIRDPARTY_DIR}/stb) # Add engine and editor add_subdirectory(engine) add_subdirectory(editor) + +# Create .desktop file for linux +if(UNIX) + set(DESKTOP_FILE "${EDITOR_RESOURCES_DIR}/ferx.desktop") + set(ICON_FILE "${ENGINE_RESOURCES_DIR}/icons/icon.png") + + include(GNUInstallDirs) + + install(FILES ${DESKTOP_FILE} + DESTINATION ${CMAKE_INSTALL_DATADIR}/applications + ) + + install(FILES ${ICON_FILE} + DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/256x256/apps + RENAME ferx.png + ) +endif(UNIX) diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 29e5806..4dc2cef 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -5,7 +5,8 @@ project(editor) set(NAME ferx) set(EDITOR_SOURCE_DIR src) set(EDITOR_INCLUDE_DIR include) -set(EDITOR_RESOURCES_DIR resources) +set(EDITOR_RESOURCES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/resources) +set(EDITOR_RESOURCES_DIR ${EDITOR_RESOURCES_DIR} PARENT_SCOPE) file(GLOB_RECURSE EDITOR_SOURCES ${EDITOR_SOURCE_DIR}/*.cpp) @@ -16,7 +17,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release") file(COPY ${EDITOR_RESOURCES_DIR} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) target_compile_definitions(${NAME} PUBLIC EDITOR_RESOURCES_PATH="${CMAKE_CURRENT_BINARY_DIR}/resources/") else() - target_compile_definitions(${NAME} PUBLIC EDITOR_RESOURCES_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/") + target_compile_definitions(${NAME} PUBLIC EDITOR_RESOURCES_PATH="${EDITOR_RESOURCES_DIR}/") endif() target_sources(${NAME} PRIVATE ${EDITOR_SOURCES}) diff --git a/editor/resources/ferx.desktop b/editor/resources/ferx.desktop new file mode 100755 index 0000000..4a39f89 --- /dev/null +++ b/editor/resources/ferx.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Ferx Engine +Exec=ferx +Version=1.0 +Type=Application +Categories=Development; +Terminal=false +Icon=ferx +Comment=Basic C++ game engine for learning +StartupWMClass=ferx +StartupNotify=true diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 79f5b10..e25cff7 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -21,7 +21,8 @@ file(GLOB COMPONENTS_SOURCES "${COMPONENTS_INCLUDES}/*.cpp") set(UI_INCLUDES ui) file(GLOB UI_SOURCES "${UI_INCLUDES}/*.cpp") -set(ENGINE_RESOURCES_DIR resources) +set(ENGINE_RESOURCES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/resources) +set(ENGINE_RESOURCES_DIR ${ENGINE_RESOURCES_DIR} PARENT_SCOPE) # Build engine as library add_library(${PROJECT_NAME}) @@ -31,7 +32,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release") file(COPY ${ENGINE_RESOURCES_DIR} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) target_compile_definitions(${PROJECT_NAME} PUBLIC ENGINE_RESOURCES_PATH="${CMAKE_CURRENT_BINARY_DIR}/resources/") else() - target_compile_definitions(${PROJECT_NAME} PUBLIC ENGINE_RESOURCES_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/") + target_compile_definitions(${PROJECT_NAME} PUBLIC ENGINE_RESOURCES_PATH="${ENGINE_RESOURCES_DIR}/") endif() # Link sources, include directories, and third party libraries diff --git a/engine/core/Window.cpp b/engine/core/Window.cpp index 0cb5c67..5d7fd07 100644 --- a/engine/core/Window.cpp +++ b/engine/core/Window.cpp @@ -28,6 +28,12 @@ void Window::Init() glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); +#if defined(_WIN32) + // Add Windows-specific configuration if needed +#elif defined(__linux__) + glfwWindowHintString(GLFW_X11_CLASS_NAME, "ferx"); + glfwWindowHintString(GLFW_X11_INSTANCE_NAME, "Ferx"); +#endif m_Window = glfwCreateWindow(m_Data.Size.Width, m_Data.Size.Height, m_Data.Title.c_str(), nullptr, nullptr); if (!m_Window) { @@ -36,6 +42,8 @@ void Window::Init() return; } + SetWindowIcon(); + glfwMakeContextCurrent(m_Window); } @@ -65,6 +73,27 @@ WindowSize Window::GetSize() return m_Data.Size; } +void Window::SetWindowIcon() const +{ + int width, height, channels; + const char* iconPath = ENGINE_RESOURCES_PATH"icons/icon.png"; + + unsigned char* pixels = stbi_load(iconPath, &width, &height, &channels, 4); // Force RGBA + if (!pixels) { + std::cerr << "Failed to load icon: " << iconPath << std::endl; + return; + } + + GLFWimage images[1]; + images[0].width = width; + images[0].height = height; + images[0].pixels = pixels; + + glfwSetWindowIcon(m_Window, 1, images); + + stbi_image_free(pixels); +} + void Window::Shutdown() const { glfwDestroyWindow(m_Window); diff --git a/engine/core/Window.h b/engine/core/Window.h index 0eade8f..24cb39d 100644 --- a/engine/core/Window.h +++ b/engine/core/Window.h @@ -39,9 +39,10 @@ public: const std::string& GetTitle() const; WindowSize GetSize(); + void SetWindowIcon() const; void Shutdown() const; private: GLFWwindow* m_Window{}; WindowData m_Data; -}; \ No newline at end of file +}; diff --git a/engine/resources/icons/icon.png b/engine/resources/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..27984edba6288c451c810baf427e440c019ccefd GIT binary patch literal 2678 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" + echo + echo "Commands:" + echo " all Build and run the project in Debug mode" + echo " build-release Build the project in Release mode" + echo " build-debug Build the project in Debug mode" + echo " run-release Run the Release build" + echo " run-debug Run the Debug build" + echo " clean-release Clean Release build files" + echo " clean-debug Clean Debug build files" + echo " clean-release-all Remove all Release build files" + echo " clean-debug-all Remove all Debug build files" + ;; *) - echo "Usage: $0 {all|build-release|build-debug|run-release|run-debug|clean-release|clean-debug|clean-release-all|clean-debug-all}" + echo "Unknown command: $1" + echo "Use --help for a list of available commands" exit 1 ;; esac diff --git a/scripts/InstallLinux.sh b/scripts/InstallLinux.sh new file mode 100755 index 0000000..52af1e6 --- /dev/null +++ b/scripts/InstallLinux.sh @@ -0,0 +1,135 @@ +#!/bin/bash + +# Set variables +LINUX_BUILD_DIR="/usr/local/lib/ferx" +EXECUTABLE_PATH="$LINUX_BUILD_DIR/editor/ferx" + +# Detect the Linux distribution +detect_distro() { + if [ -f /etc/os-release ]; then + . /etc/os-release + + if [[ "$ID_LIKE" == *"ubuntu"* ]] || [[ "$ID_LIKE" == *"debian"* ]]; then + echo "ubuntu" + + elif [[ "$ID_LIKE" == *"rhel"* ]] || [[ "$ID_LIKE" == *"centos"* ]] || [[ "$ID_LIKE" == *"fedora"* ]]; then + echo "fedora" + + elif [[ "$ID_LIKE" == *"arch"* ]]; then + echo "arch" + + else + echo "$ID" + fi + else + echo "unknown" + fi +} + +install_ubuntu() { + echo "Installing dependencies for Ubuntu/Debian..." + sudo apt update && sudo apt install -y libxkbcommon-dev libxinerama-dev libwayland-dev libxrandr-dev libxcursor-dev libxi-dev mesa-common-dev +} + +install_fedora() { + echo "Installing dependencies for Fedora/RHEL/CentOS..." + sudo dnf install -y libxkbcommon-devel libXinerama-devel wayland-devel libXrandr-devel libXcursor-devel libXi-devel mesa-libGL-devel +} + +install_arch() { + echo "Installing dependencies for Arch Linux..." + sudo pacman -Syu libxkbcommon libxinerama wayland libxrandr libxcursor libxi mesa +} + +# Install Linux Dependencies +install_dependencies() { + distro=$(detect_distro) + + case "$distro" in + ubuntu) + install_ubuntu + ;; + fedora) + install_fedora + ;; + arch) + install_arch + ;; + *) + echo "Unsupported distribution: $distro" + exit 1 + ;; + esac +} + +# Build project in global directory +build(){ + echo "Building project..." + sudo cmake -S .. -B "$LINUX_BUILD_DIR" -G Ninja -DCMAKE_BUILD_TYPE=Release -DGLFW_BUILD_WAYLAND=OFF -DGLFW_BUILD_X11=ON + sudo cmake --build "$LINUX_BUILD_DIR" -j8 + + echo "Creating symbolic link for executable..." + sudo ln -sf "$EXECUTABLE_PATH" /usr/local/bin/ferx +} + +# Install .desktop file +install_desktop_file() { + if [ ! -d "$LINUX_BUILD_DIR" ]; then + echo "Build directory not found! Please build the project first." + exit 1 + fi + + echo "Installing configurations..." + sudo cmake --install "$LINUX_BUILD_DIR" --prefix /usr/ +} + +case $1 in + install-dependencies) + install_dependencies + ;; + install-ubuntu) + install_ubuntu + ;; + install-fedora) + install_fedora + ;; + install-arch) + install_arch + ;; + --help) + echo "Usage: $0 " + echo + echo "This script helps with the installation and setup of the Ferx project." + echo "It supports installing dependencies, building the project, and creating symlinks for easy access." + echo + echo "Commands:" + echo " install-dependencies - Automatically installs dependencies based on the detected Linux distribution" + echo " install-ubuntu - Installs dependencies using apt for Ubuntu/Debian" + echo " install-fedora - Installs dependencies using dnf for Fedora/RHEL" + echo " install-arch - Installs dependencies using pacman for Arch Linux" + echo " build - Builds the project and installs it into /usr/local/lib/ferx" + echo " install-desktop-file - Installs the .desktop file and creates a symbolic link to the executable" + echo + echo "If no command is specified, the script will automatically follow all steps:" + echo " 1. Install dependencies based on your Linux distribution" + echo " 2. Build the project and install it into /usr/local/lib/ferx" + echo " 3. Install the .desktop file and create a symbolic link for easy access" + echo + echo "Examples:" + echo " $0 install-dependencies - Automatically installs dependencies based on your distribution." + echo " $0 build - Builds the project in /usr/local/lib/ferx." + echo " $0 install-desktop-file - Installs the .desktop file and creates a symlink." + echo " $0 - Executes all steps: installs dependencies, builds the project, and installs the desktop file." + echo + echo "To run the full process without specifying a command, just run the script without arguments." + echo "It will automatically handle installing dependencies, building the project, and installing the desktop file." + echo + ;; + *) + install_dependencies + build + install_desktop_file + + echo "Installation complete!" + ;; +esac diff --git a/scripts/Makefile b/scripts/Makefile index 7975e90..82026ca 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -1,25 +1,93 @@ DEBUG_BUILD_DIR = build-debug RELEASE_BUILD_DIR = build-release -EDITOR_DIR = editor -NAME = ferx +EXECUTABLE_PATH = editor/ferx + +LINUX_BUILD_DIR = /usr/local/lib/ferx +LINUX_INSTALL_FILE_PATH = InstallLinux.sh RM += -r -all: build-debug run-debug +all: debug + +# Help +help: + @echo "Usage: make " + @echo + @echo "Targets:" + @echo " help Show this help message" + @echo " install-dependencies Install project dependencies based on the detected Linux distribution" + @echo " install-ubuntu Install dependencies for Ubuntu/Debian-based systems" + @echo " install-fedora Install dependencies for Fedora/RHEL-based systems" + @echo " install-arch Install dependencies for Arch Linux" + @echo " linux Install dependencies, build, and set up the project for Linux" + @echo " debug Build and run the project in Debug mode" + @echo " release Build and run the project in Release mode" + @echo " build-debug Build the project in Debug mode" + @echo " build-release Build the project in Release mode" + @echo " run-debug Run the Debug build" + @echo " run-release Run the Release build" + @echo " clean-debug Clean Debug build files" + @echo " clean-release Clean Release build files" + @echo " clean-debug-all Remove all Debug build files" + @echo " clean-release-all Remove all Release build files" + @echo + @echo "If no target is specified, the script will default to building the Debug version." + @echo "You can also specify a target to run the corresponding command. For example:" + @echo " make help - Displays this help message." + @echo " make linux - Installs dependencies, builds, and sets up the project for Linux." + @echo " make debug - Builds the project in Debug mode and runs it." + @echo " make release - Builds the project in Release mode and runs it." + @echo " make clean-debug-all - Removes all Debug build files." + @echo " make clean-release-all - Removes all Release build files." + +# Install for Linux +linux: install-dependencies build-linux install-desktop-file run-linux + +install-dependencies: + @echo "Detecting platform..." + @sh ./${LINUX_INSTALL_FILE_PATH} install-dependencies + +install-ubuntu: + @echo "Installing dependencies for Ubuntu..." + @sh ./${LINUX_INSTALL_FILE_PATH} install-ubuntu + +install-fedora: + @echo "Installing dependencies for Fedora..." + @sh ./${LINUX_INSTALL_FILE_PATH} install-fedora + +install-arch: + @echo "Installing dependencies for Arch Linux..." + @sh ./${LINUX_INSTALL_FILE_PATH} install-arch + +build-linux: + sudo cmake -S .. -B $(LINUX_BUILD_DIR) -G Ninja -DCMAKE_BUILD_TYPE=Release -DGLFW_BUILD_WAYLAND=OFF -DGLFW_BUILD_X11=ON + sudo cmake --build $(LINUX_BUILD_DIR) -j8 + sudo ln -sf ${LINUX_BUILD_DIR}/${EXECUTABLE_PATH} /usr/local/bin/ferx + +run-linux: + ferx + +install-desktop-file: + sudo cmake --install ${LINUX_BUILD_DIR} --prefix /usr/ + +# Build project +debug: build-debug run-debug + +release: build-release run-release build-release: - cmake -S .. -B ../$(RELEASE_BUILD_DIR) -G Ninja -DCMAKE_BUILD_TYPE=Release + cmake -S .. -B ../$(RELEASE_BUILD_DIR) -G Ninja -DCMAKE_BUILD_TYPE=Release -DGLFW_BUILD_WAYLAND=OFF -DGLFW_BUILD_X11=ON cmake --build ../$(RELEASE_BUILD_DIR) -j8 build-debug: - cmake -S .. -B ../$(DEBUG_BUILD_DIR) -G Ninja -DCMAKE_BUILD_TYPE=Debug + cmake -S .. -B ../$(DEBUG_BUILD_DIR) -G Ninja -DCMAKE_BUILD_TYPE=Debug -DGLFW_BUILD_WAYLAND=OFF -DGLFW_BUILD_X11=ON cmake --build ../$(DEBUG_BUILD_DIR) -j8 run-release: - cd ../$(RELEASE_BUILD_DIR)/${EDITOR_DIR} && ./${NAME} + ../$(RELEASE_BUILD_DIR)/${EXECUTABLE_PATH} run-debug: - cd ../$(DEBUG_BUILD_DIR)/${EDITOR_DIR} && ./${NAME} + ../$(DEBUG_BUILD_DIR)/${EXECUTABLE_PATH} clean-release: cmake --build ../$(RELEASE_BUILD_DIR) --target clean