Success building JavaScript library from scratch on Linux

For discussion of ports to POSIX based systems, especially using GNUStep.

Moderators: winston, another_commander, Getafix

Post Reply
User avatar
mcarans
---- E L I T E ----
---- E L I T E ----
Posts: 656
Joined: Sun Jun 20, 2010 6:00 pm

Success building JavaScript library from scratch on Linux

Post by mcarans »

I managed to build the JavaScript library on Linux and use it with Oolite successfully. The greatest challenge is that Python 2 is obsolete. Python 2 must be built from source on Kubuntu 25.10. To build Python 2.7:

Code: Select all

wget https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz
tar -xvf Python-2.7.18.tgz
cd Python-2.7.18
export CFLAGS="-std=c17"
./configure --prefix=/usr/local --enable-optimizations
make -j16
I wanted to see the minimal set of changes to the original package to get it to work with Oolite. That package is here: https://ftp.mozilla.org/pub/firefox/rel ... ce.tar.bz2. I unzipped only the js/src folder into a folder mozilla-2.0. mozilla-2.0 is in the same folder as my oolite directory.

I edited Oolite's libjs.make to:

Code: Select all

#
# This makefile is used to build the Javascript dependency for Oolite
#
# This Makefile is used to download and build the Javascript library
# for use by Oolite.
# Depending on invocation, a debug or release (default) version of the
# library will be built.
#
# To use:
# $ make -f libjs.make debug=(yes|no)

include config.make

LIBJS_SRC_DIR                    = ../mozilla-2.0/js/src
LIBJS_CONFIG_FLAGS               = --disable-shared-js
LIBJS_CONFIG_FLAGS               += --enable-threadsafe
LIBJS_CONFIG_FLAGS               += --with-system-nspr
LIBJS_CONFIG_FLAGS               += --disable-tests
ifeq ($(OO_JAVASCRIPT_TRACE),yes)
    LIBJS_CONFIG_FLAGS           += --enable-trace-jscalls
endif
LIBJS_CFLAGS                = -std=gnu89
LIBJS_CXXFLAGS              = -Wno-error=narrowing
ifeq ($(debug),yes)
    LIBJS_BUILD_DIR              = $(LIBJS_SRC_DIR)/build-debug
    LIBJS_CONFIG_FLAGS           += --enable-debug
    LIBJS_CONFIG_FLAGS           += --disable-optimize
else
    LIBJS_BUILD_DIR              = $(LIBJS_SRC_DIR)/build-release
endif
LIBJS                            = $(LIBJS_BUILD_DIR)/libjs_static.a
LIBJS_BUILD_STAMP                = $(LIBJS_BUILD_DIR)/build_stamp
LIBJS_CONFIG_STAMP               = $(LIBJS_BUILD_DIR)/config_stamp


.PHONY: all
all: $(LIBJS)

$(LIBJS): $(LIBJS_BUILD_STAMP)

$(LIBJS_BUILD_STAMP): $(LIBJS_CONFIG_STAMP)
	@echo
	@echo "Building Javascript library..."
	@echo
	$(MAKE) -C $(LIBJS_BUILD_DIR)
	touch $@

$(LIBJS_CONFIG_STAMP):
	@echo
	@echo "Configuring Javascript library..."
	@echo
	mkdir -p $(LIBJS_BUILD_DIR)
	cd $(LIBJS_BUILD_DIR) && CC="gcc $(LIBJS_CFLAGS)" CFLAGS="$(LIBJS_CFLAGS)" CXXFLAGS="$(LIBJS_CXXFLAGS)" ../configure $(LIBJS_CONFIG_FLAGS)
	touch $@

.PHONY: clean
clean:
	-$(MAKE) -C $(LIBJS_BUILD_DIR) clean
	-$(RM) $(LIBJS_BUILD_STAMP)

# This target also removes the configuration status, forcing
# a reconfiguration. Use this after changing LIBJS_CONFIG_FLAGS
.PHONY: distclean
distclean:
	-$(RM) -r $(LIBJS_BUILD_DIR)
The only changes needed to the mozilla code was to change some false and JS_FALSE values to NULL. This is a slightly smaller set of changes than is currently in https://github.com/OoliteProject/spidermonkey-ff4

Code: Select all

diff -ruN src_old/jsapi.cpp src/jsapi.cpp
--- src_old/jsapi.cpp	2011-03-19 12:33:50.000000000 +1300
+++ src/jsapi.cpp	2025-11-28 17:51:34.029783960 +1300
@@ -3977,7 +3977,7 @@
     AutoIdVector props(cx);
     JSIdArray *ida;
     if (!GetPropertyNames(cx, obj, JSITER_OWNONLY, &props) || !VectorToIdArray(cx, props, &ida))
-        return false;
+        return NULL;
     for (size_t n = 0; n < size_t(ida->length); ++n)
         JS_ASSERT(js_CheckForStringIndex(ida->vector[n]) == ida->vector[n]);
     return ida;
diff -ruN src_old/jsfun.cpp src/jsfun.cpp
--- src_old/jsfun.cpp	2011-03-19 12:33:50.000000000 +1300
+++ src/jsfun.cpp	2025-11-28 19:54:22.686549344 +1300
@@ -2052,7 +2052,7 @@
 
     JSString *str = JS_DecompileFunction(cx, fun, indent);
     if (!str)
-        return false;
+        return NULL;
 
     if (!indent)
         cx->compartment->toSourceCache.put(fun, str);
@@ -2658,7 +2658,7 @@
     const Shape *shape = funobj->nativeLookup(id);
     if (!shape) {
         if (!ResolveInterpretedFunctionPrototype(cx, funobj))
-            return false;
+            return NULL;
         shape = funobj->nativeLookup(id);
     }
     JS_ASSERT(!shape->configurable());
diff -ruN src_old/jsiter.cpp src/jsiter.cpp
--- src_old/jsiter.cpp	2011-03-19 12:33:50.000000000 +1300
+++ src/jsiter.cpp	2025-11-28 19:55:49.322088177 +1300
@@ -425,7 +425,7 @@
          */
         JSObject *obj = js_NewGCObject(cx, FINALIZE_OBJECT0);
         if (!obj)
-            return false;
+            return NULL;
         obj->init(cx, &js_IteratorClass, NULL, NULL, NULL, false);
         obj->setMap(cx->compartment->emptyEnumeratorShape);
         return obj;
diff -ruN src_old/jsparse.cpp src/jsparse.cpp
--- src_old/jsparse.cpp	2011-03-19 12:33:51.000000000 +1300
+++ src/jsparse.cpp	2025-11-28 18:08:47.242185339 +1300
@@ -3352,7 +3352,7 @@
     if (!outertc->inFunction() && bodyLevel && funAtom && !lambda && outertc->compiling()) {
         JS_ASSERT(pn->pn_cookie.isFree());
         if (!DefineGlobal(pn, outertc->asCodeGenerator(), funAtom))
-            return false;
+            return NULL;
     }
 
     pn->pn_blockid = outertc->blockid();
diff -ruN src_old/jsstr.cpp src/jsstr.cpp
--- src_old/jsstr.cpp	2011-03-19 12:33:51.000000000 +1300
+++ src/jsstr.cpp	2025-11-28 18:01:16.809181447 +1300
@@ -1734,7 +1734,7 @@
         if (flat) {
             patstr = flattenPattern(cx, fm.patstr);
             if (!patstr)
-                return false;
+                return NULL;
         } else {
             patstr = fm.patstr;
         }
@@ -3400,7 +3400,7 @@
                                  UndefinedValue(), NULL, NULL,
                                  JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED, 0, 0,
                                  NULL)) {
-        return JS_FALSE;
+        return NULL;
     }
 
     return proto;
diff -ruN src_old/jstypedarray.cpp src/jstypedarray.cpp
--- src_old/jstypedarray.cpp	2011-03-19 12:33:51.000000000 +1300
+++ src/jstypedarray.cpp	2025-11-28 20:00:22.614582793 +1300
@@ -1334,7 +1334,7 @@
         if (size != 0 && count >= INT32_MAX / size) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                  JSMSG_NEED_DIET, "size and count");
-            return false;
+            return NULL;
         }
 
         int32 bytelen = size * count;
@@ -1668,7 +1668,7 @@
 
       default:
         JS_NOT_REACHED("shouldn't have gotten here");
-        return false;
+        return NULL;
     }
 }
 
diff -ruN src_old/jsxml.cpp src/jsxml.cpp
--- src_old/jsxml.cpp	2011-03-19 12:33:51.000000000 +1300
+++ src/jsxml.cpp	2025-11-28 20:01:02.884222691 +1300
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=4 sw=4 et tw=78:
  *
  * ***** BEGIN LICENSE BLOCK *****
@@ -282,7 +282,7 @@
 
     obj = NewBuiltinClassInstanceXML(cx, &js_NamespaceClass);
     if (!obj)
-        return JS_FALSE;
+        return NULL;
     JS_ASSERT(JSVAL_IS_VOID(obj->getNamePrefixVal()));
     JS_ASSERT(JSVAL_IS_VOID(obj->getNameURIVal()));
     JS_ASSERT(JSVAL_IS_VOID(obj->getNamespaceDeclared()));
@@ -431,7 +431,7 @@
         size_t length = str->length();
         jschar *chars = (jschar *) cx->malloc((length + 2) * sizeof(jschar));
         if (!chars)
-            return JS_FALSE;
+            return NULL;
         *chars = '@';
         const jschar *strChars = str->getChars(cx);
         if (!strChars) {
diff -ruN src_old/methodjit/InvokeHelpers.cpp src/methodjit/InvokeHelpers.cpp
--- src_old/methodjit/InvokeHelpers.cpp	2011-03-19 12:33:51.000000000 +1300
+++ src/methodjit/InvokeHelpers.cpp	2025-11-29 07:42:40.832218462 +1300
@@ -728,7 +728,7 @@
 {
     JSStackFrame *fp = cx->fp();
     if (fp->hasImacropc())
-        return false;
+        return NULL;
 
     JSScript *script = fp->script();
     return script->maybeNativeCodeForPC(fp->isConstructing(), cx->regs->pc);
I ran:

Code: Select all

make -f libjs.make distclean
make -f libjs.make -j16
The static library was created in mozilla-2.0/js/src/build-release/libjs_static.a. I copied it to oolite/deps/Linux-deps/x86_64/mozilla/. I built the Oolite game and ran it installing a few expansions. It worked fine.
Post Reply