8

How can I determine what will be the arguments of the ld command in the build process from inside a script running as "run script build phase"?

I was looking at xcodebuild -dry-run as an option, but then I need to understand what should be the arguments I supply it.

Any idea for a robust solution?

EDIT:

It seems that xcodebuild doesn't support LD and LDPLUSPLUS when the project includes swift source code. So the solution that @fpotter offered doesn't work on project with swift.

Any thoughts?

ekeren
  • 3,408
  • 3
  • 35
  • 55

1 Answers1

5

Xcode doesn't expose a nice way to do this. In a Run Script build phase, all you have to work with are the Xcode build settings provided to you in the environment.

If you really need the entire argument list to ld, there's a hack you can use. With the LD and LDPLUSPLUS build settings, you can make Xcode call a script of your own instead of the real ld. From that script, you could capture the args, call through to the real linker, and then do whatever post processing you like there rather than in a Run Script build phase.

Here's how you could do that:

Create an .xcconfig for your target.

It should look like this:

LD = $(SRCROOT)/ld-wrapper/clang
LDPLUSPLUS = $(SRCROOT)/ld-wrapper/clang++

SRCROOT points to your project's directory. The LDPLUSPLUS line is only required if your app has C++ or ObjC++ code. If you don't want to create an xcconfig, you can also add these as User-Defined build settings via the Xcode UI.

Create wrapper scripts for Xcode to call.

Install a script like this at <your project root>/ld-wrapper/wrapper.sh:

#!/bin/bash

set -o errexit

# Choose which clang to run (clang or clang++) depending on how we're invoked.
# If we're invoked via the 'clang' link, we'll run 'clang'.  If we're invoked
# via the 'clang++' link, we'll run 'clang++'.
CLANG_PATH="$DEVELOPER_DIR"/Toolchains/XcodeDefault.xctoolchain/usr/bin/$(basename "$0")

"$CLANG_PATH" "$@"

echo "clang args: $@"
echo "do any post processing here."

Create symlinks for the wrapper script for clang and clang++:

cd <project root>/ld-wrapper
ln -s wrapper.sh clang
ln -s wrapper.sh clang++

That's it. It's ugly, but it works.

fpotter
  • 463
  • 2
  • 5
  • Thanks @fpotter, glad to be the first one you answer in SO. I think that the LD variable approach is interesting. Why can't I parse the result of `xcodebuild -dry-run`? – ekeren Feb 03 '15 at 12:13
  • You certainly could parse the output of `dry-run`. But, calling xcodebuild with `dry-run` from within a Run Script would be slow. Even if only doing a dry-run, xcodebuild spends a lot of time opening your projects and preparing to build. On really large projects, it could take more than a minute just to do a dry-run. – fpotter Feb 03 '15 at 19:16
  • 1
    do you have any clue why xcode disregards LD and LDPLUSPLUS variable when the project contains swift code? – ekeren Mar 10 '15 at 15:07