News:

Download Pelles C here: http://www.pellesc.se

Main Menu

Compiling using pomake

Started by rweidner, March 03, 2026, 05:27:26 PM

Previous topic - Next topic

rweidner

I noticed a post recently where someone was trying to compile using pomake. I didn't attempt to compile his examples. Others looked and determined the issue was user error.  But the whole thread got me thinking. Why compile from the command line?

I can explain why I use that approach. It may seem unusual to some, but it works for me. I let PellesC manage my *.ppj files, while I sometimes use a different IDE for coding. Project management and debugging stay in PellesC, and pomake handles the builds.

So, my questions are:
  • What workflow issue are you personally trying to solve if you're compiling from the command line?
  • What challenges does your "outside the box (IDE)" create, if any?
  • Did you solve those challenges? If so, how?


rweidner

This isn't my first post. There are still a few posts around.

I wrote a GTK+ PellesC post back in the day. 
I wrote a MySQL + PellesC post too. 
I was certain I wrote a SDL + PellesC post at some point in the past. But I can't seem to find that one now.

I don't mean to sound like a reporter. Just trying to start a conversation. (aka General Discussion)

rweidner

The reason I use the command line and pomake is because I also use a separate IDE from PellesC. I use PellesC IDE too. But sometimes I prefer something else.

No, I'm not a recruiter. In this context I'm just a dev that likes C and PellesC.

When I search my name, I see that none of my posts show up. What does show up are a few conversations about my posts. Other users seemed to get some value from at least a few of them. Maybe I'll make a few new ones to rebuild my street cred? My project today is PellesC + Raylib. I built a template for that type of project. I'll share that.

TimoVJL

May the source be with you

John Z

I see.  No offense meant, can't be too careful these days.

Removing my prior post.

Regards,
John Z

I don't use pomake but I'm finishing up an IDE Add-In that when called creates one batch file that does the entire build process...just for fun - -

cheers,
 

rweidner

It's all good. No offense taken. Sometimes I use a couple of tiny .bat files for building. These are 2 of them.

build_debug.bat
===============
@echo off
call "%~dp0env_pelles32.bat"
cd /d "%~dp0"
"C:\Program Files\PellesC\Bin\pomake.exe" /F "RaylibWin32.ppj" POC_PROJECT_MODE=Debug

env_pelles32.bat
================
@echo off
REM Sets PellesC environment for x86 builds.
call "C:\Program Files\PellesC\Bin\povars32.bat"

John Z

#6
Useful to be sure.  Attached it an example output .bat file from the BBBBuilder.DLL.  It built a bat file that builds itself (builds the dll that is).  It does not use pomake but uses pocc, poasm, porc, and polink.  It does not use the .prj file either.  One other possible use is to use the resulting  .bat file as a template to build using another compiler package.

Once the .bat is built the supporting file .lst files can be edited for example to add a new source file, then run the bat for a new executable.

Current limitations (working to resolve)
1) a file in the source list marked 'exclude' can't be determined as excluded (feature request submitted)
2) file names should preferably be ASCII, but ANSI might be ok too (cmd limitation)
3) sub directories with source files are not handled.  All sources must be in one directory.  This is probably the biggest issue to solve.  (fixed subdirs under the main project dir are automatically handled)

Also working on outputting a Powershell script to do the build. It is working up to polink. The polink use requires an @ preface which unfortunately is a Powershell special character . . . :(

John Z


rweidner

It took me a long minute to understand what you're building. You're building a replacement process for managing projects and project configuration. You're doing so with the intention of making the whole process less manual, scriptable, and easier to control. If I understand what you're doing, brilliant.

rweidner

John Z,
Inspired by BBB Builder, I worked with ChatGPT for a couple hours and we built this .bat file. Thanks for the inspiration. I believe this script will help improve my workflow.

@echo off
REM File: project.bat
REM Purpose: FBI Pursuit build/workflow entry point

setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

set "PROJECT_DIR=%~dp0"
if "%PROJECT_DIR:~-1%"=="\" set "PROJECT_DIR=%PROJECT_DIR:~0,-1%"
set "PROJECT_NAME=FBIPursuit"
set "EXE_NAME=FBIPursuit.exe"
set "OUTPUT_DIR=output"
set "CRUDE_EXE=C:\CRUDE\crude.exe"
set "CRUDE_REPO=C:\CRUDE"
set "WINMERGE_EXE=C:\Program Files\WinMerge\WinMergeU.exe"

set "CCFLAGS_DEBUG=-Tx86-coff -std:C17 -Zi -Ob0 -fp:precise -W1 -Gd -Ze -Zc-"
set "CCFLAGS_RELEASE=-Tx86-coff -std:C17 -Ot -Ob1 -fp:precise -W1 -Gd -Zc- -Ze"
set "LINKFLAGS_DEBUG=-machine:x86 -subsystem:console -safeseh -debug -debugtype:po kernel32.lib advapi32.lib delayimp.lib raylibdll.lib opengl32.lib gdi32.lib winmm.lib user32.lib shell32.lib"
set "LINKFLAGS_RELEASE=-machine:x86 -subsystem:console -safeseh kernel32.lib advapi32.lib delayimp.lib raylibdll.lib opengl32.lib gdi32.lib winmm.lib user32.lib shell32.lib"

if "%~1"=="" goto build_debug
if /I "%~1"=="build_debug" goto build_debug
if /I "%~1"=="build_release" goto build_release
if /I "%~1"=="rebuild_debug" goto rebuild_debug
if /I "%~1"=="rebuild_release" goto rebuild_release
if /I "%~1"=="run" goto run
if /I "%~1"=="clean" goto clean
if /I "%~1"=="crude" goto crude
if /I "%~1"=="diff" goto diff
if /I "%~1"=="help" goto help

echo Unknown target: %~1
goto help

:prepare_env
call "%PROJECT_DIR%\env_pelles32.bat"
if errorlevel 1 exit /b 1

pushd "%PROJECT_DIR%"
if errorlevel 1 exit /b 1

set "INCLUDE=%INCLUDE%;%PROJECT_DIR%\deps\include;%PROJECT_DIR%\src\include"
set "LIB=%LIB%;%PROJECT_DIR%\deps\lib"

if not exist "%OUTPUT_DIR%" mkdir "%OUTPUT_DIR%"
if errorlevel 1 (
    echo ERROR: Failed to create output directory.
    popd
    exit /b 1
)

exit /b 0

:build_debug
call :clean_internal || exit /b 1
set "ACTIVE_CCFLAGS=%CCFLAGS_DEBUG%"
set "ACTIVE_LINKFLAGS=%LINKFLAGS_DEBUG%"
call :do_build || exit /b 1
exit /b 0

:build_release
call :clean_internal || exit /b 1
set "ACTIVE_CCFLAGS=%CCFLAGS_RELEASE%"
set "ACTIVE_LINKFLAGS=%LINKFLAGS_RELEASE%"
call :do_build || exit /b 1
exit /b 0

:rebuild_debug
call :build_debug
exit /b %errorlevel%

:rebuild_release
call :build_release
exit /b %errorlevel%

:do_build
call :prepare_env || exit /b 1

echo Building %PROJECT_NAME%...

call :compile_one "main.c" || goto build_fail

for %%F in (src\*.c) do (
    call :compile_one "%%F" || goto build_fail
)

set "OBJLIST="
for /f "delims=" %%F in ('dir /b "%OUTPUT_DIR%\*.obj" 2^>nul') do (
    set "OBJLIST=!OBJLIST! "%OUTPUT_DIR%\%%F""
)

if not defined OBJLIST (
    echo ERROR: No object files were produced.
    goto build_fail
)

echo Linking %EXE_NAME%...
polink %ACTIVE_LINKFLAGS% -out:"%EXE_NAME%" !OBJLIST!
if errorlevel 1 goto build_fail

echo Build complete: %EXE_NAME%
popd
exit /b 0

:build_fail
echo Build failed.
popd
exit /b 1

:compile_one
echo Compiling %~1 ...
pocc %ACTIVE_CCFLAGS% "%~1" /Fo"%OUTPUT_DIR%\%~n1.obj"
if errorlevel 1 exit /b 1
exit /b 0

:run
pushd "%PROJECT_DIR%"
if not exist "%EXE_NAME%" (
    echo ERROR: %EXE_NAME% not found. Run build_debug or build_release first.
    popd
    exit /b 1
)
start "" "%PROJECT_DIR%\%EXE_NAME%"
popd
exit /b 0

:clean
call :clean_internal
exit /b %errorlevel%

:clean_internal
pushd "%PROJECT_DIR%"
if errorlevel 1 exit /b 1

echo Cleaning...
del /q "%OUTPUT_DIR%\*.obj" 2>nul
del /q "%EXE_NAME%" 2>nul

popd
exit /b 0

:crude
call :clean_internal || exit /b 1
if not exist "%CRUDE_EXE%" (
    echo ERROR: CRUDE not found:
    echo %CRUDE_EXE%
    exit /b 1
)
"%CRUDE_EXE%" "%PROJECT_DIR%" "%CRUDE_REPO%"
exit /b %errorlevel%

:diff
call :clean_internal || exit /b 1

if not exist "%WINMERGE_EXE%" (
    echo ERROR: WinMerge not found:
    echo %WINMERGE_EXE%
    exit /b 1
)

set "REVISIONS_DIR=%CRUDE_REPO%\%PROJECT_NAME%\revisions"
if not exist "%REVISIONS_DIR%" (
    echo ERROR: Revisions folder not found:
    echo %REVISIONS_DIR%
    exit /b 1
)

set "LATEST_REV="
for /f "delims=" %%D in ('dir "%REVISIONS_DIR%" /b /ad /o:-n 2^>nul') do (
    set "LATEST_REV=%%D"
    goto found_latest
)

:found_latest
if not defined LATEST_REV (
    echo ERROR: No revisions found in:
    echo %REVISIONS_DIR%
    exit /b 1
)

set "LATEST_DIR=%REVISIONS_DIR%\%LATEST_REV%"

echo Comparing:
echo   CURRENT: %PROJECT_DIR%
echo   REVISION: %LATEST_DIR%
start "" "%WINMERGE_EXE%" "%PROJECT_DIR%" "%LATEST_DIR%"
exit /b 0

:help
echo.
echo Usage:
echo     %~n0 build_debug
echo     %~n0 build_release
echo     %~n0 rebuild_debug
echo     %~n0 rebuild_release
echo     %~n0 run
echo     %~n0 clean
echo     %~n0 crude
echo     %~n0 diff
echo     %~n0 help
echo.
exit /b 1

John Z

Hi rweidner,

Nice - many levels of complexity added.  BBBBuilder.dll builds only for the selected mode, and execution method, you've got it all covered in one. Plus you have added much more error detection/escapes. 

Next 'soon' version of BBBBuilder has the option to output a PowerShell  script or the bat file.  PowerShell works well now so I'm integrating it into the code.  I stuck with the base PowerShell 5 since it comes with windows, even though no longer updated.  I believe it will also work with 7 but not everyone will download and install pwsh.exe.

John Z