diff --git a/.gitignore b/.gitignore index d36511a..2e92c1a 100644 --- a/.gitignore +++ b/.gitignore @@ -72,3 +72,18 @@ libtcc.dylib # Release packages release/ *.zip + +# Build output (self-contained toolchain) +bin/include/ +bin/lib/ +bin/*.o +bin/*.obj + + +# Allow toolchain binaries in bin/ to be committed +!bin/ +bin/* +!bin/pcc.exe +!bin/pcmake.exe +!bin/libpcc.dll +!bin/libpcc1.a diff --git a/bin/libpcc.dll b/bin/libpcc.dll new file mode 100644 index 0000000..cb594c7 Binary files /dev/null and b/bin/libpcc.dll differ diff --git a/bin/pcc.exe b/bin/pcc.exe new file mode 100644 index 0000000..227ee8c Binary files /dev/null and b/bin/pcc.exe differ diff --git a/bin/pcmake.exe b/bin/pcmake.exe new file mode 100644 index 0000000..fd94103 Binary files /dev/null and b/bin/pcmake.exe differ diff --git a/build-release.ps1 b/build-release.ps1 deleted file mode 100644 index 9833b33..0000000 --- a/build-release.ps1 +++ /dev/null @@ -1,99 +0,0 @@ -# build-release.ps1 - one-click packaging of PCC Windows toolchain -$ErrorActionPreference = "Stop" -$root = "F:\Paze C Compiler" -$win32 = Join-Path $root "win32" -$version = "0.9.28" -$outDir = Join-Path $root "release" -$pkgName = "pcc-$version-win32" -$pkgDir = Join-Path $outDir $pkgName - -Write-Host "=== PCC Windows toolchain packaging ===" -Write-Host "Version: $version" -Write-Host "" - -if (Test-Path $pkgDir) { Remove-Item $pkgDir -Recurse -Force } -New-Item -ItemType Directory -Path $pkgDir -Force | Out-Null - -Write-Host "[1/6] Copy core programs..." -Copy-Item (Join-Path $win32 "pcc.exe") $pkgDir -if (Test-Path (Join-Path $win32 "libpcc.dll")) { - Copy-Item (Join-Path $win32 "libpcc.dll") $pkgDir -} - -Write-Host "[2/6] Copy standard headers..." -$destInc = Join-Path $pkgDir "include" -New-Item -ItemType Directory -Path $destInc -Force | Out-Null -Get-ChildItem (Join-Path $root "include") -File | Copy-Item -Destination $destInc - -Write-Host "[3/6] Copy Windows headers..." -$destWinInc = Join-Path $pkgDir "win32\include" -New-Item -ItemType Directory -Path $destWinInc -Force | Out-Null -Get-ChildItem (Join-Path $win32 "include") -Recurse -File | ForEach-Object { - $rel = $_.FullName.Substring((Join-Path $win32 "include").Length + 1) - $target = Join-Path $destWinInc $rel - New-Item -ItemType Directory -Path (Split-Path $target) -Force | Out-Null - Copy-Item $_.FullName $target -} - -Write-Host "[4/6] Copy runtime libs..." -$destLib = Join-Path $pkgDir "lib" -New-Item -ItemType Directory -Path $destLib -Force | Out-Null -Get-ChildItem (Join-Path $win32 "lib") -File | Where-Object { $_.Extension -in ".a",".def" } | Copy-Item -Destination $destLib -ErrorAction SilentlyContinue -# also place libs where -B can find them (tcc layout: /lib/) -$winDestLib = Join-Path $pkgDir "win32\lib" -New-Item -ItemType Directory -Path $winDestLib -Force | Out-Null -Get-ChildItem (Join-Path $win32 "lib") -File | Where-Object { $_.Extension -in ".a",".def" } | Copy-Item -Destination $winDestLib -ErrorAction SilentlyContinue - -Write-Host "[5/6] Copy examples and docs..." -$destEx = Join-Path $pkgDir "examples" -New-Item -ItemType Directory -Path $destEx -Force | Out-Null -Get-ChildItem (Join-Path $win32 "examples") -File | Copy-Item -Destination $destEx -ErrorAction SilentlyContinue -Copy-Item (Join-Path $win32 "pcc-win32.txt") $pkgDir -ErrorAction SilentlyContinue - -Write-Host "[6/6] Create README and wrapper..." -$readme = @" -PCC - Paze C Compiler $version (Windows) -======================================== - -Usage: - pcc.bat hello.c -o hello.exe compile C program (auto paths) - pcc.bat -run hello.c compile and run directly - pcc.exe --version show version - -Structure: - pcc.exe compiler main program - pcc.bat launcher with auto include/lib paths - libpcc.dll embeddable compiler library (optional) - include\ standard C headers - win32\include\ Windows API headers - lib\ runtime and import libs - examples\ example programs - -Notes: - - Add this directory to PATH to use pcc globally - - pcc is fully self-contained, no GCC/MinGW needed - -License: MIT -"@ -$readme | Out-File (Join-Path $pkgDir "README.txt") -Encoding ascii - -# pcc.bat launcher: automatically sets -B, -I and -L relative to itself -$bat = @" -@echo off -setlocal -set "PCCDIR=%~dp0" -"%PCCDIR%pcc.exe" -B "%PCCDIR%win32" -I "%PCCDIR%include" -L "%PCCDIR%lib" %* -exit /b %errorlevel% -"@ -$bat | Out-File (Join-Path $pkgDir "pcc.bat") -Encoding ascii - -Write-Host "" -Write-Host "Zipping..." -$zipFile = Join-Path $outDir "$pkgName.zip" -if (Test-Path $zipFile) { Remove-Item $zipFile -Force } -Compress-Archive -Path $pkgDir -DestinationPath $zipFile -CompressionLevel Optimal - -$size = [math]::Round((Get-Item $zipFile).Length / 1KB, 1) -Write-Host "" -Write-Host "OK: $zipFile ($size KB)" -Write-Host "Extract and use directly, no install needed." \ No newline at end of file diff --git a/tools/pcmake.bat b/tools/pcmake.bat deleted file mode 100644 index 3b9a7dd..0000000 --- a/tools/pcmake.bat +++ /dev/null @@ -1,24 +0,0 @@ -@echo off -rem ============================================================ -rem pcmake.bat - build C projects with PCC -rem -rem Reads pcmake.conf in the current directory and builds -rem the project using the pcc compiler. -rem -rem Usage: -rem pcmake build (uses pcmake.conf in cwd) -rem pcmake clean remove build artifacts -rem ============================================================ -setlocal -set "TOOLSDIR=%~dp0" -for %%I in ("%TOOLSDIR%..") do set "ROOT=%%~fI" -set "WIN32=%ROOT%\win32" -set "PCCEXE=%WIN32%\pcc.exe" - -if not exist "%PCCEXE%" ( - echo pcmake.bat: cannot find pcc.exe at "%PCCEXE%" - exit /b 1 -) - -"%TOOLSDIR%pcmake.exe" -pcc "%PCCEXE%" -B "%WIN32%" %* -exit /b %errorlevel% diff --git a/tools/pcmake.c b/tools/pcmake.c index fcd9d6b..aad8fa7 100644 --- a/tools/pcmake.c +++ b/tools/pcmake.c @@ -267,24 +267,52 @@ int main(int argc, char **argv) { read_config(cfg); - /* locate pcc: + /* locate pcc automatically: 1. if -pcc was given, use it - 2. else if pcc.bat wrapper exists in cwd, use it (it sets -B) - 3. else search common install locations for pcc.exe */ + 2. else look for pcc.exe in the same directory as pcmake.exe + 3. else look in cwd and common install locations */ if (strcmp(pcc, "pcc") == 0) { - const char *cands[] = { - "pcc.bat", - "pcc.exe", - "C:\\pcc\\pcc.exe", - "C:\\Program Files\\pcc\\pcc.exe", - "C:\\Program Files (x86)\\pcc\\pcc.exe", - NULL - }; - int k; - for (k = 0; cands[k]; k++) { - if (file_exists(cands[k])) { - pcc = cands[k]; - break; + /* find pcmake's own executable path */ + char selfpath[MAX_STR]; + char selfdir[MAX_STR]; + char *slash; +#ifdef _WIN32 + GetModuleFileNameA(NULL, selfpath, sizeof selfpath); +#else + /* on POSIX use argv[0] relative path */ + strncpy(selfpath, argv[0], sizeof selfpath - 1); + selfpath[sizeof selfpath - 1] = 0; +#endif + strncpy(selfdir, selfpath, sizeof selfdir - 1); + selfdir[sizeof selfdir - 1] = 0; + slash = strrchr(selfdir, '\\'); + if (!slash) slash = strrchr(selfdir, '/'); + if (slash) *slash = 0; + else strcpy(selfdir, "."); + + { + char cand[MAX_STR]; + snprintf(cand, sizeof cand, "%s\\pcc.exe", selfdir); + if (file_exists(cand)) { + pcc = cand; /* pcc.exe sits next to pcmake.exe */ + /* bin/ is self-contained: pcc finds include/lib + relative to its own location, so no -B needed */ + } + } + if (strcmp(pcc, "pcc") == 0) { + const char *cands[] = { + "pcc.exe", + "C:\\pcc\\pcc.exe", + "C:\\Program Files\\pcc\\pcc.exe", + "C:\\Program Files (x86)\\pcc\\pcc.exe", + NULL + }; + int k; + for (k = 0; cands[k]; k++) { + if (file_exists(cands[k])) { + pcc = cands[k]; + break; + } } } } diff --git a/win32/build-pcc.bat b/win32/build-pcc.bat deleted file mode 100644 index 28d54e0..0000000 --- a/win32/build-pcc.bat +++ /dev/null @@ -1,208 +0,0 @@ -@rem ------------------------------------------------------ -@rem batch file to build pcc using mingw, msvc or pcc itself -@rem ------------------------------------------------------ - -@echo off -setlocal -if (%1)==(-clean) goto :cleanup -set CC=gcc -O2 -Wall -set /p VERSION= < ..\VERSION -set PCCDIR= -set BINDIR= -set DOC=no -set TX= -set SELF=%~nx0 -goto :a0 - -:a2 -shift -:a3 -shift -:a0 -if not (%1)==(-c) goto :a1 -set CC=%~2 -if (%2)==(cl) set CC=@call :cl -goto :a2 -:a1 -if (%1)==(-t) set T=%2&& goto :a2 -if (%1)==(-v) set VERSION=%~2&& goto :a2 -if (%1)==(-i) set PCCDIR=%2&& goto :a2 -if (%1)==(-b) set BINDIR=%2&& goto :a2 -if (%1)==(-d) set DOC=yes&& goto :a3 -if (%1)==(-x) set TX=%2&& goto :a2 -if (%1)==() goto :p1 - -:usage -echo usage: build-pcc.bat [ options ... ] -echo options: -echo -c prog use prog (gcc/pcc/cl) to compile pcc -echo -c "prog options" use prog with options to compile pcc -echo -t target set target -echo -x target build pcc cross-compiler for target -echo -v "version" set pcc version -echo -i pccdir install pcc into pccdir -echo -b bindir but install pcc.exe and libpcc.dll into bindir -echo -d create pcc-doc.html too (needs makeinfo) -echo -clean delete all previously produced files and directories -echo supported targets i386 x86_64 arm64 -exit /B 1 - -@rem ------------------------------------------------------ -@rem sub-routines - -:cleanup -set LOG=echo -%LOG% removing files: -for %%f in (*pcc.exe libpcc.dll lib\*.a) do call :del_file %%f -for %%f in (..\config.h ..\config.texi) do call :del_file %%f -for %%f in (include\*.h) do @if exist ..\%%f call :del_file %%f -for %%f in (include\pcclib.h examples\libpcc_test.c) do call :del_file %%f -for %%f in (lib\*.o *.o *.obj *.def *.pdb *.lib *.exp *.ilk) do call :del_file %%f -%LOG% removing directories: -for %%f in (doc libpcc) do call :del_dir %%f -%LOG% done. -exit /B 0 -:del_file -if exist %1 del %1 && %LOG% %1 -exit /B 0 -:del_dir -if exist %1 rmdir /Q/S %1 && %LOG% %1 -exit /B 0 - -@rem ------------------------------------------------------ -:cl -@echo off -set CMD=cl -:c0 -set ARG=%1 -set ARG=%ARG:.dll=.lib% -if (%1)==(-shared) set ARG=-LD -if (%1)==(-o) shift && set ARG=-Fe%2 -set CMD=%CMD% %ARG% -shift -if not (%1)==() goto :c0 -echo on -%CMD% -O2 -W2 -Zi -MT -GS- -nologo %DEF_GITHASH% -link -opt:ref,icf -@exit /B %ERRORLEVEL% - -@rem ------------------------------------------------------ -@rem main program - -:p1 -if not _%TX%_==__ set T=%TX%&&set TX=%TX%-win32- -if _%T%_%PROCESSOR_ARCHITECTURE%_==__x86_ set T=i386 -if _%T%_%PROCESSOR_ARCHITECTURE%_==__ARM64_ set T=arm64 -if _%T%_==__ set T=x86_64 -if %T%==i386 set D=-DPCC_TARGET_PE -DPCC_TARGET_I386 -if %T%==x86_64 set D=-DPCC_TARGET_PE -DPCC_TARGET_X86_64 -if %T%==arm64 set D=-DPCC_TARGET_PE -DPCC_TARGET_ARM64 -if "%D%"=="" echo %SELF%: error: unknown target '%T%'&&exit /B 1 - -@if (%CC:~0,3%)==(gcc) set CC=%CC% -s -static -@if (%BINDIR%)==() set BINDIR=%PCCDIR% - -:git_hash -git.exe --version 2>nul -if not %ERRORLEVEL%==0 goto :git_done -for /f %%b in ('git.exe rev-parse --abbrev-ref HEAD') do set GITHASH=%%b -for /f %%b in ('git.exe log -1 "--pretty=format:%%cs_%GITHASH%@%%h"') do set GITHASH=%%b -git.exe diff --quiet -if %ERRORLEVEL%==1 set GITHASH=%GITHASH%* -:git_done -@echo on - -:config.h -echo>..\config.h #define PCC_VERSION "%VERSION%" -@if not "%GITHASH%"=="" echo>>..\config.h #define PCC_GITHASH "%GITHASH%" -@if not _%BINDIR%_==_%PCCDIR%_ echo>>..\config.h #define CONFIG_PCCDIR "%PCCDIR:\=/%" -@if not _%TX%_==__ @echo>>..\config.h #define CONFIG_PCC_CROSSPREFIX "%TX%" - -@rem echo>> ..\config.h #define CONFIG_PCC_PREDEFS 1 -@rem %CC% -DC2STR ..\conftest.c -o c2str.exe -@rem .\c2str.exe ../include/pccdefs.h ../pccdefs_.h - -@if not _%TX%_==__ goto :pcc_cross -@if not _%PCC_C%_==__ goto :pcc_only - -@if _%LIBPCC_C%_==__ set LIBPCC_C=..\libpcc.c -@set IMPLIB=libpcc.dll -@if "%CC:~0,5%"=="clang" set IMPLIB=libpcc.lib - -%CC% -o libpcc.dll -shared %LIBPCC_C% %D% -DLIBPCC_AS_DLL -@if errorlevel 1 goto :the_end -%CC% -o pcc.exe ..\pcc.c %IMPLIB% %D% -DONE_SOURCE"=0" -@if errorlevel 1 goto :the_end -@goto :compiler_done - -:pcc_only -%CC% -o pcc.exe %PCC_C% %D% -@if errorlevel 1 goto :the_end -@goto :compiler_done - -:pcc_cross -%CC% -o %TX%pcc.exe ..\pcc.c %D% -@if errorlevel 1 goto :the_end -@goto :compiler_done - -:compiler_done -@if (%EXES_ONLY%)==(yes) goto :files_done - -if not exist libpcc mkdir libpcc -if not exist doc mkdir doc -copy>nul ..\include\*.h include -copy>nul ..\pcclib.h include -copy>nul ..\libpcc.h libpcc -copy>nul ..\tests\libpcc_test.c examples -copy>nul pcc-win32.txt doc - -if exist libpcc.dll .\pcc -impdef libpcc.dll -o libpcc\libpcc.def -@if errorlevel 1 goto :the_end - -:lib -@call :make_lib %TX% || goto :the_end - -:pcc-doc.html -@if not (%DOC%)==(yes) goto :doc-done -echo>..\config.texi @set VERSION %VERSION% -cmd /c makeinfo --html --no-split ../pcc-doc.texi -o doc/pcc-doc.html -:doc-done - -:files_done -for %%f in (*.o *.def) do @del %%f - -:copy-install -@if (%PCCDIR%)==() goto :the_end -if not exist %BINDIR% mkdir %BINDIR% -for %%f in (*pcc.exe *pcc.dll) do @copy>nul %%f %BINDIR%\%%f -if not exist %PCCDIR% mkdir %PCCDIR% -@if not exist %PCCDIR%\lib mkdir %PCCDIR%\lib -for %%f in (lib\*.a lib\*.o lib\*.def) do @copy>nul %%f %PCCDIR%\%%f -for %%f in (include examples libpcc doc) do @xcopy>nul /s/i/q/y %%f %PCCDIR%\%%f - -:the_end -exit /B %ERRORLEVEL% - -:make_lib -@set LIBPCC1=libpcc1 -@if _%1_==_arm64_ set LIBPCC1=lib-arm64 -.\%1pcc -B. -c ../lib/%LIBPCC1%.c -.\%1pcc -B. -c lib/crt1.c -.\%1pcc -B. -c lib/crt1w.c -.\%1pcc -B. -c lib/wincrt1.c -.\%1pcc -B. -c lib/wincrt1w.c -.\%1pcc -B. -c lib/dllcrt1.c -.\%1pcc -B. -c lib/dllmain.c -.\%1pcc -B. -c lib/winex.c -.\%1pcc -B. -c lib/chkstk.S -.\%1pcc -B. -c ../lib/alloca.S -.\%1pcc -B. -c ../lib/alloca-bt.S -.\%1pcc -B. -c ../lib/stdatomic.c -.\%1pcc -B. -c ../lib/atomic.S -.\%1pcc -B. -c ../lib/builtin.c -.\%1pcc -ar lib/%1libpcc1.a %LIBPCC1%.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o winex.o chkstk.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o -.\%1pcc -B. -c ../lib/bcheck.c -o lib/%1bcheck.o -bt -I.. -.\%1pcc -B. -c ../lib/bt-exe.c -o lib/%1bt-exe.o -.\%1pcc -B. -c ../lib/bt-log.c -o lib/%1bt-log.o -.\%1pcc -B. -c ../lib/bt-dll.c -o lib/%1bt-dll.o -.\%1pcc -B. -c ../lib/runmain.c -o lib/%1runmain.o -exit /B %ERRORLEVEL% diff --git a/win32/pcc-run.cmd b/win32/pcc-run.cmd deleted file mode 100644 index c68346d..0000000 --- a/win32/pcc-run.cmd +++ /dev/null @@ -1,21 +0,0 @@ -@echo off -rem ============================================================ -rem pcc-run.cmd - run a C source file directly (script mode) -rem -rem Usage: -rem pcc-run hello.c [args...] -rem pcc-run myscript [args...] (no extension works too) -rem -rem This compiles the C file in memory and runs it immediately, -rem just like a script. No .exe file is produced. -rem ============================================================ -setlocal -set "PCCDIR=%~dp0" - -if "%~1"=="" ( - echo Usage: pcc-run script.c [arguments...] - exit /b 1 -) - -"%PCCDIR%pcc.exe" -B "%PCCDIR%win32" -I "%PCCDIR%include" -L "%PCCDIR%lib" -run %* -exit /b %errorlevel%