# $Id: Portfile 120130 2014-05-16 21:51:27Z jeremyhu@macports.org $

PortSystem              1.0

# cctools uses a static library from this port when it builds, please
# revbump cctools whenever this port updates

name                    ld64
# XCode 5.1
version                 236.3
revision                1
categories              devel
platforms               darwin
maintainers             jeremyhu
homepage                http://opensource.apple.com/source/${name}/
master_sites            http://opensource.apple.com/tarballs/${name}/
license                 APSL-2
depends_build           port:libunwind-headers \
                        path:include/mach-o/dyld_priv.h:dyld-headers \
                        path:include/mach-o/arm/reloc.h:cctools-headers
description             ld64 is the new mach-o linker
long_description        ld64 combines several object files and libraries, \
                        resolves references, and produces an ouput file.

checksums               rmd160  6a3f44aa9ae57a60d2cff5b3d47be7972ad83029 \
                        sha256  8ef36729b643201081ab45ebd8586ede8f9968bc17614b679a940faa82875ca6

patchfiles              ld64-version.patch ld64-133-no-CrashReporterClient.h.patch ld64-134-missing-include.patch ld64-136-i386-badAddress.patch PR-16935960.patch PR-16936488.patch

# We don't set llvmXX as the default variant on Tiger because it would introduce a
# dependency cycle as llvm requires apple-gcc42 and ld64 to build correctly.  Users
# wanting LTO support in ld64 on Tiger can install the +llvm variant after llvm
# has been installed.
if {![variant_isset llvm29] && ![variant_isset llvm30] && ![variant_isset llvm31] && ![variant_isset llvm32] && ![variant_isset llvm33] && ![variant_isset llvm34] && ![variant_isset llvm34] && ${os.major} >= 9} {
    default_variants +llvm34

    # Leopard/powerpc has the option to not be LTO
    if {![variant_isset llvm34] && ${os.arch} ne "powerpc"} {
        ui_error "Your platform cannot be configured without LTO support in ld64.  Please enable one of the llvmXX variants, and try again."
        return -code error "Your platform cannot be configured without LTO support in ld64.  Please enable one of the llvmXX variants, and try again."
    }
}

variant universal {}

set llvm_version {}
variant llvm29 conflicts llvm30 llvm31 llvm32 llvm33 llvm34 llvm35 description {Use llvm-2.9 for libLTO} {
    set llvm_version        2.9
    depends_lib-append      port:llvm-${llvm_version}
}

variant llvm30 conflicts llvm29 llvm31 llvm32 llvm33 llvm34 llvm35 description {Use llvm-3.0 for libLTO} {
    set llvm_version        3.0
    depends_lib-append      port:llvm-${llvm_version}
}

variant llvm31 conflicts llvm29 llvm30 llvm32 llvm33 llvm34 llvm35 description {Use llvm-3.1 for libLTO} {
    set llvm_version        3.1
    depends_lib-append      port:llvm-${llvm_version}
}

variant llvm32 conflicts llvm29 llvm30 llvm31 llvm33 llvm34 llvm35 description {Use llvm-3.2 for libLTO} {
    set llvm_version        3.2
    depends_lib-append      port:llvm-${llvm_version}
}

variant llvm33 conflicts llvm29 llvm30 llvm31 llvm32 llvm34 llvm35 description {Use llvm-3.3 for libLTO} {
    set llvm_version        3.3
    depends_lib-append      port:llvm-${llvm_version}
}

variant llvm34 conflicts llvm29 llvm30 llvm31 llvm32 llvm33 llvm35 description {Use llvm-3.4 for libLTO} {
    set llvm_version        3.4
    depends_lib-append      port:llvm-${llvm_version}
}

variant llvm35 conflicts llvm29 llvm30 llvm31 llvm32 llvm33 llvm34 description {Use llvm-3.5 for libLTO} {
    set llvm_version        3.5
    depends_lib-append      port:llvm-${llvm_version}
}

set makefile "Makefile-133"

# TODO: Check ${configure.cxx_stdlib} directly once MacPorts 2.3 is released
set cxx_stdlibflags {}
platform darwin {
    set cxxstdlib {}

    if {[info exists configure.cxx_stdlib] &&
        ${configure.cxx_stdlib} ne {} &&
        [string match *clang* ${configure.cxx}]} {
        set cxxstdlib ${configure.cxx_stdlib}
    } elseif {[string match *clang* ${configure.cxx}] &&
              ${os.major} >= 13} {
        set cxxstdlib libc++
    } else {
        set cxxstdlib libstdc++
    }

    if {[string match *clang* ${configure.cxx}]} {
        set cxx_stdlibflags -stdlib=${cxxstdlib}
    }
}

if {${os.arch} eq "powerpc" || ${os.major} < 9} {
    # XCode 3.2.6
    # 127.2 should work for powerpc, but it will require some build fixes.
    version             97.17
    revision            2
    checksums           rmd160  d52df7d7f741c8bedd29cbac73dbb9db992b4795 \
                        sha256  02bd46af0809eaa415d096d7d41c3e8e7d80f7d8d181840866fb87f036b4e089
    supported_archs     x86_64 i386 ppc

    set makefile	"Makefile-97"

    patchfiles-delete   ld64-133-no-CrashReporterClient.h.patch ld64-134-missing-include.patch ld64-136-i386-badAddress.patch PR-16935960.patch PR-16936488.patch
    patchfiles-append   ld64-97-no-LTO.patch ld64-97-ppc-branch-island.patch ld64-97-arm_types_PR38931.patch
} elseif {${os.major} < 10} {
    # XCode 4.2
    # This was the last ld64 release that supported linking ppc executables.
    version             127.2
    revision            6
    checksums           rmd160  8ee709341549a1944732daef6ebab7ef1acfcc6e \
                        sha256  97b75547b2bd761306ab3e15ae297f01e7ab9760b922bc657f4ef72e4e052142
    supported_archs     i386 x86_64

    set makefile	"Makefile-127"

    patchfiles-delete   ld64-133-no-CrashReporterClient.h.patch ld64-136-i386-badAddress.patch PR-16935960.patch PR-16936488.patch
    patchfiles-append   ld64-127-any-cctools.patch
} elseif {${cxxstdlib} eq "libstdc++"} {
    patchfiles-append   ld64-236-hash_set.patch
}

platform darwin 8 {
    pre-fetch {
        if {${llvm_version} != ""} {
            if {![file exists ${prefix}/bin/llvm-config-mp-${llvm_version}]} {
                ui_error "You must first install ld64 without llvm support to build llvm.  After llvm is installed, you can reinstall ld64 with the llvm variant."
                return -code error "You must first install ld64 without llvm support to build llvm.  After llvm is installed, you can reinstall ld64 with the llvm variant."
            }
        }
    }

    post-patch {
        reinplace "s:-Wl,-exported_symbol,__mh_execute_header::g" \
            ${worksrcpath}/Makefile
    }
}

compiler.blacklist gcc-4.0

post-extract {
    file copy ${filespath}/${makefile} ${worksrcpath}/Makefile
}

post-patch {
    reinplace "s|@@VERSION@@|${version}|g" \
        ${worksrcpath}/src/ld/Options.cpp

    if {${os.major} < 9} {
        # No CommonCrypto, use openssl
        reinplace "s:<CommonCrypto/CommonDigest.h>:<openssl/md5.h>:" \
            ${worksrcpath}/src/ld/MachOWriterExecutable.hpp
        reinplace "s:CC_MD5:MD5:" \
            ${worksrcpath}/src/ld/MachOWriterExecutable.hpp
    } 
}

configure {
    system "cd ${worksrcpath} && ${build.cmd} src/ld/configure.h"
}

build.args \
    CC="${configure.cc}" \
    CXX="${configure.cxx}" \
    OTHER_CPPFLAGS="${configure.cppflags}" \
    OTHER_CFLAGS="${configure.cflags} [get_canonical_archflags cc]" \
    OTHER_CXXFLAGS="${configure.cxxflags} ${cxx_stdlibflags} [get_canonical_archflags cxx]" \
    OTHER_LDFLAGS="${configure.ldflags} ${cxx_stdlibflags} [get_canonical_archflags ld]"

if {${os.major} >= 11} {
    build.args-append \
        RC_SUPPORTED_ARCHS="armv6 armv7 i386 x86_64"
}

destroot.args \
    PREFIX=${prefix}

pre-build {
    if {${llvm_version} != ""} {
        build.args-append LLVM_CONFIG=${prefix}/bin/llvm-config-mp-${llvm_version}
    }

    if {${os.major} < 9} {
        build.args-append OTHER_LDFLAGS_LD64=-lcrypto
    }    
}

post-destroot {
    # ${prefix}/bin/ld will always use the llvm we built against
    # ${prefix}/libexec/ld64/ld uses relative linking for use with the llvm ports
    file mkdir ${destroot}${prefix}/libexec/ld64
    file copy ${destroot}${prefix}/bin/ld ${destroot}${prefix}/libexec/ld64/ld

    if {${llvm_version} != ""} {
        system "install_name_tool -change ${prefix}/libexec/llvm-${llvm_version}/lib/libLTO.dylib \
                @executable_path/../lib/libLTO.dylib ${destroot}${prefix}/libexec/ld64/ld"
    }
}

livecheck.type          regex
livecheck.regex         "${name}-(\[\\d.\]+)"
