Skip to content

Commit 65f3ade

Browse files
authored
Merge branch 'main' into unix-duplicates
2 parents ab0bef2 + e813767 commit 65f3ade

16 files changed

+361
-82
lines changed

CMakeLists.txt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ if(APPLE)
6565
target_sources(btop PRIVATE src/osx/btop_collect.cpp src/osx/sensors.cpp src/osx/smc.cpp)
6666
elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
6767
target_sources(btop PRIVATE src/freebsd/btop_collect.cpp)
68+
elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
69+
target_sources(btop PRIVATE src/openbsd/btop_collect.cpp src/openbsd/sysctlbyname.cpp)
6870
elseif(LINUX)
6971
target_sources(btop PRIVATE src/linux/btop_collect.cpp)
7072
else()
@@ -110,6 +112,7 @@ if(HAS_FCF_PROTECTION)
110112
endif()
111113

112114
target_compile_definitions(btop PRIVATE
115+
FMT_HEADER_ONLY
113116
_FILE_OFFSET_BITS=64
114117
$<$<CONFIG:Debug>:_GLIBCXX_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS=1>
115118
# Only has an effect with optimizations enabled
@@ -179,12 +182,18 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
179182
endif()
180183

181184
find_package(devstat REQUIRED)
182-
target_link_libraries(btop devstat::devstat)
185+
find_package(kvm REQUIRED)
186+
target_link_libraries(btop devstat::devstat kvm::kvm)
183187
if(BTOP_STATIC)
184188
find_package(elf REQUIRED)
185-
find_package(kvm REQUIRED)
186-
target_link_libraries(btop elf::elf kvm::kvm)
189+
target_link_libraries(btop elf::elf)
187190
endif()
191+
elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
192+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
193+
target_compile_options(btop PRIVATE -static-libstdc++)
194+
endif()
195+
find_package(kvm REQUIRED)
196+
target_link_libraries(btop kvm::kvm)
188197
endif()
189198

190199
install(TARGETS btop RUNTIME)

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ else ifeq ($(PLATFORM_LC),macos)
143143
else ifeq ($(PLATFORM_LC),openbsd)
144144
PLATFORM_DIR := openbsd
145145
THREADS := $(shell sysctl -n hw.ncpu || echo 1)
146-
override ADDFLAGS += -lkvm
146+
override ADDFLAGS += -lkvm -static-libstdc++
147147
export MAKE = gmake
148148
SU_GROUP := wheel
149149
else
@@ -179,7 +179,7 @@ override GOODFLAGS := $(foreach flag,$(TESTFLAGS),$(strip $(shell echo "int main
179179
override REQFLAGS := -std=c++20
180180
WARNFLAGS := -Wall -Wextra -pedantic
181181
OPTFLAGS := -O2 -ftree-vectorize -flto=$(LTO)
182-
LDCXXFLAGS := -pthread -D_GLIBCXX_ASSERTIONS -D_FILE_OFFSET_BITS=64 $(GOODFLAGS) $(ADDFLAGS)
182+
LDCXXFLAGS := -pthread -DFMT_HEADER_ONLY -D_GLIBCXX_ASSERTIONS -D_FILE_OFFSET_BITS=64 $(GOODFLAGS) $(ADDFLAGS)
183183
override CXXFLAGS += $(REQFLAGS) $(LDCXXFLAGS) $(OPTFLAGS) $(WARNFLAGS)
184184
override LDFLAGS += $(LDCXXFLAGS) $(OPTFLAGS) $(WARNFLAGS)
185185
INC := $(foreach incdir,$(INCDIRS),-isystem $(incdir)) -I$(SRCDIR)

README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,74 @@ If you have an AMD GPU `rocm_smi_lib` is required, which may or may not be packa
995995
gmake help
996996
```
997997
998+
</details>
999+
<details>
1000+
<summary>
1001+
1002+
### With CMake (Community maintained)
1003+
</summary>
1004+
1005+
1. **Install build dependencies**
1006+
1007+
Requires GCC, CMake, Ninja and Git
1008+
1009+
_**Note:** LLVM's libc++ shipped with OpenBSD 7.4 is too old and cannot compile btop._
1010+
1011+
```bash
1012+
pkg_add cmake g++%11 git ninja
1013+
```
1014+
1015+
2. **Clone the repository**
1016+
1017+
```bash
1018+
git clone https://github.com/aristocratos/btop.git && cd btop
1019+
```
1020+
1021+
3. **Compile**
1022+
1023+
```bash
1024+
# Configure
1025+
CXX=eg++ cmake -B build -G Ninja
1026+
# Build
1027+
cmake --build build
1028+
```
1029+
1030+
This will automatically build a release version of btop.
1031+
1032+
Some useful options to pass to the configure step:
1033+
1034+
| Configure flag | Description |
1035+
|---------------------------------|-------------------------------------------------------------------------|
1036+
| `-DBTOP_LTO=<ON\|OFF>` | Enables link time optimization (ON by default) |
1037+
| `-DBTOP_USE_MOLD=<ON\|OFF>` | Use mold to link btop (OFF by default) |
1038+
| `-DBTOP_PEDANTIC=<ON\|OFF>` | Compile with additional warnings (OFF by default) |
1039+
| `-DBTOP_WERROR=<ON\|OFF>` | Compile with warnings as errors (OFF by default) |
1040+
| `-DBTOP_FORTIFY=<ON\|OFF>` | Detect buffer overflows with `_FORTIFY_SOURCE=3` (ON by default) |
1041+
| `-DCMAKE_INSTALL_PREFIX=<path>` | The installation prefix ('/usr/local' by default) |
1042+
1043+
To force any other compiler, run `CXX=<compiler> cmake -B build -G Ninja`
1044+
1045+
4. **Install**
1046+
1047+
```bash
1048+
cmake --install build
1049+
```
1050+
1051+
May require root privileges
1052+
1053+
5. **Uninstall**
1054+
1055+
CMake doesn't generate an uninstall target by default. To remove installed files, run
1056+
```
1057+
cat build/install_manifest.txt | xargs rm -irv
1058+
```
1059+
1060+
6. **Cleanup build directory**
1061+
1062+
```bash
1063+
cmake --build build -t clean
1064+
```
1065+
9981066
</details>
9991067
10001068
## Installing the snap

cmake/Modules/Findkvm.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Find libkvm, the Kernel Data Access Library
44
#
55

6-
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
6+
if(BSD)
77
find_path(kvm_INCLUDE_DIR NAMES kvm.h)
88
find_library(kvm_LIBRARY NAMES kvm)
99

src/btop.cpp

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ tab-size = 4
5353
#include "btop_draw.hpp"
5454
#include "btop_menu.hpp"
5555
#include "fmt/core.h"
56+
#include "fmt/ostream.h"
5657

5758
using std::atomic;
5859
using std::cout;
@@ -108,6 +109,7 @@ namespace Global {
108109
atomic<bool> should_sleep (false);
109110
atomic<bool> _runner_started (false);
110111
atomic<bool> init_conf (false);
112+
atomic<bool> reload_conf (false);
111113

112114
bool arg_tty{};
113115
bool arg_low_color{};
@@ -364,7 +366,36 @@ void _signal_handler(const int sig) {
364366
case SIGUSR1:
365367
// Input::poll interrupt
366368
break;
369+
case SIGUSR2:
370+
Global::reload_conf = true;
371+
Input::interrupt();
372+
break;
373+
}
374+
}
375+
376+
//* Config init
377+
void init_config(){
378+
atomic_lock lck(Global::init_conf);
379+
vector<string> load_warnings;
380+
Config::load(Config::conf_file, load_warnings);
381+
Config::set("lowcolor", (Global::arg_low_color ? true : not Config::getB("truecolor")));
382+
383+
static bool first_init = true;
384+
385+
if (Global::debug and first_init) {
386+
Logger::set("DEBUG");
387+
Logger::debug("Running in DEBUG mode!");
388+
}
389+
else Logger::set(Config::getS("log_level"));
390+
391+
static string log_level;
392+
if (const string current_level = Config::getS("log_level"); log_level != current_level) {
393+
log_level = current_level;
394+
Logger::info("Logger set to " + (Global::debug ? "DEBUG" : log_level));
367395
}
396+
397+
for (const auto& err_str : load_warnings) Logger::warning(err_str);
398+
first_init = false;
368399
}
369400

370401
//* Manages secondary thread for collection and drawing of boxes
@@ -895,22 +926,7 @@ int main(int argc, char **argv) {
895926
}
896927

897928
//? Config init
898-
{
899-
atomic_lock lck(Global::init_conf);
900-
vector<string> load_warnings;
901-
Config::load(Config::conf_file, load_warnings);
902-
Config::set("lowcolor", (Global::arg_low_color ? true : not Config::getB("truecolor")));
903-
904-
if (Global::debug) {
905-
Logger::set("DEBUG");
906-
Logger::debug("Starting in DEBUG mode!");
907-
}
908-
else Logger::set(Config::getS("log_level"));
909-
910-
Logger::info("Logger set to " + (Global::debug ? "DEBUG" : Config::getS("log_level")));
911-
912-
for (const auto& err_str : load_warnings) Logger::warning(err_str);
913-
}
929+
init_config();
914930

915931
//? Try to find and set a UTF-8 locale
916932
if (std::setlocale(LC_ALL, "") != nullptr and not s_contains((string)std::setlocale(LC_ALL, ""), ";")
@@ -920,7 +936,7 @@ int main(int argc, char **argv) {
920936
else {
921937
string found;
922938
bool set_failure{};
923-
for (const auto loc_env : array{"LANG", "LC_ALL"}) {
939+
for (const auto loc_env : array{"LANG", "LC_ALL", "LC_CTYPE"}) {
924940
if (std::getenv(loc_env) != nullptr and str_to_upper(s_replace((string)std::getenv(loc_env), "-", "")).ends_with("UTF8")) {
925941
found = std::getenv(loc_env);
926942
if (std::setlocale(LC_ALL, found.c_str()) == nullptr) {
@@ -1035,6 +1051,7 @@ int main(int argc, char **argv) {
10351051
std::signal(SIGCONT, _signal_handler);
10361052
std::signal(SIGWINCH, _signal_handler);
10371053
std::signal(SIGUSR1, _signal_handler);
1054+
std::signal(SIGUSR2, _signal_handler);
10381055

10391056
sigset_t mask;
10401057
sigemptyset(&mask);
@@ -1086,9 +1103,27 @@ int main(int argc, char **argv) {
10861103
try {
10871104
while (not true not_eq not false) {
10881105
//? Check for exceptions in secondary thread and exit with fail signal if true
1089-
if (Global::thread_exception) clean_quit(1);
1090-
else if (Global::should_quit) clean_quit(0);
1091-
else if (Global::should_sleep) { Global::should_sleep = false; _sleep(); }
1106+
if (Global::thread_exception) {
1107+
clean_quit(1);
1108+
}
1109+
else if (Global::should_quit) {
1110+
clean_quit(0);
1111+
}
1112+
else if (Global::should_sleep) {
1113+
Global::should_sleep = false;
1114+
_sleep();
1115+
}
1116+
//? Hot reload config from CTRL + R or SIGUSR2
1117+
else if (Global::reload_conf) {
1118+
Global::reload_conf = false;
1119+
if (Runner::active) Runner::stop();
1120+
Config::unlock();
1121+
init_config();
1122+
Theme::updateThemes();
1123+
Theme::setTheme();
1124+
Draw::banner_gen(0, 0, false, true);
1125+
Global::resized = true;
1126+
}
10921127

10931128
//? Make sure terminal size hasn't changed (in case of SIGWINCH not working properly)
10941129
term_resize(Global::resized);
@@ -1123,9 +1158,9 @@ int main(int argc, char **argv) {
11231158
update_ms = Config::getI("update_ms");
11241159
future_time = time_ms() + update_ms;
11251160
}
1126-
else if (future_time - current_time > update_ms)
1161+
else if (future_time - current_time > update_ms) {
11271162
future_time = current_time;
1128-
1163+
}
11291164
//? Poll for input and process any input detected
11301165
else if (Input::poll(min((uint64_t)1000, future_time - current_time))) {
11311166
if (not Runner::active) Config::unlock();

src/btop_config.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ namespace Config {
199199

200200
{"selected_battery", "#* Which battery to use if multiple are present. \"Auto\" for auto detection."},
201201

202+
{"show_battery_watts", "#* Show power stats of battery next to charge indicator."},
203+
202204
{"log_level", "#* Set loglevel for \"~/.config/btop/btop.log\" levels are: \"ERROR\" \"WARNING\" \"INFO\" \"DEBUG\".\n"
203205
"#* The level set includes all lower levels, i.e. \"DEBUG\" will show all logging info."},
204206
#ifdef GPU_SUPPORT
@@ -293,6 +295,7 @@ namespace Config {
293295
{"net_auto", true},
294296
{"net_sync", true},
295297
{"show_battery", true},
298+
{"show_battery_watts", true},
296299
{"vim_keys", false},
297300
{"tty_mode", false},
298301
{"disk_free_priv", false},
@@ -729,16 +732,17 @@ namespace Config {
729732
if (geteuid() != Global::real_uid and seteuid(Global::real_uid) != 0) return;
730733
std::ofstream cwrite(conf_file, std::ios::trunc);
731734
if (cwrite.good()) {
732-
cwrite << "#? Config file for btop v. " << Global::Version;
735+
cwrite << "#? Config file for btop v. " << Global::Version << "\n";
733736
for (auto [name, description] : descriptions) {
734-
cwrite << "\n\n" << (description.empty() ? "" : description + "\n")
737+
cwrite << "\n" << (description.empty() ? "" : description + "\n")
735738
<< name << " = ";
736739
if (strings.contains(name))
737740
cwrite << "\"" << strings.at(name) << "\"";
738741
else if (ints.contains(name))
739742
cwrite << ints.at(name);
740743
else if (bools.contains(name))
741744
cwrite << (bools.at(name) ? "True" : "False");
745+
cwrite << "\n";
742746
}
743747
}
744748
}

src/btop_draw.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@ namespace Cpu {
706706
if (Config::getB("show_battery") and has_battery) {
707707
static int old_percent{}; // defaults to = 0
708708
static long old_seconds{}; // defaults to = 0
709+
static float old_watts{}; // defaults to = 0
709710
static string old_status;
710711
static Draw::Meter bat_meter {10, "cpu", true};
711712
static const std::unordered_map<string, string> bat_symbols = {
@@ -715,16 +716,18 @@ namespace Cpu {
715716
{"unknown", ""}
716717
};
717718

718-
const auto& [percent, seconds, status] = current_bat;
719+
const auto& [percent, watts, seconds, status] = current_bat;
719720

720-
if (redraw or percent != old_percent or seconds != old_seconds or status != old_status) {
721+
if (redraw or percent != old_percent or (watts != old_watts and Config::getB("show_battery_watts")) or seconds != old_seconds or status != old_status) {
721722
old_percent = percent;
723+
old_watts = watts;
722724
old_seconds = seconds;
723725
old_status = status;
724726
const string str_time = (seconds > 0 ? sec_to_dhms(seconds, true, true) : "");
725727
const string str_percent = to_string(percent) + '%';
728+
const string str_watts = (watts != -1 and Config::getB("show_battery_watts") ? fmt::format("{:.2f}", watts) + 'W' : "");
726729
const auto& bat_symbol = bat_symbols.at((bat_symbols.contains(status) ? status : "unknown"));
727-
const int current_len = (Term::width >= 100 ? 11 : 0) + str_time.size() + str_percent.size() + to_string(Config::getI("update_ms")).size();
730+
const int current_len = (Term::width >= 100 ? 11 : 0) + str_time.size() + str_percent.size() + str_watts.size() + to_string(Config::getI("update_ms")).size();
728731
const int current_pos = Term::width - current_len - 17;
729732

730733
if ((bat_pos != current_pos or bat_len != current_len) and bat_pos > 0 and not redraw)
@@ -734,7 +737,7 @@ namespace Cpu {
734737

735738
out += Mv::to(y, bat_pos) + title_left + Theme::c("title") + Fx::b + "BAT" + bat_symbol + ' ' + str_percent
736739
+ (Term::width >= 100 ? Fx::ub + ' ' + bat_meter(percent) + Fx::b : "")
737-
+ (not str_time.empty() ? ' ' + Theme::c("title") + str_time : " ") + Fx::ub + title_right;
740+
+ (not str_time.empty() ? ' ' + Theme::c("title") + str_time : "") + (not str_watts.empty() ? " " + Theme::c("title") + Fx::b + str_watts : "") + Fx::ub + title_right;
738741
}
739742
}
740743
else if (bat_pos > 0) {
@@ -1361,6 +1364,7 @@ namespace Net {
13611364
int x = 1, y, width = 20, height;
13621365
int b_x, b_y, b_width, b_height, d_graph_height, u_graph_height;
13631366
bool shown = true, redraw = true;
1367+
const int MAX_IFNAMSIZ = 15;
13641368
string old_ip;
13651369
std::unordered_map<string, Draw::Graph> graphs;
13661370
string box;
@@ -1381,7 +1385,7 @@ namespace Net {
13811385
out.reserve(width * height);
13821386
const string title_left = Theme::c("net_box") + Fx::ub + Symbols::title_left;
13831387
const string title_right = Theme::c("net_box") + Fx::ub + Symbols::title_right;
1384-
const int i_size = min((int)selected_iface.size(), 10);
1388+
const int i_size = min((int)selected_iface.size(), MAX_IFNAMSIZ);
13851389
const long long down_max = (net_auto ? safeVal(graph_max, "download"s) : ((long long)(Config::getI("net_download")) << 20) / 8);
13861390
const long long up_max = (net_auto ? safeVal(graph_max, "upload"s) : ((long long)(Config::getI("net_upload")) << 20) / 8);
13871391

@@ -1403,7 +1407,7 @@ namespace Net {
14031407
//? Interface selector and buttons
14041408

14051409
out += Mv::to(y, x+width - i_size - 9) + title_left + Fx::b + Theme::c("hi_fg") + "<b " + Theme::c("title")
1406-
+ uresize(selected_iface, 10) + Theme::c("hi_fg") + " n>" + title_right
1410+
+ uresize(selected_iface, MAX_IFNAMSIZ) + Theme::c("hi_fg") + " n>" + title_right
14071411
+ Mv::to(y, x+width - i_size - 15) + title_left + Theme::c("hi_fg") + (safeVal(net.stat, "download"s).offset + safeVal(net.stat, "upload"s).offset > 0 ? Fx::b : "") + 'z'
14081412
+ Theme::c("title") + "ero" + title_right;
14091413
Input::mouse_mappings["b"] = {y, x+width - i_size - 8, 1, 3};
@@ -2238,3 +2242,4 @@ namespace Draw {
22382242
}
22392243
}
22402244
}
2245+

0 commit comments

Comments
 (0)