Linker (ld) fails to produce output file? - xcode

I'm getting a strange error while trying to build Chromium on Mac. I've tracked the problem down to the following block of code, which is in a script called adjust_visibility.sh.
NEW_OBJECT="${OBJECT}.new"
ld -o "${NEW_OBJECT}" -r "${OBJECT}" \
-exported_symbols_list /dev/null -keep_private_externs
mv "${NEW_OBJECT}" "${OBJECT}"
The script fails on the last line, where mv claims that the file ${NEW_OBJECT} doesn't exist. ${NEW_OBJECT} should have been created by the linker command right above, but for some reason this isn't happening. The linker doesn't produce the new file, but it also doesn't print any errors or warnings.
I know there's no problem with the linker itself -- when I run similar commands in the terminal they work fine. The problem must have something to do with the environment that the script's executing in.
Does anyone have any idea why this linker command isn't working properly?

Related

Linker fails in sandbox when running through Bazel but works when sandboxed command is executed from the command line

I'm trying to get our cross-toolchain (standard Yocto toolchain) working with Bazel. I followed the instructions on https://github.com/bazelbuild/bazel/wiki/Building-with-a-custom-toolchain but the linker fails every time I try to build a simple test program. It says
external/toolchain_e6500/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc64-fsl-linux/../../libexec/powerpc64-fsl-linux/gcc/powerpc64-fsl-linux/4.9.2/real-ld: cannot find /lib64/libc.so.6
external/toolchain_e6500/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc64-fsl-linux/../../libexec/powerpc64-fsl-linux/gcc/powerpc64-fsl-linux/4.9.2/real-ld: cannot find /usr/lib64/libc_nonshared.a
external/toolchain_e6500/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc64-fsl-linux/../../libexec/powerpc64-fsl-linux/gcc/powerpc64-fsl-linux/4.9.2/real-ld: cannot find /lib64/ld64.so.1
The sysroot is set properly. When running the linker command outside of the sandbox (e.g. with --spawn_strategy=standalone or just manually) it works always. The strange thing is that when I use --debug_sandbox and run the emitted command from the command line, it works, too.
I've been debugging this issue for two days now, including straceing the Bazel daemon and comparing the real-ld input but I didn't find anything suspicious.
There must be a difference between the execution environments but I'm out of ideas now. Here is the failing command as printed by --debug_sandbox:
(cd /home/sick/.cache/bazel/_bazel_sick/2a7ae5e27644389520091aa03d045c73/execroot/__main__ && \
exec env - \
PATH=/home/sick/bin:/home/sick/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/sick/bin \
PWD=/proc/self/cwd \
TMPDIR=/tmp \
/home/sick/.cache/bazel/_bazel_sick/2a7ae5e27644389520091aa03d045c73/execroot/__main__/_bin/linux-sandbox -t 15 -w /home/sick/.cache/bazel/_bazel_sick/2a7ae5e27644389520091aa03d045c73/sandbox/linux-sandbox/2/execroot/__main__ -w /tmp -w /dev/shm -D -- tools/compiler_e6500/e6500_gcc/powerpc64-fsl-linux-gcc -o bazel-out/e6500-fastbuild/bin/test '--sysroot=external/toolchain_e6500/sysroots/ppc64e6500-fsl-linux' -no-canonical-prefixes -pie -Wl,-z,relro,-z,now -Wl,-S -Wl,#bazel-out/e6500-fastbuild/bin/test-2.params)
You can take a look at the workspace here https://github.com/jasal82/bazel-cross-eval
I can provide the toolchain if needed.
UPDATE 2018-09-25
I did some more investigation after reading the answer regarding the linker script below. Section 4.4.2 in this manual says that
In case a sysroot prefix is configured, and the filename starts with
the / character, and the script being processed was located inside the
sysroot prefix, the filename will be looked for in the sysroot prefix.
Otherwise, the linker will try to open the file in the current
directory.
Obviously the script is not being considered to be located inside the sysroot prefix by ld and thus used literally (i.e. resolved relative to the current dir, probably the sandbox root). That would explain the observed behavior. However, I still don't understand why it does not happen when I run the command manually, i.e. not through the Bazel daemon.
Could this be related to the relative sysroot path used in the CROSSTOOL file? As far as I understood you cannot specify an absolute path to the sysroot due to the sandboxing. What is the recommended way to handle this in Bazel? I would like to avoid having to patch the toolchain.
Have a look at lib.so in your sysroot. It probably looks something like this:
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc_nonshared.a AS_NEEDED ( /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 )
Change the paths in it to be relative to the directory that libc.so is in. You'll have to perform a similar operation on libm.so and libpthread.so.
The GNU linkers resolve symlinks before evaluating whether a script is within the sysroot. The current Bazel Linux sandbox implementation makes a symlink farm of all an action's inputs. Thus, the libc.so.6 linker script is detected as being in the sysroot outside the sandbox but not within the sandbox.

getting error while executing code of assembly language on nasm Ubuntu Terminal

I tried it so many time, but while executing the assembly language code on terminal through nasm to make an executable file, then I stuck here, any one can help me to get out of this problem..
i tried these command line to execute it.
nasm -f elf helloworld.asm
to make run the file then i want to make an object file to execute it so I used this command
id -s -o helloworld helloworld.o
but the second command is not running because there are no command options such as -s or -o.
Please help me and follow the image thanks

figure out ld command arguments from xcode run script build phase

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?
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.

PATH variable when calling make from XCode

For an iPad application I need to transform some CoffeeScript files into JavaScript files before bundling them with the application.
I tried to add a Makefile to my XCode project with the following code:
MANUAL_ROOT=IOS12BSH/manual
SCRIPTS_ROOT=$(MANUAL_ROOT)/scripts
COFFEE_SOURCES=$(SCRIPTS_ROOT)/*.coffee $(SCRIPTS_ROOT)/guides/*.coffee
JAVASCRIPT_TARGETS=$(COFFEE_SOURCES:.coffee=.js)
all: build
build: coffeescript
clean: clean_coffeescript
coffeescript: $(JAVASCRIPT_TARGETS)
clean_coffeescript:
rm -f $(JAVASCRIPT_TARGETS)
$(JAVASCRIPT_TARGETS): $(COFFEE_SOURCES)
coffee -c $(COFFEE_SOURCES)
Running this Makefile from the shell works without problems. However, after I added the Makefile as a target in XCode, I ran into problems.
The following error was produced by the Makefile:
coffee -c IOS12BSH/manual/scripts/*.coffee IOS12BSH/manual/scripts/guides/*.coffee
/bin/sh: coffee: command not found
make: *** [IOS12BSH/manual/scripts/*.js] Error 127
Command /Applications/Xcode.app/Contents/Developer/usr/bin/make failed with exit code 2
That is strange, as the coffee command is installed on my machine (it is installed under /opt/local/bin/coffee and /opt/local/bin is added to my $PATH in ~/.profile).
So I added an echo $(PATH) to my Makefile and it seems that the $PATH is different, when the Makefile is executed by XCode. XCode does not seem to read the settings from ~/.profile and therefore /opt/local/bin is not in $PATH.
What is the reason for this and how can I fix this, so that the coffee command is found?
Well, it seems that programs started via the Dock or Spotlight do not execute .profile and therefore $PATH is not set correctly.
So one way would be to set the $PATH in ~/.MacOSX/environments.plist. That works then apparently, but you will need a restart before it works.
Another way is to start XCode always from the command line with open projectfile.
This answer explains the problem in detail:
https://stackoverflow.com/a/14285335/751061
What ended up working best for me is just to launch Xcode from the command line.
I wrote a simple bash script that looks like:
source ~/.bash_profile # This is the trick that gets us our environment variables.
open -a "Xcode"
And then I call it from an Applescript Application just to give it a bundle I could put on the dock:
do shell script "~/xcode_launcher"
Sourcing your profile is necessary in the bash script, because running a script from Applescript doesn't ever source from a profile, so you still wouldn't have your default environment variables.
SAme thing with ant command. It works on terminal, not if Xcode have to do it. Only way to got it work: sudo open project.xcodeproj in terminal.

Eclipse CDT: pkg-config indexing

I`m developing a application using gtkmm with eclipse. While I could have setup gtkmm include paths and linking options manually, i decided to let pkg-config do the work because of the huge number of referenced projects. This was quite easy as adding the appropriate pkg-config command to the compiler invocation worked just fine because one can simply use the
`...`
shell substitution since eclipse will generate a makefile which is then executed.
Setting up the indexer right isnt that easy though. Instead of executing shell script in a interpreter, eclipse executes the compiler directly and pass command line arguments directly without substituting them before.
How can one execute shell script when executing the indexer?
The solution is to execute the bash interpreter with the -c flag directly instead of executing g++.
For the scenario described in the question the configurations are as followed:
Compiler invocation command
bash
Compiler invocation arguements
-c "g++ `pkg-config gtkmm-2.4 --cflags` -E -P -v -dD ${plugin_state_location}/specs.cpp"

Resources