jetc: rename --shared build output convention from .so to .jtc
Purely a naming-convention change per user request, not a format
change - the output is still a real ELF shared object (-shared -fPIC),
still dlopen()-able exactly as before. .jtc ("jet compiled") marks it as
an APIServer-loadable content module rather than a generic library.
build-shared.sh: usage text and STEM derivation
(basename "$OUTPUT" .so -> .jtc) both updated - the STEM change is the
one functional piece here, everything else in this commit is comments/
usage strings. Doc comments in jetc.cpp/JetCodegen.h/host_test.cpp/
api_test.cpp updated to match.
Verified live: rebuilt jetc and all five demo*.jtc modules, reran
api_test/host_test against demo3.jtc (still resolves jetc_api_demo3/
jetc_render_demo3 and renders correctly) - the extension is purely
cosmetic to dlopen(), as expected.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3f273b0a95
commit
9bbb95cc57
6 files changed
+28
-22
No files matched your search
+3
-3
@@ -10,7 +10,7 @@ namespace jetc {
|
||||
|
||||
// One `#api METHOD /path` directive from the top of the source template
|
||||
// (see jetc.cpp) - a compile-time-known route this template wants to
|
||||
// serve once loaded as a .so. Purely descriptive data handed to Codegen;
|
||||
// serve once loaded as a .jtc. Purely descriptive data handed to Codegen;
|
||||
// jetc itself never interprets the method/path beyond storing them.
|
||||
struct ApiRoute {
|
||||
std::string method;
|
||||
@@ -34,7 +34,7 @@ namespace jetc {
|
||||
//
|
||||
// sharedMode == true: emits no main() at all. Instead the render
|
||||
// logic is exported as `extern "C" void <entrySymbol>(jet::Global
|
||||
// &global, coreutils::MString &out)`, meant to be built into a .so
|
||||
// &global, coreutils::MString &out)`, meant to be built into a .jtc
|
||||
// (see build-shared.sh) and dlsym()'d by a long-running host server -
|
||||
// one call renders one request into the caller-owned `out`, using
|
||||
// whatever Global the host passes in (its lifecycle, cgi/session
|
||||
@@ -45,7 +45,7 @@ namespace jetc {
|
||||
// letting coreutils::Exception propagate to the caller) across the
|
||||
// dlopen() boundary is safe; this is a same-ABI plugin boundary, not
|
||||
// a foreign C ABI one. entrySymbol should be unique per compiled
|
||||
// template (see jetc.cpp) so multiple .so's can coexist even if a
|
||||
// template (see jetc.cpp) so multiple .jtc's can coexist even if a
|
||||
// host ever dlopen()s them RTLD_GLOBAL instead of keeping separate
|
||||
// handles.
|
||||
//
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
// Minimal dlsym() check for the jetc_api_<name> route-metadata export added
|
||||
// alongside jetc_render_<name> in --shared mode (see JetCodegen.cpp). Proves
|
||||
// a host can discover a compiled module's declared routes purely from the
|
||||
// .so itself, with no separate manifest file - the actual point of putting
|
||||
// .jtc itself, with no separate manifest file - the actual point of putting
|
||||
// routing metadata in an exported symbol instead of a sidecar file.
|
||||
#include <dlfcn.h>
|
||||
#include <iostream>
|
||||
@@ -12,7 +12,7 @@ typedef const JetApiRoute *(*ApiFn)(int *count);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 3) {
|
||||
std::cerr << "usage: api_test <module.so> <api-symbol>" << std::endl;
|
||||
std::cerr << "usage: api_test <module.jtc> <api-symbol>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
void *handle = dlopen(argv[1], RTLD_NOW);
|
||||
|
||||
+10
-8
@@ -1,12 +1,14 @@
|
||||
#!/bin/bash
|
||||
# Compiles a .jet file into a shared object exporting a stable, dlsym()-able
|
||||
# render entry point - `jetc_render_<basename>(jet::Global &global,
|
||||
# coreutils::MString &out)` - for a long-running server to load and call
|
||||
# directly instead of spawning a jet-2.0 process per request.
|
||||
# Compiles a .jet file into a shared object (conventionally named .jtc -
|
||||
# "jet compiled" - to mark it as an APIServer-loadable content module, not
|
||||
# a generic .so) exporting a stable, dlsym()-able render entry point -
|
||||
# `jetc_render_<basename>(jet::Global &global, coreutils::MString &out)`
|
||||
# - for a long-running server to load and call directly instead of
|
||||
# spawning a jet-2.0 process per request.
|
||||
#
|
||||
# Usage: ./build-shared.sh <input.jet> <output.so>
|
||||
# Usage: ./build-shared.sh <input.jet> <output.jtc>
|
||||
#
|
||||
# The host server links/dlopen()s the .so and calls the exported symbol
|
||||
# The host server links/dlopen()s the .jtc and calls the exported symbol
|
||||
# (see the "entry symbol:" line jetc prints) with its own jet::Global -
|
||||
# this script does not decide that lifecycle, only builds the module.
|
||||
# coreutils::Exception propagates out of the call uncaught; the host
|
||||
@@ -18,13 +20,13 @@ CU="$JC/../CoreUtils"
|
||||
HERE="$JC/jetc"
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "usage: $0 <input.jet> <output.so>"
|
||||
echo "usage: $0 <input.jet> <output.jtc>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INPUT="$1"
|
||||
OUTPUT="$2"
|
||||
STEM="$(basename "$OUTPUT" .so)"
|
||||
STEM="$(basename "$OUTPUT" .jtc)"
|
||||
|
||||
if [ ! -x "$HERE/jetc" ]; then
|
||||
echo "Building jetc..."
|
||||
|
||||
Executable → Regular
+4
-4
@@ -1,5 +1,5 @@
|
||||
// Minimal stand-in for the not-yet-built server: dlopen()s a compiled
|
||||
// template .so and calls its exported render entry point directly, the
|
||||
// Minimal stand-in for a server: dlopen()s a compiled
|
||||
// template .jtc and calls its exported render entry point directly, the
|
||||
// way a persistent content-provider process would (no process spawn per
|
||||
// request, no re-parsing the .jet source - both the compile step AND
|
||||
// the shared-object load happen once, ahead of time).
|
||||
@@ -14,7 +14,7 @@ typedef void (*RenderFn)(jet::Global &, coreutils::MString &);
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
if (argc < 3) {
|
||||
std::cerr << "usage: host_test <module.so> <symbol>" << std::endl;
|
||||
std::cerr << "usage: host_test <module.jtc> <symbol>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
void *handle = dlopen(argv[1], RTLD_NOW);
|
||||
@@ -31,7 +31,7 @@ int main(int argc, char **argv, char **envp) {
|
||||
}
|
||||
|
||||
// Simulate the host calling the SAME module twice, for two different
|
||||
// "requests", to prove the .so is reusable across calls without being
|
||||
// "requests", to prove the .jtc is reusable across calls without being
|
||||
// reloaded - the actual point of a persistent content provider.
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
jet::Global global(envp);
|
||||
|
||||
+3
-3
@@ -63,7 +63,7 @@ int main(int argc, char **argv) {
|
||||
// is stripped - a plain directive line, not a new tag/attribute concept,
|
||||
// since jetc's parser has no existing notion of the enclosing <jet> tag's
|
||||
// attributes to hang this off of. Each becomes one route this template
|
||||
// wants to serve once loaded as a .so (see JetCodegen's apiRoutes).
|
||||
// wants to serve once loaded as a .jtc (see JetCodegen's apiRoutes).
|
||||
std::vector<jetc::ApiRoute> apiRoutes;
|
||||
while (src.rfind("#api ", 0) == 0) {
|
||||
size_t nl = src.find('\n');
|
||||
@@ -88,8 +88,8 @@ int main(int argc, char **argv) {
|
||||
jetc::Codegen codegen;
|
||||
// Both symbols are derived from the input filename (not the output
|
||||
// path) so they stay stable and predictable for whatever builds and
|
||||
// dlsym()'s the resulting .so - unique per template, so multiple
|
||||
// compiled templates' .so's can coexist in one process even under
|
||||
// dlsym()'s the resulting .jtc - unique per template, so multiple
|
||||
// compiled templates' .jtc's can coexist in one process even under
|
||||
// dlopen(..., RTLD_GLOBAL) instead of requiring isolated handles.
|
||||
std::string baseIdent = sanitizeIdent(baseNameNoExt(inputPath));
|
||||
std::string symbol = "jetc_render_" + baseIdent;
|
||||
|
||||
Reference in new issue
Block a user