Skip to content

Update Omake for Linux running#1060

Merged
LADSoft merged 35 commits intoLADSoft:masterfrom
chuggafan:fix_omake_real
Dec 28, 2025
Merged

Update Omake for Linux running#1060
LADSoft merged 35 commits intoLADSoft:masterfrom
chuggafan:fix_omake_real

Conversation

@chuggafan
Copy link
Contributor

This is a prototype with some basic changes for linux, this DOES NOT CURRENTLY WORK, and I know this because I haven't tested anything to do with actually capturing process output, this is just some fill-in from before to get some eyeballs on this.

The main thing stopping me from getting anywhere is my complete inability to understand how the dup2 stuff works, and all of the pipe issues, which gets me lost immediately upon trying to understand it, I'm at the point of trying to understand how glibc implements popen and it has also gotten me absolutely nowhere...
@GitMensch I assume you have the best eyes to know what in the universe POSIX is supposed to be doing and if I'm on the right track here, because I sure know I don't.

@chuggafan chuggafan changed the title Fix prototype code. Update Omake for Linux running Jan 4, 2025
@chuggafan
Copy link
Contributor Author

Ok, so I've done some testing, I've figured out how to get the readout from posix_spawn properly, thankfully, it's not too bad, it's just annoying because I have to juggle multiple pipes (for stdout and stdin) on that, and then remember everything, I've actually made a test-program for this because the online documentation is so bad that it's not understandable to a beginning that I'll add here in case someone in the future somehow finds this and wants my work as a reference:

#define _GNU_SOURCE
#include <spawn.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <poll.h>
extern char **environ;
int main()
{
    posix_spawn_file_actions_t spawn_actions;
    posix_spawnattr_t attrs;
    posix_spawn_file_actions_init(&spawn_actions);
    posix_spawnattr_init(&attrs);
    pid_t spawned_pid;
    int pipes[2];
    int ret = pipe2(pipes, O_CLOEXEC);
    if (ret != 0)
    {
        printf("Pipe failed\n");
    }
    // Copy stdout to the writable pipe, pipes[0] is the readable pipe. Mirrors stdin vs stdout
    posix_spawn_file_actions_adddup2(&spawn_actions, pipes[1], 1);
    // Ensure pipes close
    posix_spawn_file_actions_addclose(&spawn_actions, pipes[1]);
    posix_spawn_file_actions_addclose(&spawn_actions, pipes[0]);

    ret = posix_spawn(&spawned_pid, "/bin/sh", &spawn_actions, &attrs, (char *const[]){"sh", "-c", "--", "ls /var/", NULL}, environ);
    if (ret)
    {
        printf("Failed to spawn! errno: %d\n", ret);
    }
    posix_spawn_file_actions_destroy(&spawn_actions);
    posix_spawnattr_destroy(&attrs);

    int wait_status = 0;
    do
    {
        wait_status = 0;
        char val[80] = {0};
        struct pollfd polls = {.events = POLLIN, .fd = pipes[0]};
        // Poll for < 100ms, if we timeout on having any data whatsoever, we check if the process is done, if the process is done, exit the read loop.
        int ret = poll(&polls, 1, 100);
        if (ret > 0)
        {
            if (polls.revents & POLLIN)
            {
                int success = read(pipes[0], val, sizeof(val) - 1);
                printf("%s", val);
                if (success < 1)
                {
                    break;
                }
            }
        }
        if (ret == 0)
        {
            waitpid(spawned_pid, &wait_status, WUNTRACED);
            if (!(!WIFEXITED(wait_status) && !WIFSIGNALED(wait_status) && !WIFSTOPPED(wait_status)))
            {
                break;
            }
        }
    } while (1);
    close(pipes[0]);
    close(pipes[1]);
}

I have verified in WSL that this prints the exact output of ls /var/ on my machine.
I'm going to incorporate this now that I have it into my code for this PR since I now realize my previous attempt was not even close to successful.

@LADSoft
Copy link
Owner

LADSoft commented Feb 2, 2025

😄

@chuggafan
Copy link
Contributor Author

Minor update:
I've integrated the aforementioned code, current status is that it is able to run once, before getting a return of "EBADF" on the 2nd run, I have no idea what is causing it, and I've dug as far as the linux kernel clone3 syscall itself, as I'm getting EBADF off of the posix_spawn call, and not the adddup2 call, I have literally no idea what's going on there.
I likely will want an actual linux box for future testing on this as this is... weird, and possibly has some weird WSL custom kernel shenanigans at play instead of the mainline kernel here, and I may shop around for some extra hardware to make that happen in the near future.
But this is a basic status update.

@chuggafan
Copy link
Contributor Author

Well... I got back to this.
I think I found my answer to this weird question by running omake on the OrangeC repo:

Failed to spawn, errno: 2, err: No such file or directory, command: .\omake\omake.exe -f \home\user\OrangeC\src\treetop.mak createdirs
Failed to spawn, errno: 9, err: Bad file descriptor, command: .\omake\omake.exe -f \home\user\OrangeC\src\treetop.mak library
Failed to spawn, errno: 9, err: Bad file descriptor, command: .\omake\omake.exe -f \home\user\OrangeC\src\treetop.mak exefile

On unix systems, this should default to forward slashes, I'll have to search for that logic somewhere....

@chuggafan
Copy link
Contributor Author

        gcc -O3 -Wextra -Wall -pedantic -c -o test_spawn.o test_spawn.c

/bin/bash
-c
--
gcc -O3 -Wextra -Wall -pedantic -c -o test_spawn.o test_spawn.c
Env: .DEFAULT_GOAL=
Env: .FEATURES=second-expansion order-only target-specific
Env: .INCLUDE_DIRS=
Env: CURDIR=/home/user/test_spawn
Env: DISPLAY=:0
Env: HOME=/home/user
Env: HOSTTYPE=x86_64
Env: LANG=en_US.UTF-8
Env: LOGNAME=user
Env: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=00:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.avif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:*~=00;90:*#=00;90:*.bak=00;90:*.old=00;90:*.orig=00;90:*.part=00;90:*.rej=00;90:*.swp=00;90:*.tmp=00;90:*.dpkg-dist=00;90:*.dpkg-old=00;90:*.ucf-dist=00;90:*.ucf-new=00;90:*.ucf-old=00;90:*.rpmnew=00;90:*.rpmorig=00;90:*.rpmsave=00;90:
Env: MAKE=/home/user/omake.exe
Env: MAKECMDGOALS=
Env: MAKEFLAGS= -j:1 --jobserver-auth=3,4 $(MAKEOVERRIDES)
Env: MAKEOVERRIDES=
Env: MAKE_LEVEL=0
Env: NAME=DESKTOP-blargh
Env: OLDPWD=/home/user/test
Env: PATH=/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/Program Files/WindowsApps/TheDebianProject.DebianGNULinux_1.18.0.0_x64__76v4gfsz19hv4:/mnt/c/Program Files/ImageMagick-7.1.1-Q16-HDRI:/mnt/c/Program Files/Common Files/Oracle/Java/javapath:/mnt/c/Program Files (x86)/Common Files/Oracle/Java/java8path:/mnt/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/mnt/c/Program Files/Oculus/Support/oculus-runtime:/mnt/c/Program Files/Microsoft/jdk-11.0.13.8-hotspot/bin:/mnt/c/Program Files/Microsoft/jdk-17.0.1.12-hotspot/bin:/mnt/c/Windows/system32:/mnt/c/Windows:/mnt/c/Windows/System32/Wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0/:/mnt/c/Windows/System32/OpenSSH/:/mnt/c/Program Files/Microsoft SQL Server/150/Tools/Binn/:/mnt/c/Program Files/Microsoft SQL Server/Client SDK/ODBC/170/Tools/Binn/:/mnt/c/Program Files/dotnet/:/mnt/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/mnt/c/Program Files/MATLAB/R2022a/bin:/mnt/c/Program Files/LLVM/bin:/mnt/c/Program Files/Graphviz/bin:/mnt/c/Program Files/Git/cmd:/mnt/c/Program Files/Microchip/xc32/v4.35/bin:/mnt/c/Program Files/Microchip/xc16/v2.10/bin:/mnt/c/Program Files (x86)/Windows Kits/10/Windows Performance Toolkit/:/mnt/c/Program Files/PuTTY/:/mnt/c/Program Files/CMake/bin:/mnt/c/Program Files/NVIDIA Corporation/NVIDIA app/NvDLISR:/mnt/c/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/12.2 rel1/bin:/mnt/c/Users/user/AppData/Local/Programs/Python/Python310/Scripts/:/mnt/c/Users/user/AppData/Local/Programs/Python/Python310/:/mnt/c/Users/user/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/user/AppData/Local/Programs/Microsoft VS Code/bin:/mnt/c/Users/user/.dotnet/tools
Env: PULSE_SERVER=unix:/mnt/wslg/PulseServer
Env: PWD=/home/user/test_spawn
Env: SHELL=/bin/bash
Env: SHLVL=1
Env: TERM=xterm-256color
Env: USER=user
Env: VPATH=
Env: WAYLAND_DISPLAY=wayland-0
Env: WSL2_GUI_APPS_ENABLED=1
Env: WSLENV=
Env: WSL_DISTRO_NAME=Debian
Env: WSL_INTEROP=/run/WSL/13_interop
Env: XDG_RUNTIME_DIR=/mnt/wslg/runtime-dir
Env: _=/home/user/omake.exe
cwd: /home/user/test_spawn
        gcc test_spawn.o -o test_spawn

/bin/bash
-c
--
gcc test_spawn.o -o test_spawn
Env: .DEFAULT_GOAL=
Env: .FEATURES=second-expansion order-only target-specific
Env: .INCLUDE_DIRS=
Env: CURDIR=/home/user/test_spawn
Env: DISPLAY=:0
Env: HOME=/home/user
Env: HOSTTYPE=x86_64
Env: LANG=en_US.UTF-8
Env: LOGNAME=user
Env: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=00:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.avif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:*~=00;90:*#=00;90:*.bak=00;90:*.old=00;90:*.orig=00;90:*.part=00;90:*.rej=00;90:*.swp=00;90:*.tmp=00;90:*.dpkg-dist=00;90:*.dpkg-old=00;90:*.ucf-dist=00;90:*.ucf-new=00;90:*.ucf-old=00;90:*.rpmnew=00;90:*.rpmorig=00;90:*.rpmsave=00;90:
Env: MAKE=/home/user/omake.exe
Env: MAKECMDGOALS=
Env: MAKEFLAGS= -j:1 --jobserver-auth=3,4 $(MAKEOVERRIDES)
Env: MAKEOVERRIDES=
Env: MAKE_LEVEL=0
Env: NAME=DESKTOP-blargh
Env: OLDPWD=/home/user/test
Env: PATH=/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/Program Files/WindowsApps/TheDebianProject.DebianGNULinux_1.18.0.0_x64__76v4gfsz19hv4:/mnt/c/Program Files/ImageMagick-7.1.1-Q16-HDRI:/mnt/c/Program Files/Common Files/Oracle/Java/javapath:/mnt/c/Program Files (x86)/Common Files/Oracle/Java/java8path:/mnt/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/mnt/c/Program Files/Oculus/Support/oculus-runtime:/mnt/c/Program Files/Microsoft/jdk-11.0.13.8-hotspot/bin:/mnt/c/Program Files/Microsoft/jdk-17.0.1.12-hotspot/bin:/mnt/c/Windows/system32:/mnt/c/Windows:/mnt/c/Windows/System32/Wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0/:/mnt/c/Windows/System32/OpenSSH/:/mnt/c/Program Files/Microsoft SQL Server/150/Tools/Binn/:/mnt/c/Program Files/Microsoft SQL Server/Client SDK/ODBC/170/Tools/Binn/:/mnt/c/Program Files/dotnet/:/mnt/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/mnt/c/Program Files/MATLAB/R2022a/bin:/mnt/c/Program Files/LLVM/bin:/mnt/c/Program Files/Graphviz/bin:/mnt/c/Program Files/Git/cmd:/mnt/c/Program Files/Microchip/xc32/v4.35/bin:/mnt/c/Program Files/Microchip/xc16/v2.10/bin:/mnt/c/Program Files (x86)/Windows Kits/10/Windows Performance Toolkit/:/mnt/c/Program Files/PuTTY/:/mnt/c/Program Files/CMake/bin:/mnt/c/Program Files/NVIDIA Corporation/NVIDIA app/NvDLISR:/mnt/c/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/12.2 rel1/bin:/mnt/c/Users/user/AppData/Local/Programs/Python/Python310/Scripts/:/mnt/c/Users/user/AppData/Local/Programs/Python/Python310/:/mnt/c/Users/user/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/user/AppData/Local/Programs/Microsoft VS Code/bin:/mnt/c/Users/user/.dotnet/tools
Env: PULSE_SERVER=unix:/mnt/wslg/PulseServer
Env: PWD=/home/user/test_spawn
Env: SHELL=/bin/bash
Env: SHLVL=1
Env: TERM=xterm-256color
Env: USER=user
Env: VPATH=
Env: WAYLAND_DISPLAY=wayland-0
Env: WSL2_GUI_APPS_ENABLED=1
Env: WSLENV=
Env: WSL_DISTRO_NAME=Debian
Env: WSL_INTEROP=/run/WSL/13_interop
Env: XDG_RUNTIME_DIR=/mnt/wslg/runtime-dir
Env: _=/home/user/omake.exe
cwd: /home/user/test_spawn
Failed to spawn, errno: 9, err: Bad file descriptor, command: gcc test_spawn.o -o test_spawn
cwd:/home/user/test_spawn

Error Makefile(9): commands returned error code -1

I've been staring at this result through WSL and I have absolutely no idea what in the universe is causing omake to only run the first time, not the 2nd.
Utterly confusing, errno 9 (EBADF) as best as I can tell doesn't even come out in the most recent kernels! (I haven't looked at the Microsoft WSL kernel yet).

@LADSoft
Copy link
Owner

LADSoft commented Feb 23, 2025

so i don't know anything about linux, but, is there some possibility that the first run doesn't clean something up? Maybe Leaves a handle to the file being spawned open or something?

@chuggafan
Copy link
Contributor Author

Hmmm, re-looking with more info this might be an artifact of posix_spawn_file_actions_addclose only performing a fnctl call in posix_spawn and that kicks an EBADF?

@chuggafan
Copy link
Contributor Author

I figured it out, I forgot to actually fill in the pipe by calling pipe, so when I attempt to open a new pipe it fails the 2nd go around.
I have no idea how it functions properly the first time.

…'t point out where EBADF would appear from that, whoops.
@chuggafan
Copy link
Contributor Author

Current status with the new build:
The current make program does not handle Makefile and makefile simultaneously, as linux is case sensitive, I would prefer a fallback system of something like Makefile -> makefile for automatic makefiles, but I'd have to do a bunch of piping reworks to fix that I think.
My test program functions fine, but no major makefile has been checked yet.

@GitMensch
Copy link
Contributor

You know, if you want to put the updated omake to some serious test, there's #168 for that ;-)

@LADSoft
Copy link
Owner

LADSoft commented Mar 2, 2025

I'll put it on my list for later this week, to recheck the operation under windows.... then maybe we can roll it into master...

@LADSoft LADSoft marked this pull request as ready for review March 2, 2025 07:12
@chuggafan
Copy link
Contributor Author

I'm actually still working on a few issues with omake running on the OrangeC repo, notably, if I try to run it, it will try calling /homeuseromake.exe if I place omake.exe in the ~ (aka: /home/user) directory, so I'm doing some debugging to figure out where that is coming from, I'll say this PR is ready when omake can be used to compile OrangeC on linux, I've only done the bare minimum start here.

@GitMensch
Copy link
Contributor

What about just setting it to a "draft" until you considered this goal to be reached?

@chuggafan
Copy link
Contributor Author

Well, since I'm not the repository owner, and this was changed from draft by the repo owner, I can't exactly do that anymore, thanks github.

@LADSoft
Copy link
Owner

LADSoft commented Mar 3, 2025

yeah sorry about that. I pressed a button that did nothing like what I was expecting it to do... sigh....

@LADSoft LADSoft marked this pull request as draft March 3, 2025 16:09
@chuggafan
Copy link
Contributor Author

chuggafan commented Mar 4, 2025

Ah, I've figured out why it's running the way it does, on Linux systems oftentimes /bin/sh is a symlink to another shell found in the system. I have to basically figure out if the shell is a unix shell or windows shell (and probably implement a preference on one or the other depending on if we're compiled for windows or linux) and then figure that out from there.
https://www.gnu.org/software/make/manual/html_node/Choosing-the-Shell.html this specific document will be my gospel for gnu make compat.
Perhaps I'm just going to check if $SHELL exists in the environment, if it does, we use $SHELL, otherwise we do what we've always done.
(TL;DR: NormalizeFileName is being run on Linux atm if your default shell is /bin/bash, need a more generic solution than checking for /bin/sh)

@chuggafan
Copy link
Contributor Author

Ok, so there's STILL an issue with make on linux:
jobserver passing, the long-option switch that we have breaks because the pipe numbers are passed with a comma separartor.

This jobserver implementation was tested a long time ago and almost certainly requires re-testing, but I will not touch the command line parsing since that's... a bit fragile for my tastes.

@chuggafan
Copy link
Contributor Author

Once I finish cleanup of #810 I'm going to return to work here, I think I can pretty decisively make some progress overall since I think 99% of the error right now is just "Get the switch-parser to parse stuff with commas" and that should unlock the "You have forgotten errors with Linux pipes" issue... At least that I tested (once)....
We'll see how far I get with this in the next month, but I don't expect this to be wrapped up for the next release.

@chuggafan
Copy link
Contributor Author

I've gotten a bit further, I'm doing ~/omake -v -DCOMPILER=gcc-linux -f makefile on a linux VM and it's now exiting with error code 3 after I got --jobserver-auth= somewhat working.

@LADSoft
Copy link
Owner

LADSoft commented Dec 19, 2025

i don't know why that wouldn't work. I'll try it after a while.

Right now I found that the changes you made OCCPARSE, without anychanges for anything else, cause BUILD.BAT to fail. I'm trying to diagnose it.........

@LADSoft
Copy link
Owner

LADSoft commented Dec 20, 2025

so the problem with the crash in omake is the change you made to templateinst.cpp. Problem is I'm looking at it and I'm agreeing that you deleting the code you deleted there is probably correct, however, when it is removed it caused other problems.... I'll look into it some more tomorrow....

@LADSoft
Copy link
Owner

LADSoft commented Dec 20, 2025

@chuggafan...

i updated the master branch with your compiler fixes and an additional fix that fixed a problem when compiling the omake on the master branch....

@chuggafan
Copy link
Contributor Author

I merged with the hashing branch, still has trouble running NORMALCompiles because somehow there's now a linker error, bad syntax when linking oimplib (which I made better slightly errors for because man just getting "Invalid rel file format" is easy, but not great.)

@LADSoft
Copy link
Owner

LADSoft commented Dec 20, 2025

@chuggafan, hehehe.... usually these days i don't much have to deal with syntax errors out of the linker.... the 'hashing' branch is several days old, I've made improvements since then. I've compiled the entire suite with it several times now (but not your latest omake) I just pushed it if you want to see if that resolves anything... I'm planning on merging it soon but I think I'm gonna ask if I can get more time on appveyor first...

I was noticing, you put made some fprintfs in expr.cpp for what appear to be diagnostics... usually for diagnostics I use the DIAG() macro. That collects them as they happen and then gives you a summary if there are any that happened, you can use the /C+d compiler switch to dump them after everything else is done...

@chuggafan
Copy link
Contributor Author

Ah, for the expr.cpp are you talking about the "Candidate '%s' found at....." messages? Those are actually deliberately NOT DIAGs, those are meant to be additional information for the error.
I'm trying to replicate the style of error messages brought by GCC, Clang and newer MSVCs, and that exact style is hard to replicate with our existing error mechanisms.

It's about getting more information to know exactly what the location is, it's very related to the style of update that I am thinking of for #1104
(I also just realized that using BasicTypeToString there is probably why I was getting junk and that ToString was the correct function call).

@chuggafan
Copy link
Contributor Author

Not sure exactly which change did it, but NORMALcompiles.bat now functions properly and runs until success.
I'm going to re-re-redo this after a push on Linux and if it functions we're golden for a merge.

Also change to printerr for some things.
@chuggafan
Copy link
Contributor Author

We now build on linux and run!

I can retarget this to my (actual) base at this point, which is the hashing branch, or we can merge with master.
My next plan is working on getting some benchmark library running (I'm just going to use picobench, then we can deal with gbenchmark) and get some hard numbers on my machine about how the memcpys I've made function.

Woohoo!

@LADSoft
Copy link
Owner

LADSoft commented Dec 22, 2025

as far as the fprintfs.... for things that are outside the 'normal' scope I've been putting extra %s in the error message then wrting a custom function for that one error message (or class of error messages). The 'is is not convertible to' error message is done that way for example, it has two types in the message....

I decided we had enough testing on the hashing branch now, and merged it with 'master'..... tomorrow I can accept your changes if you are up for that!

Merry Christmas!

@chuggafan
Copy link
Contributor Author

Yhea, I had forgotten about "Notes" entirely, and am converting all of the fprintfs to that (I made a "Generic" note and a "less generic" note to keep track of unique error messages).
I'm going to add some testing for suffixes to ensure we're getting good error messages, and then work on speeding up memcpy, on modern machines.
I'm probably going to go with some form of rep movsb for sizes < 256 bytes, since it actually is probably the fastest we're going to get without getting into dedicated CPU code territory and having someone specifically work on that, so I'm going to (probably) go with that and see if that does speed up the compiler.
Some docs from intel do indicate this however: (Intel 64 and IA32 Architecture optimization manual)

3.7.6.3 Memmove Considerations
When there is an overlap between the source and destination regions, software may need to use
memmove instead of memcpy to ensure correctness. It is possible to use REP MOVSB in conjunction with
the direction flag (DF) in a memmove() implementation to handle situations where the latter part of the
source region overlaps with the beginning of the destination region. However, setting the DF to force REP
MOVSB to copy bytes from high towards low addresses will experience significant performance
degradation.
When using Enhanced REP MOVSB and STOSB to implement memmove function, one can detect the
above situation and handle first the rear chunks in the source region that will be written to as part of the
destination region, using REP MOVSB with the DF=0, to the non-overlapping region of the destination.
After the overlapping chunks in the rear section are copied, the rest of the source region can be
processed normally, also with DF=0.

So I'm going to do that next, hopefully speeding up that since that will put us in modern memcpy territory on all CPUs made after 2012 can dumb us below the build limit threshold.

@chuggafan
Copy link
Contributor Author

I've pushed my changes ;)

This file now produces the following errors & notes:

#include <string>
std::string operator"" _s(const char* s, size_t sz) { return std::string(s, sz); }
std::string operator"" _s3(unsigned long long int val) { return std::to_string(val); }
int main()
{
    std::string s = 12_s;
    std::string s2 = 12_s2;
    std::string s3 = 1.2_s3;

    return 0;
}
Error(316)    suffixes.cpp(6):  Could not find a match for literal suffix '_s'
note:         suffixes.cpp(2):  Candidate was checked, but had more than one potential parameter
Error(316)    suffixes.cpp(7):  Could not find a match for literal suffix '_s2'
note:         suffixes.cpp(7):  No candidates were found
Error(316)    suffixes.cpp(8):  Could not find a match for literal suffix '_s3'
note:         suffixes.cpp(3):  Candidate tried, but has the wrong type, wanted unsigned long long, but has long double
3 Errors

@chuggafan chuggafan marked this pull request as ready for review December 24, 2025 00:56
@LADSoft
Copy link
Owner

LADSoft commented Dec 28, 2025

so i don't know about the compiler generating file errors as I haven't seen it, however, I pulled the latest from this PR, built omake with MSVC, then copied the built omake into \orangec\src, then i typed 'omake clean' and got this.

        del /Q c:\OrangeC\src\..\src\lib\ms 2> NUL
        rmdir c:\OrangeC\src\..\src\lib\ms 2> NUL
        c:\OrangeC\src\omake -C clibs clean
        del /Q c:\OrangeC\src\clibs\object\windows 2>
The syntax of the command is incorrect.
        del /Q c:\OrangeC\src\clibs\object\startup 2>
The syntax of the command is incorrect.
        del /Q c:\OrangeC\src\clibs\object\cil 2>
The syntax of the command is incorrect.
        del /Q c:\OrangeC\src\clibs\object\clib 2>
The syntax of the command is incorrect.
        del /Q platform\win32\crtdmain\*.o 2>
The syntax of the command is incorrect.
        del /Q platform\win32\lscrtl\*.o 2>
The syntax of the command is incorrect.
        del /Q platform\win32\lscrtl\*.dll 2>
The syntax of the command is incorrect.
        del /Q platform\win32\lsdbghelper\*.o 2>
The syntax of the command is incorrect.
        del /Q platform\win32\msvcrdm\*.o 2>
The syntax of the command is incorrect.
        del /Q platform\win32\occil\*.o 2>
The syntax of the command is incorrect.
        del /Q platform\win32\occil\occmsil.dll 2>
The syntax of the command is incorrect.
        del /Q platform\win32\pe\*.o 2>
The syntax of the command is incorrect.
        del /Q platform\win32\pels\*.o 2>
The syntax of the command is incorrect.
        del /Q platform\win32\rtl\*.o 2>
The syntax of the command is incorrect.
        rmdir c:\OrangeC\src\clibs\object\windows 2>
The syntax of the command is incorrect.
        rmdir c:\OrangeC\src\clibs\object\startup 2>
The syntax of the command is incorrect.
        rmdir c:\OrangeC\src\clibs\object\cil 2>
The syntax of the command is incorrect.
        rmdir c:\OrangeC\src\clibs\object\clib 2>
The syntax of the command is incorrect.
        rmdir object 2>
The syntax of the command is incorrect.
        c:\OrangeC\src\omake clean -f c:\OrangeC\src\treetop.mak -Csqlite3
        del /Q c:\OrangeC\src\sqlite3\obj\ms\*.* 2> NUL
        del /Q *.exe 2> NUL
        del /Q *.o 2> NUL
        del /Q *.odx 2> NUL
        rmdir c:\OrangeC\src\sqlite3\obj\ms 2> NUL
        del *.xcf *.xcppf *.xhf *.pdb 2> NUL
        c:\OrangeC\src\omake clean -f c:\OrangeC\src\treetop.mak -Cutil
        del /Q c:\OrangeC\src\util\obj\ms\*.* 2> NUL
        del /Q *.exe 2> NUL
        del /Q *.o 2> NUL
        del /Q *.odx 2> NUL
        rmdir c:\OrangeC\src\util\obj\ms 2> NUL

omake on the master branch doesn't do this.

I also tried to run BUILD.BAT, mostly it worked to build the compiler but similar problems did cause it to not build the runtime library every time it tried to build it.

probably NUL is getting lost somehow on the lines where it doesn't work...

@chuggafan
Copy link
Contributor Author

Hmmmm.... that's weird.
On my end it's 50/50 whether it works or not.

I think I figured it out though: I needed to add export NULLDEV to the root of the makefile.
I'll go push that commit in a second.

@LADSoft
Copy link
Owner

LADSoft commented Dec 28, 2025

thanks for the quick response. I'll check it out later today and maybe we can get this accepted :) yeah i dunno what to do about things like memcpy since it isn't practical to go for super-intensive cpu-specific changes. Thanks for looking at it! Thank you for looking at those printfs as well....

@chuggafan
Copy link
Contributor Author

Yhea, my plan for memcpy is to just use rep movsb since any CPU after 2013 has EREX set, https://lunnova.dev/articles/ryzen-slow-short-rep-mov/
I don't know about memset with rep stosb, but Intel advertises this on newer CPUs:

3.8 REP STRING OPERATIONS
Several REP string performance enhancements are available beginning with processors based on Golden
Cove microarchitecture.
3.8.1 FAST ZERO LENGTH REP MOVSB
REP MOVSB performance of zero length operations is enhanced. The latency of a zero length REP MOVSB
is now the same as the latency of lengths 1 to 128 bytes. When both Fast Short REP MOVSB and Fast Zero
Length REP MOVSB features are enabled, REP MOVSB performance is flat 9 cycles per operation, for all
strings 0-128 byte long whose source and destination operands reside in the processor first level cache.
Support for fast zero-length REP MOVSB is enumerated by the CPUID feature flag:
CPUID.07H.01H:EAX.FAST_ZERO_LENGTH_REP_MOVSB[bit 10] = 1.
3.8.2 FAST SHORT REP STOSB
REP STOSB performance of short operations is enhanced. The enhancement applies to string lengths
between 0 and 128 bytes long. When Fast Short REP STOSB feature is enabled, REP STOSB performance
is flat 12 cycles per operation, for all strings 0-128 byte long whose destination operand resides in the
processor first level cache.
Support for fast-short REP STOSB is enumerated by the CPUID feature flag:
CPUID.07H.01H:EAX.FAST_SHORT_REP_STOSB[bit 11] = 1

9 cycles per operation could mean that @4gHz processor core speeds, we get ~444MB/s speeds for just using rep movsb on the lower-performance section, which should be faster than the however many cycles our loop takes. "Golden cove" for reference is 12th Gen intel CPUs.
256-bit data paths were released in Haswell in 2013, so idk exactly how fast.

I would highly recommend taking a look at the "Intel 64 and IA-32 Architectures Optimization Reference Manual Volume 1" figure 3-3, table 3-5, and table 3-6.

@LADSoft
Copy link
Owner

LADSoft commented Dec 28, 2025

so it seems fine now, other than that the compile of the RTL is much more choppy than it was (it may take a little longer). I'm going to accept it though and we can deal with the choppiness at some other time....

@LADSoft LADSoft closed this Dec 28, 2025
@LADSoft LADSoft reopened this Dec 28, 2025
@LADSoft LADSoft merged commit e12ab1f into LADSoft:master Dec 28, 2025
2 of 5 checks passed
@chuggafan chuggafan mentioned this pull request Dec 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants