From 5c6a2810021c352584a0834c95eff4ece7454c0e Mon Sep 17 00:00:00 2001 From: nobounce Date: Tue, 29 Aug 2023 20:39:00 +0200 Subject: [PATCH] Add CMake support Linux is completly supported FreeBSD is not able to create a static executable for now. See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=273398 MacOS was not tested --- .gitignore | 21 +++- CMakeLists.txt | 167 +++++++++++++++++++++++++++++ README.md | 179 +++++++++++++++++++++++++++++++- cmake/Modules/Finddevstat.cmake | 23 ++++ cmake/Modules/Findelf.cmake | 23 ++++ cmake/Modules/Findkvm.cmake | 23 ++++ 6 files changed, 432 insertions(+), 4 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 cmake/Modules/Finddevstat.cmake create mode 100644 cmake/Modules/Findelf.cmake create mode 100644 cmake/Modules/Findkvm.cmake diff --git a/.gitignore b/.gitignore index 25ee477..14aa9cd 100644 --- a/.gitignore +++ b/.gitignore @@ -51,9 +51,8 @@ bin btop .*/ - -#do not ignore .github directory -!.github +# Don't ignore .github directory +!.github/ # Ignore files created by Qt Creator *.config @@ -64,3 +63,19 @@ btop *.cxxflags *.files *.includes + +# CMake +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps + +# CLion +cmake-build-* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d11a250 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,167 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# CMake configuration for btop +# + +cmake_minimum_required(VERSION 3.12) + +# Disable in-source builds since they would override the Makefile +if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") + message(FATAL_ERROR "In-source builds are not allowed") +endif() + +project("btop" + VERSION 1.2.13 + DESCRIPTION "A monitor of resources" + HOMEPAGE_URL "https://github.com/aristocratos/btop" + LANGUAGES CXX +) + +# Make custom modules available +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/") + +# When the build type is not set we can't fortify +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_COLOR_DIAGNOSTICS ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Options +option(BTOP_STATIC "Link btop statically" OFF) +option(BTOP_LTO "Enable LTO" ON) +option(BTOP_USE_MOLD "Use mold to link btop" OFF) +option(BTOP_PEDANTIC "Enable a bunch of additional warnings" OFF) +option(BTOP_WERROR "Compile with warnings as errors" OFF) + +if(BTOP_STATIC) + # Set this before calling find_package + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + find_package(devstat REQUIRED) + find_package(kvm REQUIRED) + if(BTOP_STATIC) + find_package(elf REQUIRED) + endif() +endif() + +include(CheckCXXCompilerFlag) +include(CheckIPOSupported) + +add_executable(btop + src/btop.cpp + src/btop_config.cpp + src/btop_draw.cpp + src/btop_input.cpp + src/btop_menu.cpp + src/btop_shared.cpp + src/btop_theme.cpp + src/btop_tools.cpp +) + +# NOTE: Checks can be simplified with CMake 3.25 +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + target_sources(btop PRIVATE + src/osx/btop_collect.cpp + src/osx/sensors.cpp + src/osx/smc.cpp + ) +elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + target_sources(btop PRIVATE src/freebsd/btop_collect.cpp) +elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + target_sources(btop PRIVATE src/linux/btop_collect.cpp) +else() + message(FATAL_ERROR "${CMAKE_SYSTEM_NAME} is not supported") +endif() + +# Check for and enable LTO +check_ipo_supported(RESULT ipo_supported) +if(ipo_supported AND BTOP_LTO) + set_target_properties(btop PROPERTIES INTERPROCEDURAL_OPTIMIZATION ON) +endif() + +# TODO: enable more warnings in coordination with upstream +target_compile_options(btop PRIVATE + -Wall -Wextra -Wpedantic + -ftree-vectorize -fstack-clash-protection +) +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_compile_options(btop PRIVATE + -Wheader-hygiene -Wgnu -Wthread-safety + ) +endif() + +if(BTOP_PEDANTIC) + target_compile_options(btop PRIVATE + -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wunused + -Woverloaded-virtual -Wconversion -Wsign-conversion -Wdouble-promotion + -Wformat=2 -Wimplicit-fallthrough -Weffc++ + ) + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_compile_options(btop PRIVATE + -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wnull-dereference + -Wuseless-cast + ) + endif() +endif() + +if(BTOP_WERROR) + target_compile_options(btop PRIVATE -Werror) +endif() + +check_cxx_compiler_flag(-fstack-protector CXX_HAS_FSTACK_PROTECTOR) +if(CXX_HAS_FSTACK_PROTECTOR) + target_compile_options(btop PRIVATE -fstack-protector) +endif() + +check_cxx_compiler_flag(-fcf-protection CXX_HAS_FCF_PROTECTION) +if(CXX_HAS_FCF_PROTECTION) + target_compile_options(btop PRIVATE -fcf-protection) +endif() + +target_compile_definitions(btop PRIVATE + _FILE_OFFSET_BITS=64 + _GLIBCXX_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS=1 + # Only has an effect with optimizations enabled + $<$>:_FORTIFY_SOURCE=2> +) + +target_include_directories(btop SYSTEM PRIVATE include) + +# mold +if(BTOP_USE_MOLD) + target_link_options(btop PRIVATE -fuse-ld=mold) +endif() + +if(BTOP_STATIC) + target_compile_definitions(btop PRIVATE STATIC_BUILD) + target_link_options(btop PRIVATE -static LINKER:--fatal-warnings) +endif() + +# Add libraries +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) +target_link_libraries(btop PRIVATE Threads::Threads) + +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + target_link_libraries(btop PRIVATE $ + + + +### With Make + + 1. **Install dependencies (example for Ubuntu 21.04 Hirsute)** @@ -397,6 +403,79 @@ Also needs a UTF8 locale and a font that covers: make help ``` + + +
+ + + +### With CMake (Community maintained) + + + +1. **Install build dependencies** + + Requires Clang / GCC, CMake, Ninja and Git + + For example, with Debian Bookworm: + + ```bash + sudo apt install cmake git g++ ninja-build + ``` + +2. **Clone the repository** + + ```bash + git clone https://github.com/aristocratos/btop.git && cd btop + `````` + +3. **Compile** + + ```bash + # Configure + cmake -B build -G Ninja + # Build + cmake --build build + ``` + + This will automatically build a release version of btop. + + Some useful options to pass to the configure step: + + | Configure flag | Description | + |---------------------------------|-------------------------------------------------------------------------| + | `-DBTOP_STATIC=` | Enables static linking (OFF by default) | + | `-DBTOP_LTO=` | Enables link time optimization (ON by default) | + | `-DBTOP_USE_MOLD=` | Use mold to link btop (OFF by default) | + | `-DBTOP_PEDANTIC=` | Compile with additional warnings (OFF by default) | + | `-DBTOP_WERROR=` | Compile with warnings as errors (OFF by default) | + | `-DCMAKE_INSTALL_PREFIX=` | The installation prefix ('/usr/local' by default) | + + To force a compiler, run `CXX= cmake -B build -G Ninja` + +4. **Install** + + ```bash + cmake --install build + ``` + + May require root privileges + +5. **Uninstall** + + CMake doesn't generate an uninstall target by default. To remove installed files, run + ``` + cat build/install_manifest.txt | xargs rm -irv + ``` + +6. **Cleanup build directory** + + ```bash + cmake --build build -t clean + ``` + +
+ ## Compilation macOS OSX Needs GCC 10 or higher, (GCC 11 or above strongly recommended for better CPU efficiency in the compiled binary). @@ -493,6 +572,14 @@ Also needs a UTF8 locale and a font that covers: Note that GNU make (`gmake`) is required to compile on FreeBSD. +
+ + + +### With gmake + + + 1. **Install dependencies** ```bash @@ -573,6 +660,96 @@ Also needs a UTF8 locale and a font that covers: gmake help ``` +
+ +
+ + + +### With CMake (Community maintained) + + + +1. **Install build dependencies** + + Requires Clang / GCC, CMake, Ninja and Git + + _**Note:** LLVM's libc++ shipped with FreeBSD 13 is too old and cannot compile btop._ + + FreeBSD 14 and later: + ```bash + pkg install cmake ninja + ``` + + FreeBSD 13: + ```bash + pkg install cmake gcc13 ninja + ``` + +2. **Clone the repository** + + ```bash + git clone https://github.com/aristocratos/btop.git && cd btop + `````` + +3. **Compile** + + FreeBSD 14 and later: + ```bash + # Configure + cmake -B build -G Ninja + # Build + cmake --build build + ``` + + FreeBSD 13: + ```bash + # Configure + CXX=g++13 cmake -B build -G Ninja + # Build + cmake --build build + ``` + + This will automatically build a release version of btop. + + Some useful options to pass to the configure step: + + | Configure flag | Description | + |---------------------------------|-------------------------------------------------------------------------| + | `-DBTOP_STATIC=` | Enables static linking (OFF by default) | + | `-DBTOP_LTO=` | Enables link time optimization (ON by default) | + | `-DBTOP_USE_MOLD=` | Use mold to link btop (OFF by default) | + | `-DBTOP_PEDANTIC=` | Compile with additional warnings (OFF by default) | + | `-DBTOP_WERROR=` | Compile with warnings as errors (OFF by default) | + | `-DCMAKE_INSTALL_PREFIX=` | The installation prefix ('/usr/local' by default) | + + _**Note:** Static linking does not work with GCC._ + + To force a compiler, run `CXX= cmake -B build -G Ninja` + +4. **Install** + + ```bash + cmake --install build + ``` + + May require root privileges + +5. **Uninstall** + + CMake doesn't generate an uninstall target by default. To remove installed files, run + ``` + cat build/install_manifest.txt | xargs rm -irv + ``` + +6. **Cleanup build directory** + + ```bash + cmake --build build -t clean + ``` + +
+ ## Installing the snap [![btop](https://snapcraft.io/btop/badge.svg)](https://snapcraft.io/btop) diff --git a/cmake/Modules/Finddevstat.cmake b/cmake/Modules/Finddevstat.cmake new file mode 100644 index 0000000..694e613 --- /dev/null +++ b/cmake/Modules/Finddevstat.cmake @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Find devstat, the Device Statistics Library +# + +if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + find_path(devstat_INCLUDE_DIR NAMES devstat.h) + find_library(devstat_LIBRARY NAMES devstat) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(devstat REQUIRED_VARS devstat_LIBRARY devstat_INCLUDE_DIR) + + if(devstat_FOUND AND NOT TARGET devstat::devstat) + add_library(devstat::devstat UNKNOWN IMPORTED) + set_target_properties(devstat::devstat PROPERTIES + IMPORTED_LOCATION "${devstat_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${devstat_INCLUDE_DIR}" + ) + endif() + + mark_as_advanced(devstat_INCLUDE_DIR devstat_LIBRARY) +endif() + diff --git a/cmake/Modules/Findelf.cmake b/cmake/Modules/Findelf.cmake new file mode 100644 index 0000000..91e0beb --- /dev/null +++ b/cmake/Modules/Findelf.cmake @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Find libelf, the ELF Access Library +# + +if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + find_path(elf_INCLUDE_DIR NAMES libelf.h) + find_library(elf_LIBRARY NAMES elf) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(elf REQUIRED_VARS elf_LIBRARY elf_INCLUDE_DIR) + + if(elf_FOUND AND NOT TARGET elf::elf) + add_library(elf::elf UNKNOWN IMPORTED) + set_target_properties(elf::elf PROPERTIES + IMPORTED_LOCATION "${elf_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${elf_INCLUDE_DIR}" + ) + endif() + + mark_as_advanced(elf_INCLUDE_DIR elf_LIBRARY) +endif() + diff --git a/cmake/Modules/Findkvm.cmake b/cmake/Modules/Findkvm.cmake new file mode 100644 index 0000000..a0847de --- /dev/null +++ b/cmake/Modules/Findkvm.cmake @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Find libkvm, the Kernel Data Access Library +# + +if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + find_path(kvm_INCLUDE_DIR NAMES kvm.h) + find_library(kvm_LIBRARY NAMES kvm) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(kvm REQUIRED_VARS kvm_LIBRARY kvm_INCLUDE_DIR) + + if(kvm_FOUND AND NOT TARGET kvm::kvm) + add_library(kvm::kvm UNKNOWN IMPORTED) + set_target_properties(kvm::kvm PROPERTIES + IMPORTED_LOCATION "${kvm_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${kvm_INCLUDE_DIR}" + ) + endif() + + mark_as_advanced(kvm_INCLUDE_DIR kvm_LIBRARY) +endif() +