How to intercept and remove a command line argument in bash
Asked Answered
I

3

12

After "upgrading" to Mavericks and Xcode 5, I have a variety of minor problems to deal with to make Xcode compile some of my older projects.

It appears that Xcode is passing a new argument to the ld linker, and there's really no stopping Xcode from doing so. An older version of ld, which I need for a variety of reasons, gives an error when seeing an argument it doesn't know (so my projects cannot compile).

What I need is a thin wrapper over my older version of ld to remove the "bad" arguments under certain circumstances. I thought that a bash shell script would be perfect, but bash is not my forte.

Here's what I've got:

# Look for conditions necessary to use older ld
... # (placeholder, obviously)

# Run older ld (pseudo condition)
if [ <old_ld_condition> ]; then
    ARGS=''
    for var in "$@"; do
        # Ignore known bad arguments
        if [ "$var" = '-dependency_info' ]; then
            continue
        fi

        ARGS="$ARGS $var"
    done

    /path/to/old/ld "$ARGS"
else
    /path/to/new/ld "$@"
fi

However, running /path/to/old/ld "$ARGS" results in ld interpreting the entire $ARGS string as one argument. Running /path/to/old/ld $ARGS results in ld receiving unescaped versions of previously escaped strings.

Clearly, I'm misunderstanding something about the nature of $@, how to manipulate it, and how to pass that manipulation to the older ld. Thanks everyone.

Izzard answered 4/2, 2014 at 2:43 Comment(2)
You can select the command-line toolset version from within Xcode, I do not know if that will help you or not? Generally unless you did a complete fresh install, the old SDKs and command-line toolset versions will coexist.Moony
These projects are actual Xcode .xcodeproj files, and unfortunately I'm not in the position to bring them over to a command-line build process (e.g. make). Thanks for the suggestion though.Izzard
N
18

This should work:

# Run older ld (pseudo condition)
if [[ <old_ld_condition> ]]; then
    args=()
    for var; do
        # Ignore known bad arguments
        [[ $var != '-dependency_info' ]] && args+=("$var")
    done

    /path/to/old/ld "${args[@]}"
else
    /path/to/new/ld "$@"
fi
Nilgai answered 4/2, 2014 at 3:38 Comment(0)
S
5

You should use Bash Arrays if you really want to stay with bash:

declare -a ARGS
for var in "$@"; do
    # Ignore known bad arguments
    if [ "$var" = '-dependency_info' ]; then
        continue
    fi
    ARGS[${#ARGS[@]}]="$var"
done

now "${ARGS[@]}" can be used just as "$@". man bash for more information.

Selfaggrandizement answered 4/2, 2014 at 3:27 Comment(0)
C
0

So what about having this?

#!/bin/bash

if [ <old_ld_condition> ]; then
    /path/to/old/ld "${@//-dependency_info/}"
else
    /path/to/new/ld "$@"
fi
Clubwoman answered 3/9 at 13:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.