rmkit-dev / rmkit Goto Github PK
View Code? Open in Web Editor NEW| remarkable app framework | https://rmkit.dev
Home Page: https://build.rmkit.dev
| remarkable app framework | https://rmkit.dev
Home Page: https://build.rmkit.dev
This is awesome. I especially like the multi-tasking!
Switching from xochitl to koreader works great. However, I noticed that in order to use remux from koreader, I first have to go to the menu > Exit > Exit, then holding down the middle button will bring up remux successfully. I can switch to xochitl after this, then switch back to koreader, but I always have to exit koreader first before remux will respond to the button long press.
Is this the "better integration with koreader" point you mentioned on the reddit post? Just thought I would outline this issue in case others weren't aware.
We should have a simple package repository that:
This repository should ideally be easy to merge packages into for other devs (minimizing upload friction)
right now the ordering is indeterminate
in some places there are rendering artifacts - for example on the "open" and "flag" buttons. it is likely copying an extra row or not clearing properly
(reported by dixonary)
I saw in 357bb19 that you added #include <string>
to defines.h, but when I build rmkit.h from scratch, the source files are combined so that defines.h ends up below the first time std::string is used. I think this is an issue w/ how okp sorts the dependency graph. Here's the order files are included in my build:
/* FILE: rmkit/src/.rmkit.h_cpp/assets.h */
/* FILE: rmkit/src/.rmkit.h_cpp/fb/mxcfb.h */
/* FILE: rmkit/src/.rmkit.h_cpp/input/device_id.h */ <-- used here
/* FILE: rmkit/src/.rmkit.h_cpp/input/keycodes.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/icons.h */
/* FILE: rmkit/src/.rmkit.h_cpp/util/rm2fb.h */
/* FILE: rmkit/src/.rmkit.h_cpp/util/signals.h */
/* FILE: rmkit/src/rmkit/ui/icons.h */
/* FILE: rmkit/src/shared/clockwatch.h */
/* FILE: rmkit/src/.rmkit.h_cpp/defines.h */ <-- included here
/* FILE: rmkit/src/rmkit/defines.h */
/* FILE: rmkit/src/.rmkit.h_cpp/input/events.h */
/* FILE: rmkit/src/vendor/stb/stb_image.h */
/* FILE: rmkit/src/vendor/stb/stb_image_resize.h */
/* FILE: rmkit/src/vendor/stb/stb_image_write.h */
/* FILE: rmkit/src/vendor/stb/stb_truetype.h */
/* FILE: rmkit/src/.rmkit.h_cpp/fb/stb_text.h */
/* FILE: rmkit/src/.rmkit.h_cpp/input/gestures.h */
/* FILE: rmkit/src/.rmkit.h_cpp/util/image.h */
/* FILE: rmkit/src/.rmkit.h_cpp/input/input.h */
/* FILE: rmkit/src/.rmkit.h_cpp/fb/fb.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/task_queue.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/widget.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/range_input.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/scene.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/text.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/layouts.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/main_loop.h */
/* FILE: rmkit/src/.rmkit.h_cpp/init.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/pixmap.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/button.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/thumbnail.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/dialog.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/dropdown.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/keyboard.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/pager.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/text_input.h */
/* FILE: rmkit/src/.rmkit.h_cpp/ui/ui.h */
/* FILE: rmkit/src/.rmkit.h_cpp/rmkit.cpp */
here's the build detail:
➜ rmkit git:(include-font-vendor) ✗ ARCH=dev make harmony
mkdir src/build > /dev/null || true
cd src/rmkit && make
make[1]: Entering directory '/home/myf/wwrmsd/modules/rmkit/src/rmkit'
# $ARCH is dev
make compile_dev
make[2]: Entering directory '/home/myf/wwrmsd/modules/rmkit/src/rmkit'
okp -sh -ni -for -d ../.rmkit.h_cpp/ -o ../build/rmkit.h rmkit.cpy -- -D"DEV=1" -pthread -lpthread -DRMKIT_BUILD=1 -O0 -g -D"DEV_KBD=\"`ls /dev/input/by-path/*kbd | head -n1`\""
compile flags: -DDEV=1 -pthread -lpthread -DRMKIT_BUILD=1 -O0 -g -DDEV_KBD="/dev/input/by-path/platform-i8042-serio-0-event-kbd"
g++ -c /home/myf/wwrmsd/modules/rmkit/src/.rmkit.h_cpp/rmkit.cpp -o /home/myf/wwrmsd/modules/rmkit/src/.rmkit.h_cpp/rmkit.o -DDEV=1 -pthread -lpthread -DRMKIT_BUILD=1 -O0 -g -DDEV_KBD="/dev/input/by-path/platform-i8042-serio-0-event-kbd"
In file included from /home/myf/wwrmsd/modules/rmkit/src/rmkit/fb/fb.cpy:15,
from /home/myf/wwrmsd/modules/rmkit/src/rmkit/rmkit.cpy:1:
/home/myf/wwrmsd/modules/rmkit/src/rmkit/input/input.cpy:11:10: fatal error: device_id.h: No such file or directory
11 | #include "device_id.h"
| ^~~~~~~~~~~~~
compilation terminated.
Couldn't compile /home/myf/wwrmsd/modules/rmkit/src/.rmkit.h_cpp/rmkit.cpp aborting
compiled into /home/myf/wwrmsd/modules/rmkit/src/.rmkit.h_cpp
make[2]: *** [../actions.make:35: compile_dev] Error 1
make[2]: Leaving directory '/home/myf/wwrmsd/modules/rmkit/src/rmkit'
make[1]: *** [../actions.make:8: compile] Error 2
make[1]: Leaving directory '/home/myf/wwrmsd/modules/rmkit/src/rmkit'
make: *** [Makefile:61: rmkit.h] Error 2
device_id.cpy is htere but it cannot find device_id.h
I'm using ddvk's Remarkable-hacks, where you can toggle between the two most recent documents with a two-finger downward swipe. This is great for reading pdf's while also taking notes in another document.
If something similar is possible with remux, I could read on Plato or KOReader - which are much better than xochitl for EPUB files - while still taking notes the normal way.
as per issue in oxide from eeems and siraben, the suspend screen has bad quality. this is likely due to using rgb888 as though it is rgb565.
add rectangle, circle, etc
Thanks for a great project! I'm hoping you can help me understand the color drawing apis a little better (apologies for the wall of text):
I'm trying to write an app that will to draw in grayscale, ideally as many shades as possible. From what I can tell, most of the standard Framebuffer methods only support drawing using the predefined WHITE, BLACK, GRAY, RUBBER, and ERASER colors (e.g. draw_rect()), although looking at the implementation, even GRAY is done by dithering, and individual pixels are only set to WHITE or BLACK.
I've had some success converting arbitrary colors using to_rgb565() and I can see the colors are set correctly by examining fbmem
, but I've had trouble getting anything to draw on the screen itself unless I use WHITE, BLACK, or GRAY. It seems like it might be an issue with refreshing? I've noticed that I'll see a flash of the image I've drawn, followed by a white screen . . . I can sometimes get the image to show up afterwards but it's inconsistent enough that I'm not sure what causes the image actually end up getting rendered on the screen.
I think I've managed to track it down to the waveform_mode
. I can draw in grayscale and have it rendered to the screen if I set waveform_mode = WAVEFORM_MODE_GC16
(which I got from looking at both remux and Framebuffer::load_from_png()). I don't exactly understand what the different waveform modes do, but I assume setting GC16 all the time isn't ideal (it's slower?), since Framebuffer resets waveform_mode after each draw.
Is there a practical way to draw in grayscale all the time? Any tips? Thanks!
The idea is to let people write apps without having to compile anything - instead they call into a binary that can draw on screen
and return user input to the app
Hi there,
FYI i noticed some weirdness on my remarkable2 with suspending after installing reumx;
It seems my remarkable2 will sometimes go to suspend much faster (like 3 minutes) than before i installed remux (~ 15 minutes.)
Most of the time the suspend image is really bad quality. Like for example it is only 300 pixels or something instead of 4000. But this does not always seem to be the case, sometimes it is the normal/proper image quality.
When suspend happens after 4 minutes (and i then see the bad resolution suspend image), and i click the button to wake up the rm2 again, it wakes up but only for about 10 seconds, then it will immediately go back to the suspend image again. This repeats, until i do some activity like writing or something.
reMarkable: ~/ opkg list_installed | grep -i remux
remux - 0.1.5-1
PS. When using the button to suspend my rm2, the suspend image quality is always good.
Hi,
Thanks for creating this framework! I am interested in porting this animation onto my remarkable as well as adding a timer for a meditation app for an animation app. However, how would I create the expanding and contracting animation effect? Looking at the documentation could you potentially chain draw_bitmap with a 3-second delay of pictures of different sizes? Or is there a better way to do it?
I think it would be good to allow simple to run without clearning the entire screen. This would make it so that it could be used for simple scripts that want to display some extra information on the screen temporarily without wiping the screen content. Maybe a flag for framebuffer save/recall?
in fb.cpy, we use pnmtopng in save_lodepng() but we have another function that can save directly to pngs. we should use that
It would be really cool to see which of the apps are currently running/suspended. Maybe along with a simple memory metric to prevent opening to many apps.
As far as I gathered, killing some apps can be quite complicated, I don't find that necessary anyway.
Repro:
/home/root/harmony
folder from the device.I'm trying to get a native framebuffer library going to avoid relying on xochitl, but there are possibly three different panels to support. Can those with a reMarkable 2 run the following in an SSH session, so I can verify that I'm looking in the right place for the panel identifier?
dd if=/dev/mmcblk2boot1 bs=1 count=120 | hexdump
Originally posted by @tadfisher in #34 (comment)
we received bug report from favored user:
It seems to me that remux makes it difficult for the reMarkable to shut down automatically (using the settings in remarkable.conf) and for a reason that I don't understand when remux is enabled (I'm also tried with the latest build from toltec/testing) I need to try several time before the device accepts to boot. Maybe it's related to the way it's shut down, I've not been able to investigate this, but the problem goes away when I disable remux in systemctl.
this task is to bring power management up to snuff
from linus on discord:
seems that sometimes the sleepscreen not flashes repeatedly for like 2-5 times before finally sleeping. noticed it when the sleep screen had actually inverted colors (probably sleept right in a refresh). also had the repeated flashing after waking up.
i wonder if it could be multiple remux running, but that wouldn't make sense.
when paging through apps (when there are more than 8 or so apps), remux seems to dismiss itself. this is unexpected
I recently installed rm2fb, remux and koreader via toltec. This turns the remarkable2 into the perfect device for me: Having koReader's features (especially DAV and wallabag sync) completes the amazing note taking abilities for me.
But then I noticed how fast my battery gets drained. With remux active I lose 5-10% percent of my battery per hour, even if I have the wifi off and don't switch often between koReader and xochitl.
The battery usage is fine when I disable remux, but as soon as I restart it, the battery levels start to drop again. This battery life would make my remarkable less long lasting then a normal tablet, and thats just not an option...
Is this a known problem that I somehow missed? I didn't find any issues regarding power problems in any of the repos I looked at.
If not: Where should I start to troubleshoot? I don't see anything super suspicipus in log.txt or journalctl
I also have the ddvk-hacks installed, by they don't seem to affect the battery life as drastically, when remux is disabled.
opkg update
(update the package repo)opkg upgrade
(upgrade all installed packages)I like remux being rather non-invasive and enabling me to quickly switch between concurrent running apps.
I like oxide for bringing me the desktop
like environment
Why not getting the best of both worlds.
Using oxide as a desktop environment to do settings, starting applications, etc. and use remux as the task-manager to switch between different apps.
Ultimately, if remux could even get to the point of a split view (2 programs side by side) and oxide focuses on the ui experience, we would have a very interesting combination.
This would work on top of the package repository
Hi,
Thanks for your work, I really enjoy remux and the developing ecosystem that you are creating. I need to try your new library to create apps for the rm.
Anyway, I am using ddvk hack on xochitl to support the Lamy pen, to be able to have the eraser function by pushing the pen's button.
Right now, with remux, it's not working because remux start it's own process and stop xochitl via its systemd service : https://github.com/rmkit-dev/rmkit/blob/master/src/remux/launcher.cpy
def run():
_ := system("systemctl stop xochitl")
proc::launch_process("xochitl", true /* check running */, true /* background */)
ddvk's hack start xochitl with a command line argument:
xochitl -plugin evdevlamy
.
Would it be possible to include this feature to remux via a conf file ?
I can write a push request hardcoded for my own usage, but I like the fact that all your software is now available via opkg. Hence, if you have already defined an API for passing argument to apps in remux, I would be happy to use it and contribute to the software.
Regards, Alex.
Maybe I did something wrong, but is it possible that the lamy button hack of @ddvk conflicts the remux button listen service?
brainstormed a bit with linus on discord a week ago. for genie, it is interesting to explore other gestures for launching apps.
some ideas:
being able to launch commands without looking at the screen could make input much faster.
(more images will be attached throughout this thread)
It should be easy for an app to save settings to disk and configure them from the UI. The UI configuration might be accomplished via simple widgets, while saving to disk can be in any form, as long as its robust
[evan@blackbox rmkit] make clean
...
[evan@blackbox rmkit] ARCH=x86 make rmkit.h
mkdir src/build > /dev/null || true
mkdir: cannot create directory ‘src/build’: File exists
cd src/rmkit && make
make[1]: Entering directory '/home/evan/resources/rmkit/src/rmkit'
# $ARCH is x86
make compile_x86
make[2]: Entering directory '/home/evan/resources/rmkit/src/rmkit'
okp -sh -ni -for -d ../.rmkit.h_cpp/ -o ../build/rmkit.h rmkit.cpy -- -pthread -lpthread -DRMKIT_BUILD=1 -O0 -g
compile flags: -pthread -lpthread -DRMKIT_BUILD=1 -O0 -g
g++ -c /home/evan/resources/rmkit/src/.rmkit.h_cpp/rmkit.cpp -o /home/evan/resources/rmkit/src/.rmkit.h_cpp/rmkit.o -pthread -lpthread -DRMKIT_BUILD=1 -O0 -g
generating single header /home/evan/resources/rmkit/src/rmkit/../build/rmkit.h
compiled into /home/evan/resources/rmkit/src/.rmkit.h_cpp
make[2]: Leaving directory '/home/evan/resources/rmkit/src/rmkit'
make[1]: Leaving directory '/home/evan/resources/rmkit/src/rmkit'
[evan@blackbox rmkit] ARCH=x86 make demo
mkdir src/build > /dev/null || true
mkdir: cannot create directory ‘src/build’: File exists
cd src/rmkit && make
make[1]: Entering directory '/home/evan/resources/rmkit/src/rmkit'
# $ARCH is x86
make compile_x86
make[2]: Entering directory '/home/evan/resources/rmkit/src/rmkit'
okp -sh -ni -for -d ../.rmkit.h_cpp/ -o ../build/rmkit.h rmkit.cpy -- -pthread -lpthread -DRMKIT_BUILD=1 -O0 -g
compile flags: -pthread -lpthread -DRMKIT_BUILD=1 -O0 -g
g++ -c /home/evan/resources/rmkit/src/.rmkit.h_cpp/rmkit.cpp -o /home/evan/resources/rmkit/src/.rmkit.h_cpp/rmkit.o -pthread -lpthread -DRMKIT_BUILD=1 -O0 -g
generating single header /home/evan/resources/rmkit/src/rmkit/../build/rmkit.h
compiled into /home/evan/resources/rmkit/src/.rmkit.h_cpp
make[2]: Leaving directory '/home/evan/resources/rmkit/src/rmkit'
make[1]: Leaving directory '/home/evan/resources/rmkit/src/rmkit'
cd src/demo && make
make[1]: Entering directory '/home/evan/resources/rmkit/src/demo'
# $ARCH is x86
make compile_x86
make[2]: Entering directory '/home/evan/resources/rmkit/src/demo'
okp -ni -for -d ../.demo_cpp/ -o ../build/demo.exe main.cpy -- -pthread -lpthread -O0 -g
compile flags: -pthread -lpthread -O0 -g
missing file: stb_image.h
missing file: stb_image_resize.h
g++ -c /home/evan/resources/rmkit/src/.demo_cpp/main.cpp -o /home/evan/resources/rmkit/src/.demo_cpp/main.o -pthread -lpthread -O0 -g
g++ /home/evan/resources/rmkit/src/.demo_cpp/main.o -o /home/evan/resources/rmkit/src/demo/../build/demo.exe -pthread -lpthread -O0 -g
compiled into /home/evan/resources/rmkit/src/.demo_cpp
make[2]: Leaving directory '/home/evan/resources/rmkit/src/demo'
make[1]: Leaving directory '/home/evan/resources/rmkit/src/demo'
When I execute ./src/build/demo.exe
in a tty, the program exits with
W: 1600 H: 1024
XRES 1280 YRES 900 BPP 32 GRAYSCALE 0
CLEANING UP FB
received SIGABRT, exiting
Also in BUILDING.md, it suggests to run ./build/bin/harmony
, but this path doesn't seem to exist anymore.
I just got my rM2 and tried installing. Installation went fine, but I cannot seem to bring up the launcher.
For one, there's no home button.
(sorry for background 3d printer noise)
Sometimes, when my hand and pen touch at the same time (which is common when writing), part of the screen will refresh, and sometimes will launch an app from Remux without the menu having time to show.
It looks like Remux is listening to the input events and somehow my marker and hand equal a home button hold?
I had weird issues with Oxide as well, where after enabling Zen Mode in remarkable-hacks
by pressing L and R simultaneously, pressing any of the physical buttons would act as if I was holding it down, regardless of how long I actually touched it.
The goal is to have an app launcher that supports having multiple running apps at once
This isn't fully thought out yet, just looking to start a discussion.
I'm finding that most of the widgets I've tried work well, but I often want to make small tweaks (e.g. OutlineButton, which draws a 1px border and vertically centers the text). In the case of buttons, I think those are actually good defaults, and I'd be happy if all buttons were centered and had a border. But I could also see wanting to vertically center any kind of text-based widget, and I could see wanting to put a border around any kind of widget (even if just for debugging purposes).
So that got me thinking about the more general idea of styles. Widgets already support a fair amount of customization, like ui::Text
supports font_size
and underline
, but not all text-based widgets support those, e.g. ui::Button
doesn't support font_size
, and ui::DropdownButton
doesn't support either one. There are really two problems I'm trying to solve with this idea:
style
variable, or a set_style
function, it would make that part easier.style
a single bitmask or a struct with a few fields would make it easy to passing around, and it would also open the door to setting style in the constructor.Prior art
I see Qt has css-like stylesheets, which seems pretty cool, but also way overboard for rmkit, at least currently. I've used wxWidgets a good bit in the past, which has a simpler concept of styles: each wxWindow-derived class has a font, a border, a background, and a style bitmask (border style, background style, scrollbar style, etc). Some subclasses add more bits to the mask, like wxStaticText and wxButton have alignment bitmasks, and wxTextCtrl has all kinds of style flags, like readonly, password, multiline, wrapping.
it should be possible to build a UI through a gui builder and that would generate the simple markup
this could make it even simpler to write apps
(thanks @torwag)
I wrote ui::Stylesheet so that all its functions mutate the stylesheet and return a reference to *this
for efficiency when chaining, but I realize now that might be more complicated than its worth. For instance this diff doesn't just apply the stylesheet to a single button, it actually changes the global Button::DEFAULT_STYLE.
The pattern of taking an existing Stylesheet and applying a new one on top of it makes a lot of sense to me, so I wonder if it might be better to go ahead and have all the builders return a copy.
Currently a button is just text, which means that it's not clear to the end user that it can be interacted with. Here are some options:
I tried rmkit and it seems to be working but the display is highly teared everywhere (I cannot read, but almost, the text in the menu, the animation demo is also teared etc).
I'm not sure if this is a know or frequent issue. I don't if it shares some low level API use, but I tried running https://github.com/LinusCDE/retris and this is not teared.
harmony version: 0.0.1-16
When launching harmony, the screen goes blank
opkg install harmony
journalctl output
Dec 08 23:20:35 reMarkable remux[369]: PROC 378 /usr/bin/xochitl
Dec 08 23:20:35 reMarkable remux[369]: --system
Dec 08 23:20:35 reMarkable remux[369]: 378
Dec 08 23:20:35 reMarkable remux[369]: CURRENT APP IS Remarkable
Dec 08 23:20:35 reMarkable remux[369]: current app 0.0176978
Dec 08 23:20:35 reMarkable remux[369]: PROC 378 /usr/bin/xochitl
Dec 08 23:20:35 reMarkable remux[369]: --system
Dec 08 23:20:35 reMarkable remux[369]: 378
Dec 08 23:20:35 reMarkable remux[369]: SENDING 19 TO GROUP -378 RET 0
Dec 08 23:20:35 reMarkable remux[369]: term apps 0.0197499
Dec 08 23:20:35 reMarkable remux[369]: W: 1408 H: 1920
Dec 08 23:20:35 reMarkable remux[369]: SNAPSHOTTING Remarkable
Dec 08 23:20:35 reMarkable remux[369]: No such file or directory
Dec 08 23:20:35 reMarkable remux[369]: RENDERING Remarkable
Dec 08 23:20:48 reMarkable remux[369]: W: 1408 H: 1920
Dec 08 23:20:49 reMarkable remux[369]: RENDERING harmony
Dec 08 23:20:49 reMarkable remux[369]: LAUNCHING APP harmony
Dec 08 23:20:49 reMarkable remux[369]: CHECKING PROCESS harmony
Dec 08 23:20:49 reMarkable remux[369]: RENDERING harmony
Dec 08 23:20:49 reMarkable remux[369]: W: 1408 H: 1920
Dec 08 23:20:49 reMarkable remux[369]: XRES 1404 YRES 1872 BPP 16 GRAYSCALE 0
Dec 08 23:20:49 reMarkable remux[369]: W: 1408 H: 1920
Dec 08 23:20:49 reMarkable remux[369]: CLEANING UP FB
Dec 08 23:20:49 reMarkable remux[369]: received SIGABRT, exiting
When installing applications through nao, it doesn't have permissions to reload oxide applications, which means that when a package attempts to call rot apps call reload
it will fail. This can be fixed by adding an oxide application registration for nao that has apps
permissions. https://github.com/Eeems/oxide/wiki/Developing-Applications-for-Oxide#oxide-application-registration-specification
some useful commands might be:
with these commands, xdg-open
style functionality could be implemented (assuming we have an image viewer application and a text viewer application and so on), s.t. an app can be launched from command line and still gets managed by the launcher. somewhere down the line, a file manager could be added which uses xdg-open under the hood.
battery, wifi, ???
Sometimes when I make a stroke with the pen when reMux is installed, a large diagonal region of the screen goes blank and the tablet (remarkable 1) goes unresponsive for a few seconds. I haven't been able to determine the exact circumstances that cause this. There also seems to be a related issue where after this happens, the pen will write when above (not touching) the screen.
My setup: rmkit master (a8ded6b); rm2 with rm2fb in toltec-testing
I noticed a widget was getting a lot of mouse_down events. It seemed like I got a down when I started a touch, but also every time I dragged (without lifting my finger off the screen). Further investigation revealed that the widget was getting a sequence of events like so: down,leave,down,leave,down ...
The attached events.log has a full log of one session with #define DEBUG_INPUT_EVENT 1
. I'm no expert in decoding these events, but based on the log it looks like what's happening is that the initial touch (down) event starts with ABS_MT_TRACKING_ID
, then gets full position, pressure, etc. info, but subsequent motion events are produced as deltas (i.e. position or pressure change), not as full events. So those motion events are being processed with uninitialized values. In the case of a motion event that doesn't include both X and Y coords, one of those values is way off screen, leading to the extra leave
event.
Hi again -- I'm working on a C++ project using rmkit that's big enough I'd like to split it into multiple source files. The example repo was very helpful as a template, but once I split the source into multiple cpp files I started running into linker issues. It seems like there are some top-level functions in rmkit.h that are neither inline nor static, so they end up with multiple definitions.
Is there a straightforward way to build rmkit as a separate library that I could link into a binary? And/or some combination of flags I could pass to okp that would give me a header that's just declarations (and inline functions) without the implementation?
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.