bottom icon indicating copy to clipboard operation
bottom copied to clipboard

Termux support

Open Fogapod opened this issue 4 years ago • 8 comments

Describe the feature request

Hi, would it be possible to make battery optional? It isn't even shown by default, so it might be a good idea to make it optional (enabled by default) and maybe make other features optional as well.

Reason

I tried compiling bottom for Termux, android terminal emulator. The only dependency that doesn't seem to compile is battery. Dev said that they won't support android multiple times:

  • https://github.com/svartalf/rust-battery/issues/33#issuecomment-529193904
  • https://github.com/svartalf/rust-battery/issues/33#issuecomment-689370864

Fogapod avatar Aug 17 '21 18:08 Fogapod

Sure, I can look at that. Shouldn't be too hard to do.

ClementTsang avatar Aug 17 '21 18:08 ClementTsang

Just a heads up, the linked PR would solve the battery dependency (and technically this issue), but there's still a bit of stuff to fix before you can compile on Termux - whole lotta OS-specific code that I need to set defaults for.

ClementTsang avatar Aug 18 '21 04:08 ClementTsang

Yeah, I just tried that branch and there is a bunch of stuff missing:

error[E0433]: failed to resolve: could not find `MemHarvest` in `memory`
  --> src/app/data_farmer.rs:77:37
   |
77 |             memory_harvest: memory::MemHarvest::default(),
   |                                     ^^^^^^^^^^ could not find `MemHarvest` in `memory`

error[E0433]: failed to resolve: could not find `MemHarvest` in `memory`
  --> src/app/data_farmer.rs:78:35
   |
78 |             swap_harvest: memory::MemHarvest::default(),
   |                                   ^^^^^^^^^^ could not find `MemHarvest` in `memory`

error[E0433]: failed to resolve: could not find `CpuHarvest` in `cpu`
  --> src/app/data_farmer.rs:79:31
   |
79 |             cpu_harvest: cpu::CpuHarvest::default(),
   |                               ^^^^^^^^^^ could not find `CpuHarvest` in `cpu`

error[E0433]: failed to resolve: could not find `IoHarvest` in `disks`
  --> src/app/data_farmer.rs:83:32
   |
83 |             io_harvest: disks::IoHarvest::default(),
   |                                ^^^^^^^^^ could not find `IoHarvest` in `disks`

error[E0433]: failed to resolve: could not find `MemHarvest` in `memory`
  --> src/app/data_farmer.rs:97:39
   |
97 |         self.memory_harvest = memory::MemHarvest::default();
   |                                       ^^^^^^^^^^ could not find `MemHarvest` in `memory`

error[E0433]: failed to resolve: could not find `MemHarvest` in `memory`
  --> src/app/data_farmer.rs:98:37
   |
98 |         self.swap_harvest = memory::MemHarvest::default();
   |                                     ^^^^^^^^^^ could not find `MemHarvest` in `memory`

error[E0433]: failed to resolve: could not find `CpuHarvest` in `cpu`
  --> src/app/data_farmer.rs:99:33
   |
99 |         self.cpu_harvest = cpu::CpuHarvest::default();
   |                                 ^^^^^^^^^^ could not find `CpuHarvest` in `cpu`

error[E0433]: failed to resolve: could not find `IoHarvest` in `disks`
   --> src/app/data_farmer.rs:102:34
    |
102 |         self.io_harvest = disks::IoHarvest::default();
    |                                  ^^^^^^^^^ could not find `IoHarvest` in `disks`

error[E0433]: failed to resolve: use of undeclared crate or module `heim`
  --> src/utils/error.rs:52:11
   |
52 | impl From<heim::Error> for BottomError {
   |           ^^^^ use of undeclared crate or module `heim`

error[E0433]: failed to resolve: use of undeclared crate or module `heim`
  --> src/utils/error.rs:53:18
   |
53 |     fn from(err: heim::Error) -> Self {
   |                  ^^^^ use of undeclared crate or module `heim`

error[E0412]: cannot find type `MemHarvest` in module `memory`
  --> src/app/data_farmer.rs:56:33
   |
56 |     pub memory_harvest: memory::MemHarvest,
   |                                 ^^^^^^^^^^ not found in `memory`

error[E0412]: cannot find type `MemHarvest` in module `memory`
  --> src/app/data_farmer.rs:57:31
   |
57 |     pub swap_harvest: memory::MemHarvest,
   |                               ^^^^^^^^^^ not found in `memory`

error[E0412]: cannot find type `CpuHarvest` in module `cpu`
  --> src/app/data_farmer.rs:58:27
   |
58 |     pub cpu_harvest: cpu::CpuHarvest,
   |                           ^^^^^^^^^^ not found in `cpu`

error[E0412]: cannot find type `DiskHarvest` in module `disks`
  --> src/app/data_farmer.rs:61:34
   |
61 |     pub disk_harvest: Vec<disks::DiskHarvest>,
   |                                  ^^^^^^^^^^^ not found in `disks`

error[E0412]: cannot find type `IoHarvest` in module `disks`
  --> src/app/data_farmer.rs:62:28
   |
62 |     pub io_harvest: disks::IoHarvest,
   |                            ^^^^^^^^^ not found in `disks`

error[E0412]: cannot find type `MemHarvest` in module `memory`
   --> src/app/data_farmer.rs:191:36
    |
191 |         &mut self, memory: memory::MemHarvest, swap: memory::MemHarvest, new_entry: &mut TimedData,
    |                                    ^^^^^^^^^^ not found in `memory`

error[E0412]: cannot find type `MemHarvest` in module `memory`
   --> src/app/data_farmer.rs:191:62
    |
191 |         &mut self, memory: memory::MemHarvest, swap: memory::MemHarvest, new_entry: &mut TimedData,
    |                                                              ^^^^^^^^^^ not found in `memory`

error[E0412]: cannot find type `CpuData` in module `cpu`
   --> src/app/data_farmer.rs:219:41
    |
219 |     fn eat_cpu(&mut self, cpu: Vec<cpu::CpuData>, new_entry: &mut TimedData) {
    |                                         ^^^^^^^ not found in `cpu`

error[E0412]: cannot find type `DiskHarvest` in module `disks`
   --> src/app/data_farmer.rs:241:38
    |
241 |         &mut self, disks: Vec<disks::DiskHarvest>, io: disks::IoHarvest, harvested_time: Instant,
    |                                      ^^^^^^^^^^^ not found in `disks`

error[E0412]: cannot find type `IoHarvest` in module `disks`
   --> src/app/data_farmer.rs:241:63
    |
241 |         &mut self, disks: Vec<disks::DiskHarvest>, io: disks::IoHarvest, harvested_time: Instant,
    |                                                               ^^^^^^^^^ not found in `disks`

error[E0412]: cannot find type `CpuHarvest` in module `cpu`
  --> src/app/data_harvester.rs:32:26
   |
32 |     pub cpu: Option<cpu::CpuHarvest>,
   |                          ^^^^^^^^^^ not found in `cpu`

error[E0412]: cannot find type `MemHarvest` in module `memory`
  --> src/app/data_harvester.rs:34:32
   |
34 |     pub memory: Option<memory::MemHarvest>,
   |                                ^^^^^^^^^^ not found in `memory`

error[E0412]: cannot find type `MemHarvest` in module `memory`
  --> src/app/data_harvester.rs:35:30
   |
35 |     pub swap: Option<memory::MemHarvest>,
   |                              ^^^^^^^^^^ not found in `memory`

error[E0412]: cannot find type `DiskHarvest` in module `disks`
  --> src/app/data_harvester.rs:39:34
   |
39 |     pub disks: Option<Vec<disks::DiskHarvest>>,
   |                                  ^^^^^^^^^^^ not found in `disks`

error[E0412]: cannot find type `IoHarvest` in module `disks`
  --> src/app/data_harvester.rs:40:27
   |
40 |     pub io: Option<disks::IoHarvest>,
   |                           ^^^^^^^^^ not found in `disks`

error[E0412]: cannot find type `PastCpuWork` in module `cpu`
  --> src/app/data_harvester.rs:86:35
   |
86 |     previous_cpu_times: Vec<(cpu::PastCpuWork, cpu::PastCpuTotal)>,
   |                                   ^^^^^^^^^^^ not found in `cpu`

error[E0412]: cannot find type `PastCpuTotal` in module `cpu`
  --> src/app/data_harvester.rs:86:53
   |
86 |     previous_cpu_times: Vec<(cpu::PastCpuWork, cpu::PastCpuTotal)>,
   |                                                     ^^^^^^^^^^^^ not found in `cpu`

error[E0412]: cannot find type `PastCpuWork` in module `cpu`
  --> src/app/data_harvester.rs:87:45
   |
87 |     previous_average_cpu_time: Option<(cpu::PastCpuWork, cpu::PastCpuTotal)>,
   |                                             ^^^^^^^^^^^ not found in `cpu`

error[E0412]: cannot find type `PastCpuTotal` in module `cpu`
  --> src/app/data_harvester.rs:87:63
   |
87 |     previous_average_cpu_time: Option<(cpu::PastCpuWork, cpu::PastCpuTotal)>,
   |                                                               ^^^^^^^^^^^^ not found in `cpu`

error[E0425]: cannot find function `get_cpu_data_list` in module `cpu`
   --> src/app/data_harvester.rs:229:40
    |
229 |             if let Ok(cpu_data) = cpu::get_cpu_data_list(
    |                                        ^^^^^^^^^^^^^^^^^ not found in `cpu`

error[E0425]: cannot find function `get_load_avg` in module `cpu`
   --> src/app/data_harvester.rs:242:49
    |
242 |                 if let Ok(load_avg_data) = cpu::get_load_avg().await {
    |                                                 ^^^^^^^^^^^^ not found in `cpu`

error[E0425]: cannot find function `get_process_data` in module `processes`
   --> src/app/data_harvester.rs:276:32
    |
276 |                     processes::get_process_data(
    |                                ^^^^^^^^^^^^^^^^ not found in `processes`

error[E0425]: cannot find function `get_network_data` in module `network`
   --> src/app/data_harvester.rs:302:26
    |
302 |                 network::get_network_data(
    |                          ^^^^^^^^^^^^^^^^ not found in `network`

error[E0425]: cannot find function `get_mem_data` in module `memory`
   --> src/app/data_harvester.rs:312:36
    |
312 |         let mem_data_fut = memory::get_mem_data(self.widgets_to_harvest.use_mem);
    |                                    ^^^^^^^^^^^^ not found in `memory`

error[E0425]: cannot find function `get_disk_usage` in module `disks`
   --> src/app/data_harvester.rs:313:36
    |
313 |         let disk_data_fut = disks::get_disk_usage(
    |                                    ^^^^^^^^^^^^^^ not found in `disks`

error[E0425]: cannot find function `get_io_usage` in module `disks`
   --> src/app/data_harvester.rs:318:40
    |
318 |         let disk_io_usage_fut = disks::get_io_usage(self.widgets_to_harvest.use_disk);
    |                                        ^^^^^^^^^^^^ not found in `disks`

error[E0425]: cannot find function `get_temperature_data` in module `temperature`
   --> src/app/data_harvester.rs:322:30
    |
322 |                 temperature::get_temperature_data(
    |                              ^^^^^^^^^^^^^^^^^^^^ not found in `temperature`

error[E0425]: cannot find value `MAX_SIGNAL` in this scope
    --> src/app.rs:1124:61
     |
1124 |                 KillSignal::Kill(signal) => min(signal + 8, MAX_SIGNAL),
     |                                                             ^^^^^^^^^^ not found in this scope

error[E0425]: cannot find value `MAX_SIGNAL` in this scope
    --> src/app.rs:2328:73
     |
2328 |             self.delete_dialog_state.selected_signal = KillSignal::Kill(MAX_SIGNAL);
     |                                                                         ^^^^^^^^^^ not found in this scope

error[E0609]: no field `total_rx` on type `&_`
   --> src/app/data_harvester.rs:350:42
    |
350 |                 self.total_rx = net_data.total_rx;
    |                                          ^^^^^^^^

error[E0282]: type annotations needed
  --> src/app/data_harvester.rs:49:18
   |
49 |             cpu: None,
   |                  ^^^^ cannot infer type for type parameter `T` declared on the enum `Option`

error[E0282]: type annotations needed
   --> src/app/data_harvester.rs:115:33
    |
115 |             previous_cpu_times: vec![],
    |                                 ^^^^^^ cannot infer type for type parameter `T`
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0282]: type annotations needed
   --> src/canvas/dialogs/dd_dialog.rs:289:68
    |
142 |                 let signal_text;
    |                     ----------- consider giving `signal_text` a type
...
289 |                     ..min((layout.len() as usize) + scroll_offset, signal_text.len())]
    |                                                                    ^^^^^^^^^^^ cannot infer type
    |
    = note: type must be known at this point

error: aborting due to 43 previous errors

I poked it a bit, it looks like heim does not support memory/IO/CPU/sensors on target_os = "android", so it's completely unusable

Fogapod avatar Aug 18 '21 20:08 Fogapod

Yeah, I already have OS-specific cfg setups to leverage sysinfo which does compile for Android (afaik), so I just really need to set those up and try it.

ClementTsang avatar Aug 18 '21 20:08 ClementTsang

Oh, that's good news. If you need any help testing, let me know. Having this thing run on Termux would be awesome

Fogapod avatar Aug 18 '21 20:08 Fogapod

Sorry for the slow updates on this, still busy with some other stuff.

Going to rename this issue since the original problem (optional battery dependency) is fixed, but the core issue (termux support) is still WIP.

Hopefully I can tackle this soon.

ClementTsang avatar Oct 11 '21 04:10 ClementTsang

Would fixing this issue also solve the /proc/stat issue?

PS: thank you so much for bottom!

alexanderadam avatar Jan 15 '22 11:01 alexanderadam

@alexanderadam Potentially? It would depend on whatever library I use/a custom implementation and how they gather stats.

There's probably far more issues than just /proc/stat though; last time I tried compiling on Termux, it straight up wouldn't work since some of the code I have makes assumptions that don't take into account Android. There's a bit of stuff I would need to tinker with.

I haven't looked into this at all recently though, unfortunately.

ClementTsang avatar Jan 15 '22 12:01 ClementTsang

Just an update since I haven't looked at this for over a year (sorry!):

Building for the aarch64-linux-android target via cross on #1112 yields:

➜ cross build --target aarch64-linux-android --no-default-features
   Compiling bottom v0.9.0 (/home/clement/projects/bottom)
error[E0425]: cannot find function `get_process_data` in module `processes`
   --> src/app/data_harvester.rs:361:36
    |
361 |                         processes::get_process_data(
    |                                    ^^^^^^^^^^^^^^^^ not found in `processes`

error[E0425]: cannot find function `get_temperature_data` in module `temperature`
   --> src/app/data_harvester.rs:393:44
    |
393 |             if let Ok(data) = temperature::get_temperature_data(
    |                                            ^^^^^^^^^^^^^^^^^^^^ not found in `temperature`

error[E0425]: cannot find function `io_stats` in this scope
  --> src/app/data_harvester/disks.rs:57:23
   |
57 |             for io in io_stats()?.into_iter().flatten() {
   |                       ^^^^^^^^ not found in this scope

For more information about this error, try `rustc --explain E0425`.
error: could not compile `bottom` due to 3 previous errors

So I just need to add fallbacks/dummy implementations, and I think it'll at least compile on Android/Temux, fingers crossed.

ClementTsang avatar Apr 21 '23 09:04 ClementTsang

Closing this as the project should build against Android now.

ClementTsang avatar Jun 11 '23 06:06 ClementTsang

Just tested on Termux, cargo install --locked bottom --no-default-features worked and I could run btm after.

ClementTsang avatar Jun 14 '23 07:06 ClementTsang