# Copyright: 2016-2025 Paul Obermeier (obermeier@tcl3d.org)
# Distributed under BSD license.
#
# BuildType: MSys / gcc
#
# Possible user configuration options (--copt):
#   Build static wish: "Static=ON|OFF". Default: OFF.
#   Any -DXXX option usable for CFLAGS environment variable.
#
# Changes to source code (manual additions):
# Versions 8.6.5 and 8.6.6 generic/tkImgPhoto.c:
# Added patch for photo commands "read", "put" and "write",
# which do not allow filenames or data starting with "-".
# Applied bug fix for Mac (http://core.tcl-lang.org/tk/info/6cac4ac67e845927)

proc Init_Tk { libName libVersion } {
    SetScriptAuthor    $libName "Paul Obermeier" "obermeier@tcl3d.org"
    SetLibHomepage     $libName "https://core.tcl-lang.org/tk/"
    SetLibDependencies $libName "Tcl"
    SetPlatforms       $libName "All"
    SetWinCompilers    $libName "gcc"
}

proc Build_Tk { libName libVersion buildDir instDir devDir distDir } {
    set buildDirMSys     [MSysPath $buildDir]
    set instDirMSys      [MSysPath $instDir]
    set rootBuildDirMSys [MSysPath [GetOutputBuildDir]]

    set buildStatic false
    if { [string tolower [GetUserConfigValue $libName "Static"]] eq "on" } {
        set buildStatic true
    }

    if { [UseStage "Extract" $libName] } {
        ExtractLibrary $libName $buildDir

        if { [IsDarwin] && [IsArm] } {
            if { [VersionCheck [GetTkVersion] "older" "8.6.13"] } {
                # Versions older than 8.6.13 cannot be compiled on ARM based Darwin.
                SetErrorMessage "Darwin-arm does not support Tk versions older than 8.6.13."
                return false
            } elseif { [VersionCheck [GetTclVersion] "equal" "8.6.13"] } {
                # Version 8.6.13 has a bug in unix/configure,
                # so that it cannot be built on ARM based Darwin.
                ReplaceKeywords "$buildDir/unix/configure" [list "arm64e" "arm64"]
            }
        }

        if { [IsSunOS] } {
            if { [HaveTk9] } {
                FixSunOSCpAndFind "$buildDir/unix/Makefile.in"
            }
        }
    }

    if { [UseStage "Configure" $libName] } {
        set cmd     ""
        set cflags  ""
        set ldflags ""

        append cflags [GetSanitizerCFlags] " "
        append cflags [GetDarwinCFlags]    " "
        append cflags [GetUserCFlags $libName] " "

        if { [IsWindows] && [UseWinCompiler $libName "gcc"] && [Is64Bit] } {
            if { [IsGccCompilerNewer "8.1.0"] } {
                if { [VersionCompare "8.6.11" $libVersion] > 0 } {
                    # Tk versions older than 8.6.11 need the following for 64-bit builds
                    # using MinGW gcc 11.2.0. Otherwise a linker error occurs:
                    # relocation truncated to fit: R_X86_64_32S against `.text'
                    append ldflags "-Wl,--image-base -Wl,0x10000000 "
                }
            }
        }
        # Stripping the Tk dynamic library with command strip, does not work with Tcl >= 8.7.
        # This would remove the zipfs file system.
        # So we use the "-s" options of gcc for stripping.
        if { [StripLibs] && [IsReleaseBuild] && ( [GetCompilerVersion -lib $libName] eq "gcc" ) } {
            append ldflags "-s "
        }

        if { [string trim $cflags] ne "" } {
            append cmd "CFLAGS='$cflags' "
        }
        if { [string trim $ldflags] ne "" } {
            append cmd "LDFLAGS='$ldflags' "
        }
        if { [IsWindows] } {
            append cmd "$buildDirMSys/win/configure "
            append cmd "--build=[GetMingwVersion] "
        } else {
            append cmd "$buildDirMSys/unix/configure "
        }
        append cmd     "--prefix=$instDirMSys --exec-prefix=$instDirMSys "
        append cmd     "--with-tcl=$rootBuildDirMSys/Tcl "
        if { [Is64Bit] } {
            append cmd "--enable-64bit "
        }
        if { [IsDebugBuild] } {
            append cmd "--enable-symbols "
        } else {
            append cmd "--disable-symbols "
        }
        if { [IsDarwin] } {
            append cmd "--enable-aqua "
        }
        if { [IsSunOS "Solaris"] && [HaveTk9] } {
            append cmd "--enable-libcups=no "
        }
        if { $buildStatic == true } {
            append cmd "--disable-shared "
        }

        MSysRun $libName "${libName}_Configure" $buildDir "$cmd"
    }

    if { [UseStage "Compile" $libName] } {
        MSysBuild $libName $buildDir "install"
        # Install internal header files, too. Need for Togl widget.
        MSysBuild $libName $buildDir "install-private-headers"

        if { $buildStatic == false } {
            set tkLib [GetTkLibName $libVersion]
            if { [NeedDll2Lib $libName] } {
                Dll2Lib $libName "$instDir/bin" "${tkLib}.dll" "${tkLib}.def" "${tkLib}.lib"
            }
        }

        SingleFileCopy "$instDir/bin/[GetWishName $libVersion]" "$instDir/bin" "wish[GetExeSuffix]"
        if { [IsDebugBuild] } {
            SingleFileCopy "$instDir/bin/[GetWishName $libVersion]" "$instDir/bin" "wishg[GetExeSuffix]"
            set tkDir "tk[GetMajorMinor $libVersion .]"
            if { [IsWindows] } {
                SingleFileCopy "$instDir/lib/${tkDir}g/pkgIndex.tcl" "$instDir/lib/${tkDir}" -mustexist false
            } elseif { [IsLinux] } {
                if { [file isdirectory "$instDir/lib[GetBits true]/${tkDir}"] } {
                    SingleFileCopy "$instDir/lib[GetBits true]/${tkDir}/pkgIndex.tcl" "$instDir/lib/${tkDir}"
                }
            } else {
                SingleFileCopy "$instDir/lib/${tkDir}/pkgIndex.tcl" "$instDir/lib/${tkDir}"
            }
        }
    }

    if { [UseStage "Distribute" $libName] } {
        if { [IsWindows] } {
            MultiFileCopy "$instDir/bin"  "$devDir/[GetTclBinDir]"   "*.exe *.dll"
            MultiFileCopy "$instDir/bin"  "$distDir/[GetTclBinDir]"  "*.exe *.dll"
            if { $buildStatic == false } {
                if { [UseWinCompiler $libName "vs"] || [NeedDll2Lib $libName] } {
                    MultiFileCopy "$instDir/bin"  "$devDir/[GetTclLibDir]"   "*.lib"
                    MultiFileCopy "$instDir/bin"  "$distDir/[GetTclLibDir]"  "*.lib"
                }
            }
        } else {
            MultiFileCopy "$instDir/bin"  "$devDir/[GetTclBinDir]"
            MultiFileCopy "$instDir/bin"  "$distDir/[GetTclBinDir]"
        }
        MultiFileCopy "$instDir/include"  "$devDir/[GetTclIncDir]"   "*"  true
        MultiFileCopy "$instDir/include"  "$distDir/[GetTclIncDir]"  "*"  true

        LibFileCopy "$instDir"  "$devDir/[GetTclDir]"   "*"  true
        LibFileCopy "$instDir"  "$distDir/[GetTclDir]"  "*"  true
    }
    return true
}

proc Test_Tk { libName libVersion buildDir instDir devDir distDir } {
    if { [UseStage "Test" $libName] } {
        MSysTest $libName $buildDir "test"
    }
    return true
}
