SQLite User Forum

DOS?
Login

DOS?

(1) By tom (younique) on 2021-06-28 14:53:04 [source]

Hello to all,

as SQLite is designed to also work in embedded environments with very limited capabilities, I wonder if it is possible to get it compiled for use in a DOS application. Has anyone tried that yet or can give some advice?

Kind regards, Thomas

(2) By Stephan Beal (stephan) on 2021-06-28 16:42:53 in reply to 1 [link] [source]

I wonder if it is possible to get it compiled for use in a DOS application.

Here's a much older version:

https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.2/repos/pkg-html/sqlite.html

Good luck getting a halfway recent one to build.

(3) By Mike (pgsqlite_dev) on 2025-01-15 11:06:57 in reply to 1 [link] [source]

(4) By Aask (AAsk1902) on 2025-01-15 11:19:27 in reply to 1 [link] [source]

a DOS application

What is a DOS application? Do you mean SQLite3.EXE compiled as a 16-bit executable?

(5) By Mike (pgsqlite_dev) on 2025-01-15 20:01:57 in reply to 4 [link] [source]

Look like Tom was meant exactly SQLite3.EXE compiled as a 16-bit or 32-bit executable for DOS.

(6) By Mike (pgsqlite_dev) on 2025-01-16 05:18:21 in reply to 1 [link] [source]

Adopted SQLite 3.46.1 for DOS based on some tiny code changes and Tcl script. Thanks to Ben Collver!

I hope this 2 files ( Makefile.cross-djgpp-tcl90 and sqlite-3.46.1-djgpp.diff ) will be usefully for SQLite and DOS communities for future SQLite versions.

sqlite-3.46.1-djgpp.diff

diff -Pur sqlite-src-3460100-orig/src/os_unix.c sqlite-src-3460100/src/os_unix.c
--- sqlite-src-3460100-orig/src/os_unix.c	2024-10-08 14:03:37.579253663 -0700
+++ sqlite-src-3460100/src/os_unix.c	2024-10-08 14:03:53.168253202 -0700
@@ -411,7 +411,9 @@
 
 /* Forward reference */
 static int openDirectory(const char*, int*);
+#if LINUX == 1
 static int unixGetpagesize(void);
+#endif
 
 /*
 ** Many system calls are accessed through pointer-to-functions so that
@@ -445,7 +447,7 @@
 ** that always succeeds.  This means that locking does not occur under
 ** DJGPP.  But it is DOS - what did you expect?
 */
-#ifdef __DJGPP__
+#ifdef __DDJGPP__
   { "fstat",        0,                 0  },
 #define osFstat(a,b,c)    0
 #else   
@@ -456,8 +458,13 @@
   { "ftruncate",    (sqlite3_syscall_ptr)ftruncate,  0  },
 #define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent)
 
+#ifdef __DJGPP__
+  { "fcntl",        0,                 0  },
+#define osFcntl(a,b,c)    0
+#else
   { "fcntl",        (sqlite3_syscall_ptr)fcntl,      0  },
 #define osFcntl     ((int(*)(int,int,...))aSyscall[7].pCurrent)
+#endif
 
   { "read",         (sqlite3_syscall_ptr)read,       0  },
 #define osRead      ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)
@@ -915,7 +922,9 @@
   switch (posixError) {
   case EACCES:
   case EAGAIN:
+#ifndef __DJGPP__
   case ETIMEDOUT:
+#endif
   case EBUSY:
   case EINTR:
   case ENOLCK:
@@ -1502,6 +1511,10 @@
 ** Return TRUE if pFile has been renamed or unlinked since it was first opened.
 */
 static int fileHasMoved(unixFile *pFile){
+#ifdef __DJGPP__
+  // this check returns 'true' in DJGPP enviroments even if the file was not moved --> don't check
+  return 0;
+#else
 #if OS_VXWORKS
   return pFile->pInode!=0 && pFile->pId!=pFile->pInode->fileId.pId;
 #else
@@ -1510,6 +1523,7 @@
       (osStat(pFile->zPath, &buf)!=0
          || (u64)buf.st_ino!=pFile->pInode->fileId.ino);
 #endif
+#endif
 }
 
 
@@ -1613,7 +1627,21 @@
 ** attempt to set the lock.
 */
 #ifndef SQLITE_ENABLE_SETLK_TIMEOUT
+#ifdef __DJGPP__
+//# define osSetPosixAdvisoryLock(h,x,t) 0
+static inline int osSetPosixAdvisoryLock(
+  int h,                /* The file descriptor on which to take the lock */
+  struct flock *pLock,  /* The description of the lock */
+  unixFile *pFile       /* Structure holding timeout value */
+){
+  ((void)h);
+  ((void)pLock);
+  ((void)pFile);
+  return 0;
+}
+#else
 # define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x)
+#endif
 #else
 static int osSetPosixAdvisoryLock(
   int h,                /* The file descriptor on which to take the lock */
@@ -6734,6 +6762,11 @@
   }
   appendAllPathElements(&path, zPath);
   zOut[path.nUsed] = 0;
+#ifdef __DJGPP__
+  if (zOut[0] == '/' && zOut[2] == ':') {
+    memmove(zOut, &zOut[1], path.nUsed);
+  }
+#endif
   if( path.rc || path.nUsed<2 ) return SQLITE_CANTOPEN_BKPT;
   if( path.nSymlink ) return SQLITE_OK_SYMLINK;
   return SQLITE_OK;

Makefile.cross-djgpp-tcl90

#!/usr/make
#
# Makefile for SQLITE
#
# This is a template makefile for SQLite.  Most people prefer to
# use the autoconf generated "configure" script to generate the
# makefile automatically.  But that does not work for everybody
# and in every situation.  If you are having problems with the
# "configure" script, you might want to try this makefile as an
# alternative.  Create a copy of this file, edit the parameters
# below and type "make".
#

#### The toplevel directory of the source tree.  This is the directory
#    that contains this "Makefile.in" and the "configure.in" script.
#
TOP = .

#### C Compiler and options for use in building executables that
#    will run on the platform that is doing the build.
#
BCC = gcc -g -O0
#BCC = /opt/ancic/bin/c89 -0

#### If the target operating system supports the "usleep()" system
#    call, then define the HAVE_USLEEP macro for all C modules.
#
#USLEEP = 
USLEEP = -DHAVE_USLEEP=1

#### If you want the SQLite library to be safe for use within a 
#    multi-threaded program, then define the following macro
#    appropriately:
#
#THREADSAFE = -DTHREADSAFE=1
THREADSAFE = -DTHREADSAFE=0

#### Specify any extra linker options needed to make the library
#    thread safe
#
#THREADLIB = -lpthread -lm -ldl
THREADLIB = 

#### Specify any extra libraries needed to access required functions.
#
#TLIBS = -lrt    # fdatasync on Solaris 8
TLIBS = 

#### Leave SQLITE_DEBUG undefined for maximum speed.  Use SQLITE_DEBUG=1
#    to check for memory leaks.  Use SQLITE_DEBUG=2 to print a log of all
#    malloc()s and free()s in order to track down memory leaks.
#    
#    SQLite uses some expensive assert() statements in the inner loop.
#    You can make the library go almost twice as fast if you compile
#    with -DNDEBUG=1
#
#OPTS += -DSQLITE_DEBUG=1
#OPTS += -DSQLITE_ENABLE_WHERETRACE
#OPTS += -DSQLITE_ENABLE_SELECTTRACE
OPTS = -DNDEBUG=1
OPTS += -DHAVE_NANOSLEEP=0
OPTS += -DSQLITE_ENABLE_8_3_NAMES=2
OPTS += -DSQLITE_ENABLE_FTS5=1
OPTS += -DSQLITE_ENABLE_JSON1=1
OPTS += -DSQLITE_ENABLE_LOCKING_STYLE=0
OPTS += -DSQLITE_DEFAULT_MEMSTATUS=0
OPTS += -DSQLITE_MAX_MMAP_SIZE=0
OPTS += -DSQLITE_NO_SYNC=1
OPTS += -DSQLITE_OMIT_WAL=1
OPTS += -DSQLITE_THREADSAFE=0

#### The suffix to add to executable files.  ".exe" for windows.
#    Nothing for unix.
#
EXE = .exe
#EXE =

#### C Compile and options for use in building executables that 
#    will run on the target platform.  This is usually the same
#    as BCC, unless you are cross-compiling.
#
TCC = /home/ben/local/cross-djgpp/bin/i586-pc-msdosdjgpp-gcc -O6
#TCC = gcc -g -O0 -Wall
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive

#### Tools used to build a static library.
#
AR = /home/ben/local/cross-djgpp/bin/i586-pc-msdosdjgpp-ar cr
#AR = /opt/mingw/bin/i386-mingw32-ar cr
RANLIB = ranlib
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib

MKSHLIB = /home/ben/local/cross-djgpp/bin/i586-pc-msdosdjgpp-gcc -shared
SO = so
SHPREFIX = lib
# SO = dll
# SHPREFIX =

#### Extra compiler options needed for programs that use the TCL library.
#
#TCL_FLAGS = -I/home/drh/tcl/include/tcl8.6
TCL_FLAGS = -I/home/ben/local/tcl9.0.0/generic -DSTATIC_BUILD=1 -DCONST=const -DTCL_CHANNEL_VERSION_2=TCL_CHANNEL_VERSION_5

#### Linker options needed to link against the TCL library.
#
#LIBTCL = -ltcl -lm -ldl
LIBTCL = /home/drh/tcl/lib/libtcl9.0.a -lm -lpthread -ldl -lz

#### Additional objects for SQLite library when TCL support is enabled.
#LIBOBJ =
LIBOBJ = tclsqlite.o

#### Compiler options needed for programs that use the readline() library.
#
READLINE_FLAGS =
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline

#### Linker options needed by programs using readline() must link against.
#
LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap

# You should not have to change anything below this line
###############################################################################
include $(TOP)/main.mk

(7) By Ben Collver (bencollver) on 2025-01-18 19:26:36 in reply to 1 [link] [source]

I was asked for two things
==========================

1) Instructions to build SQLite for DOS
2) Ideas about UTF-8 output versus the selected codepage

1) How to build SQLite for DOS
==============================

I built SQLite and Tcl together in order to get SQLite support within
Tcl.  For this reason, i am including instructions to build them
together.

I based my SQLite patch on the changes found in DoJS, a Javascript
runtime for DOS.

One interesting detail is that this patch completely disables file
locking in SQLite.  I don't expect SQLite to work in a networked
multi-user configuration on DOS.  With modifications, it could
theoretically work using the file locking from the SHARE command.

Build instructions follow:

I downloaded the Tcl sources:

<https://www.tcl-lang.org/software/tcltk/9.0.html>

I downloaded the DJGPP patch in source/tcl900.dif:

<gopher://tilde.pink/9/~bencollver/files/dos386/devel/tcl/tcl90r1.zip>

The remaining instructions are from the resulting file "djgpp.txt".
These instructions involve installing a DJGPP cross-compiler and
building on a Linux host system.

I installed the following cross-compiler:

<https://github.com/andrewwutw/build-djgpp>

    git clone https://github.com/andrewwutw/build-djgpp.git
    cd build-djgpp
    DJGPP_PREFIX=$HOME/local/cross-djgpp ./build-djgpp.sh 10.3.0

I extracted pdcurs39a.zip into: ~/local/cross-djgpp/pdcurses
I extracted wat3222br6.zip into: ~/local/cross-djgpp/wattcp

I downloaded the sqlite 3.46.1 source, extracted, patched, and built it.

<https://sqlite.org/2024/sqlite-src-3460100.zip>

    cd ~/local/tcl9.0.0
    unzip sqlite-src-3460100.zip
    cd sqlite-src-3460100
    patch -p1 <~/local/tcl9.0.0/contrib/djgpp/sqlite/sqlite-3.46.1-djgpp.diff
    cp ~/local/tcl9.0.0/contrib/djgpp/sqlite/Makefile.cross-djgpp-tcl90 .
    PATH=$PATH:$HOME/local/cross-djgpp/bin make -f Makefile.cross-djgpp-tcl90

2) UTF-8 output versus the selected codepage
============================================

I was told that SQLite text function gives UTF-8 only, but for CP437
or CP866 this can give unexpected output.  I was asked to comment or
give ideas about this.

On a tangent, SQLite supports the GNU readline library, but doesn't
link to it by default because of licensing issues.

Between the lack of readline and the lack of native support on DOS
for the UTF-8 encoding, i use SQLite in batch mode. This means
writing my input to a file first and also writing SQLite's output to
a file. I use a utility such as iconv or utf8tocp to convert between
my codepage and UTF-8. For example, suppose i want to search for
recipes with the word "jalapeño" in the title field and i am using
CP437 in DOS.  I can enter the lowercase letter n with tilde 'ñ' on a
CP437 PC by keying in Alt-164 on the numeric keypad.

    C:\>edit INFILE.DOS
    PRAGMA encoding="UTF-8";
    select title from recipes where title like '%jalapeño%';
    C:\>utf8tocp -r 437 INFILE.DOS >infile.sql
    C:\>sqlite3 -init infile.sql recipes.dat .quit >outfile.txt
    C:\>utf8tocp 437 outfile.txt >OUTFILE.DOS
    C:\>edit OUTFILE.DOS
    Turkey Jalapeño Sausage Reuben
    Pickled Farm-stand Tomatoes w/Jalapeños
    Jalapeño Jelly
    Jalapeño Bean Burrito

"Life is pain, highness..." --From The Princess Bride

(8) By Samuel Marks (samuel) on 2025-01-20 00:56:33 in reply to 7 [link] [source]

Curiously, 3.48.0—which was released 5 days ago—removes the TCL requirement.

> The key innovation here is that Autosetup is now used instead of GNU Autoconf. That seems like a big change, but it is really just an implementation detail. The ./configure script is coded very differently, but should work the same as before.
> One advantage of the new configure is that you no longer need to install TCL in order to build most SQLite targets.

So I'm thinking for DOS you can try applying random compilers to it and see what errs? - Like Open Watcom, DJGPP, an old version of Microsoft's suite or other old compilers from that era.

(9) By Stephan Beal (stephan) on 2025-01-20 02:33:46 in reply to 8 [link] [source]

Curiously, 3.48.0—which was released 5 days ago—removes the TCL requirement.

Not exactly: it still needs TCL but it now embeds a copy of JimTCL, which, though lighter-weight than full TCL, is sufficient for the project's code-generation needs. Canonical TCL is still required for running the tests.