upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile32
-rw-r--r--src/gui.cpp10
-rw-r--r--src/headless.cpp20
-rw-r--r--src/main_gui.cpp13
-rw-r--r--src/util.cpp12
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
85NODE_LIBS = -L$(SECP_LIB) -lsecp256k1 \
86 -L$(RANDOMX_DIR)/build -lrandomx \
87 -lsodium -lssl -lcrypto -ldb_cxx -lpthread
88
89NODE_ONLY_OBJS = $(patsubst obj/%,obj-node/%,$(NODE_OBJS)) \
90 obj-node/main_gui.o obj-node/headless.o
91
92obj-node/%.o: %.cpp $(HEADERS)
93 @mkdir -p obj-node
94 $(CXX) -c $(CXXFLAGS) -DBITFLASH_NO_GUI -o $@ $<
95
96obj-node/sha.o: sha.cpp sha.h
97 @mkdir -p obj-node
98 $(CXX) -c $(CXXFLAGS) -DBITFLASH_NO_GUI -O3 -o $@ $<
99
100bitflash-node: $(NODE_ONLY_OBJS)
101 $(CXX) $(CXXFLAGS) -o $@ $^ $(NODE_LIBS)
102 @echo "Built: bitflash-node (headless, no libGL needed)"
103
74clean: 104clean:
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
172void MainFrameRepaint() { g_needRefresh = true; } 172void MainFrameRepaint() { g_needRefresh = true; }
173 173
174string 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.
18void 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
8int RunGUI(int argc, char* argv[]); 11int 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)
11map<string,string> mapAddressBook; 15map<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.
497string 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}