#! /usr/bin/env bash # Note: shouldn't be executed directly, src_exe and src_dir must be set. # Common link.exe driver that expects the VCBIN, SDKBIN, and LIB variables to # be set for the specific MSVC version/configuration. source "$src_dir/msvc-common/msvc-common" # Translate absolute paths from POSIX to Windows. Use bash array to store # arguments in case they contain spaces. # # This needs to be done for both certain option values and arguments. # Arguments are tricky in that unless we recognize every option, and option # may look a lot like an absolute POSIX path (e.g., /nologo). The heuristics # that we are going to use here is that if the argument starts with / and # contains at least one more /, then we consider it an argument. Otherwise -- # an options. We will also explicitly recognize certain options which may # not fit this scheme well. # # Note that link.exe /? is missing some options that are documented in MSDN. # args=() while [ $# -gt 0 ]; do case ${1^^} in # Uppercase for case-insensitive comparison. # @@ TODO: handle the rest/obscure options. # # @file # /ASSEMBLYLINKRESOURCE:filename # /ASSEMBLYMODULE:filename # /ASSEMBLYRESOURCE:filename[,[name][,PRIVATE]] # /BASE:{address[,size]|@filename,key} #+ /DEF:filename #+ /DEFAULTLIB:library #+ /DELAYLOAD:dll # /FASTGENPROFILE:PGD=filename|... # /GENPROFILE:PGD=filename|... #+ /IDLOUT:filename #+ /IMPLIB:filename #+ /KEYFILE:filename #+ /LIBPATH:dir #+ /MANIFESTFILE:filename #+ /MANIFESTINPUT:filename #+ /MAP:filename #+ /MIDL:@commandfile #+ /NODEFAULTLIB:library #+ /ORDER:@filename #+ /OUT:filename #+ /PDB:filename #+ /PDBALTPATH:filename #+ /PDBSTRIPPED:filename #+ /PGD:filename #+ /STUB:filename #+ /TLBOUT:filename # /USEPROFILE:PGD=filename #+ /WHOLEARCHIVE:library #+ /WINMDFILE:filename # /WINMDKEYCONTAINER:name #+ /WINMDKEYFILE:filename [/-]DEF:* | \ [/-]MAP:* | \ [/-]OUT:* | \ [/-]PDB:* | \ [/-]PGD:*) args=("${args[@]}" "$(split_translate 5 $1)") shift ;; [/-]STUB:*) args=("${args[@]}" "$(split_translate 6 $1)") shift ;; [/-]MIDL:@*) args=("${args[@]}" "$(split_translate 7 $1)") shift ;; [/-]IMPLIB:* | \ [/-]IDLOUT:* | \ [/-]TLBOUT:* | \ [/-]ORDER:@*) args=("${args[@]}" "$(split_translate 8 $1)") shift ;; [/-]KEYFILE:* | \ [/-]LIBPATH:*) args=("${args[@]}" "$(split_translate 9 $1)") shift ;; [/-]DELAYLOAD:* | \ [/-]WINMDFILE:*) args=("${args[@]}" "$(split_translate 11 $1)") shift ;; [/-]DEFAULTLIB:* | \ [/-]PDBALTPATH:*) args=("${args[@]}" "$(split_translate 12 $1)") shift ;; [/-]PDBSTRIPPED:*) args=("${args[@]}" "$(split_translate 13 $1)") shift ;; [/-]NODEFAULTLIB:* | \ [/-]MANIFESTFILE:* | \ [/-]WHOLEARCHIVE:* | \ [/-]WINMDKEYFILE:*) args=("${args[@]}" "$(split_translate 14 $1)") shift ;; [/-]MANIFESTINPUT:*) args=("${args[@]}" "$(split_translate 15 $1)") shift ;; # Handle other options with separate values. This makes sure we don't try # to path-translate them. # # Aren't any. # Handle other options with combined values that could possibly be # interpreted as paths. # # /ENTRY:symbol # /EXPORT:symbol # /INCLUDE:symbol # /KEYCONTAINER:name # /MANIFESTDEPENDENCY:manifest dependency # /MANIFESTUAC[:{NO|UAC fragment}] # /MAPINFO:{EXPORTS} # /MERGE:from=to # /SECTION:name,[[!]{DEKPRSW}][,ALIGN=#] # [/-]ENTRY:* | \ [/-]EXPORT:* | \ [/-]INCLUDE:* | \ [/-]KEYCONTAINER:* | \ [/-]MANIFESTDEPENDENCY:* | \ [/-]MANIFESTUAC:* | \ [/-]MAPINFO:* | \ [/-]MERGE:* | \ [/-]SECTION:* | \ [/-]REMOVE:*) args=("${args[@]}" "$1") shift ;; # Option or argument. # *) # If contains at least two slashes, treat it as a path. # if [[ "$1" == /*/* ]]; then args=("${args[@]}" "$(translate $1)") else args=("${args[@]}" "$1") fi shift ;; esac done export LIB # link.exe may need to run mt.exe which is in the SDK. # export WINEPATH="$VCBIN;$VCDLL;$SDKBIN;$WINEPATH" # link.exe always sends diagnostics to stdout. # msvc_exec 1 "$VCBIN\\link.exe" "${args[@]}"