diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 32 | ||||
| -rw-r--r-- | src/gui.cpp | 10 | ||||
| -rw-r--r-- | src/headless.cpp | 20 | ||||
| -rw-r--r-- | src/main_gui.cpp | 13 | ||||
| -rw-r--r-- | src/util.cpp | 12 |
5 files changed, 78 insertions, 9 deletions
diff --git a/src/Makefile b/src/Makefile index c0b6e1d..9846d8e 100644 --- a/src/Makefile +++ b/src/Makefile | |||
| @@ -71,5 +71,35 @@ bitflash: $(IMGUI_OBJS) $(NODE_OBJS) $(GUI_OBJS) | |||
| 71 | $(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS) | 71 | $(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS) |
| 72 | @echo "Built: bitflash" | 72 | @echo "Built: bitflash" |
| 73 | 73 | ||
| 74 | # ---- headless node --------------------------------------------------------- | ||
| 75 | # | ||
| 76 | # Same node, built without ImGui, GLFW or OpenGL. Linking the GUI made the | ||
| 77 | # binary require libGL at load time even when started with -nogui, because the | ||
| 78 | # dynamic loader resolves everything before main() runs -- so on a clean server, | ||
| 79 | # which is where a node most naturally lives, it failed to start with an error | ||
| 80 | # about shared libraries and no hint that it would otherwise work. | ||
| 81 | # | ||
| 82 | # Objects go to obj-node/ because main_gui.cpp is compiled twice, with and | ||
| 83 | # without -DBITFLASH_NO_GUI, and the two must not overwrite each other. | ||
| 84 | |||
| 85 | NODE_LIBS = -L$(SECP_LIB) -lsecp256k1 \ | ||
| 86 | -L$(RANDOMX_DIR)/build -lrandomx \ | ||
| 87 | -lsodium -lssl -lcrypto -ldb_cxx -lpthread | ||
| 88 | |||
| 89 | NODE_ONLY_OBJS = $(patsubst obj/%,obj-node/%,$(NODE_OBJS)) \ | ||
| 90 | obj-node/main_gui.o obj-node/headless.o | ||
| 91 | |||
| 92 | obj-node/%.o: %.cpp $(HEADERS) | ||
| 93 | @mkdir -p obj-node | ||
| 94 | $(CXX) -c $(CXXFLAGS) -DBITFLASH_NO_GUI -o $@ $< | ||
| 95 | |||
| 96 | obj-node/sha.o: sha.cpp sha.h | ||
| 97 | @mkdir -p obj-node | ||
| 98 | $(CXX) -c $(CXXFLAGS) -DBITFLASH_NO_GUI -O3 -o $@ $< | ||
| 99 | |||
| 100 | bitflash-node: $(NODE_ONLY_OBJS) | ||
| 101 | $(CXX) $(CXXFLAGS) -o $@ $^ $(NODE_LIBS) | ||
| 102 | @echo "Built: bitflash-node (headless, no libGL needed)" | ||
| 103 | |||
| 74 | clean: | 104 | clean: |
| 75 | rm -rf obj bitflash | 105 | rm -rf obj obj-node bitflash bitflash-node |
diff --git a/src/gui.cpp b/src/gui.cpp index a1a0698..fc6f1e1 100644 --- a/src/gui.cpp +++ b/src/gui.cpp | |||
| @@ -171,14 +171,8 @@ static void RefreshWallet() | |||
| 171 | 171 | ||
| 172 | void MainFrameRepaint() { g_needRefresh = true; } | 172 | void MainFrameRepaint() { g_needRefresh = true; } |
| 173 | 173 | ||
| 174 | string DateTimeStr(int64 nTime) | 174 | // DateTimeStr moved to util.cpp: main.cpp logs block times with it, so it is |
| 175 | { | 175 | // needed by builds that have no GUI at all. |
| 176 | time_t t = (time_t)nTime; | ||
| 177 | struct tm* p = localtime(&t); | ||
| 178 | if (!p) return ""; | ||
| 179 | char buf[32]; strftime(buf, sizeof(buf), "%m/%d/%y %H:%M", p); | ||
| 180 | return buf; | ||
| 181 | } | ||
| 182 | 176 | ||
| 183 | // --------------------------------------------------------------------------- | 177 | // --------------------------------------------------------------------------- |
| 184 | // Status bar -- separate fullscreen-width overlay pinned to bottom edge. | 178 | // Status bar -- separate fullscreen-width overlay pinned to bottom edge. |
diff --git a/src/headless.cpp b/src/headless.cpp new file mode 100644 index 0000000..3372936 --- /dev/null +++ b/src/headless.cpp | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Stand-ins for the handful of symbols the node core expects the GUI to | ||
| 5 | // provide, so a headless binary can be linked without ImGui, GLFW or OpenGL. | ||
| 6 | // | ||
| 7 | // This exists because linking the GUI made the node need libGL at load time | ||
| 8 | // even when started with -nogui: the dynamic loader resolves everything before | ||
| 9 | // main() runs, so the flag came far too late. On a clean server -- which is | ||
| 10 | // where a node most naturally lives -- that is a hard failure with an error | ||
| 11 | // message about shared libraries and no hint that the program would otherwise | ||
| 12 | // have worked fine. | ||
| 13 | |||
| 14 | #include "headers_core.h" | ||
| 15 | |||
| 16 | // The GUI uses this to mark itself dirty. With no window to repaint there is | ||
| 17 | // nothing to do, and the call sites in main.cpp and net.cpp stay unchanged. | ||
| 18 | void MainFrameRepaint() | ||
| 19 | { | ||
| 20 | } | ||
diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 9f7e34e..99e63d4 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp | |||
| @@ -5,7 +5,11 @@ | |||
| 5 | #include <csignal> | 5 | #include <csignal> |
| 6 | #endif | 6 | #endif |
| 7 | 7 | ||
| 8 | // BITFLASH_NO_GUI builds the same entry point without ImGui, GLFW or OpenGL, | ||
| 9 | // so the binary does not need libGL present just to start. See headless.cpp. | ||
| 10 | #ifndef BITFLASH_NO_GUI | ||
| 8 | int RunGUI(int argc, char* argv[]); | 11 | int RunGUI(int argc, char* argv[]); |
| 12 | #endif | ||
| 9 | 13 | ||
| 10 | // Global definitions (were in ui.cpp, now here) | 14 | // Global definitions (were in ui.cpp, now here) |
| 11 | map<string,string> mapAddressBook; | 15 | map<string,string> mapAddressBook; |
| @@ -186,8 +190,13 @@ int main(int argc, char* argv[]) | |||
| 186 | if (_beginthread(ThreadBitcoinMiner, 0, NULL) == (uintptr_t)-1) | 190 | if (_beginthread(ThreadBitcoinMiner, 0, NULL) == (uintptr_t)-1) |
| 187 | printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); | 191 | printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); |
| 188 | 192 | ||
| 193 | #ifdef BITFLASH_NO_GUI | ||
| 194 | // Nothing else this binary can do; /nogui is accepted and redundant. | ||
| 195 | bool fHeadless = true; | ||
| 196 | #else | ||
| 189 | bool fHeadless = arg(argc,argv,"/nogui") || arg(argc,argv,"-nogui") || | 197 | bool fHeadless = arg(argc,argv,"/nogui") || arg(argc,argv,"-nogui") || |
| 190 | arg(argc,argv,"/daemon") || arg(argc,argv,"-daemon"); | 198 | arg(argc,argv,"/daemon") || arg(argc,argv,"-daemon"); |
| 199 | #endif | ||
| 191 | 200 | ||
| 192 | if (fHeadless) { | 201 | if (fHeadless) { |
| 193 | #ifndef _WIN32 | 202 | #ifndef _WIN32 |
| @@ -200,8 +209,12 @@ int main(int argc, char* argv[]) | |||
| 200 | return 0; | 209 | return 0; |
| 201 | } | 210 | } |
| 202 | 211 | ||
| 212 | #ifdef BITFLASH_NO_GUI | ||
| 213 | return 0; // unreachable: fHeadless is always true in this build | ||
| 214 | #else | ||
| 203 | int ret = RunGUI(argc, argv); | 215 | int ret = RunGUI(argc, argv); |
| 204 | fShutdown = true; | 216 | fShutdown = true; |
| 205 | StopNode(); | 217 | StopNode(); |
| 206 | return ret; | 218 | return ret; |
| 219 | #endif | ||
| 207 | } | 220 | } |
diff --git a/src/util.cpp b/src/util.cpp index 68bd18e..e4e314f 100644 --- a/src/util.cpp +++ b/src/util.cpp | |||
| @@ -490,3 +490,15 @@ void AddTimeData(unsigned int ip, int64 nTime) | |||
| 490 | printf("| nTimeOffset = %+lld (%+lld minutes)\n", nTimeOffset, nTimeOffset/60); | 490 | printf("| nTimeOffset = %+lld (%+lld minutes)\n", nTimeOffset, nTimeOffset/60); |
| 491 | } | 491 | } |
| 492 | } | 492 | } |
| 493 | |||
| 494 | // Formats a block or transaction timestamp for logs and for the wallet view. | ||
| 495 | // It lived in gui.cpp, but main.cpp logs block times with it, so a headless | ||
| 496 | // build needed it too -- and nothing about formatting a date is GUI work. | ||
| 497 | string DateTimeStr(int64 nTime) | ||
| 498 | { | ||
| 499 | time_t t = (time_t)nTime; | ||
| 500 | struct tm* p = localtime(&t); | ||
| 501 | if (!p) return ""; | ||
| 502 | char buf[32]; strftime(buf, sizeof(buf), "%m/%d/%y %H:%M", p); | ||
| 503 | return buf; | ||
| 504 | } | ||