Xcode 7.1.1 - fatal error : lipo: can't open input file - build-error

I'm getting fatal error: lipo: can't open input file: /Users/.../libABC.a (No such file or directory)
I've cross-checked this file exists in same location after checking with 'Show in Finder'
I'm getting this error while building library. I've tried below solutions but didn't worked:
1. Build Active architecture only - YES/NO
2. Enable BitCode - YES/NO
3. Clean / Clean Build Folder, Quit simulator.
Any other fix?

Xcode-Build phases
check the scripts wheacher contain codes or not look like this to Removex86_64Andi386Framework:
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[#]}"
rm "${EXTRACTED_ARCHS[#]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done
delete the shell script and clean the project then run again.

Related

CMake incremental compilation through toolchain upgrade

I am trying to find a way to enable incremental compilation with CMake through a toolchain upgrade. Here is the problematic scenario :
Branch main uses g++-9 (using CMAKE_CXX_COMPILER=g++-9)
A new branch uses g++-10 (using CMAKE_CXX_COMPILER=g++-10)
Commits are happening on both branches
Incremental builds on one branch work fine
Switching to the other branch and explicitly invoking CMake fails
My question is the following : I'm looking for the proper way to make the invocation of CMake succeed and rebuild all the project from scratch when a toolchain change happens.
Here is a script that will make it quick and easy to reproduce the problem. This script requires Docker. It will create folders Sources and Build at the location where it is executed to avoid littering your filesystem. It then creates Dockerfiles to build docker containers with both g++ and cmake. It then creates a dummy Hello World C++ CMake project. Finally, it creates a folder for build artifacts and then executes the build with g++-9 and then g++-10. The second build fails because CMake generates an error.
#!/bin/bash
set -e
mkdir -p Sources
mkdir -p Build
# Creates a script that will be executed inside the docker container to perform builds
cat << EOF > Sources/Compile.sh
cd /Build \
&& cmake /Sources \
&& make \
&& ./IncrementalBuild
EOF
# Creates a Dockerfile that will be used to have both gcc-9 and cmake
cat << EOF > Sources/Dockerfile-gcc9
FROM gcc:9
RUN apt-get update && apt-get install -y cmake
RUN ln -s /usr/local/bin/g++ /usr/local/bin/g++-9
ADD Compile.sh /Compile.sh
RUN chmod +x /Compile.sh
ENTRYPOINT /Compile.sh
EOF
# Creates a Dockerfile that will be used to have both gcc-10 and cmake
cat << EOF > Sources/Dockerfile-gcc10
FROM gcc:10
RUN apt-get update && apt-get install -y cmake
RUN ln -s /usr/local/bin/g++ /usr/local/bin/g++-10
ADD Compile.sh /Compile.sh
RUN chmod +x /Compile.sh
ENTRYPOINT /Compile.sh
EOF
# Creates a dummy C++ program that will be compiled
cat << EOF > Sources/main.cpp
#include <iostream>
int main()
{
std::cout << "Hello World!\n";
}
EOF
# Creates CMakeLists.txt that will be used to compile the dummy C++ program
cat << EOF > Sources/CMakeLists.txt
cmake_minimum_required(VERSION 3.9)
project(IncrementalBuild CXX)
add_executable(IncrementalBuild main.cpp)
set_target_properties(IncrementalBuild PROPERTIES CXX_STANDARD 17)
EOF
# Build the docker images with both Dockerfiles created earlier
docker build -t cmake-gcc:9 -f Sources/Dockerfile-gcc9 Sources
docker build -t cmake-gcc:10 -f Sources/Dockerfile-gcc10 Sources
# Run a build with g++-9
echo ""
echo "### Compiling with g++-9 and then running the result..."
docker run --rm --user $(id -u):$(id -g) -v $(pwd)/Sources:/Sources -v $(pwd)/Build:/Build -e CXX=g++-9 cmake-gcc:9
echo ""
# Run a build with g++-10
echo "### Compiling with g++-10 and then running the result..."
docker run --rm --user $(id -u):$(id -g) -v $(pwd)/Sources:/Sources -v $(pwd)/Build:/Build -e CXX=g++-10 cmake-gcc:10
echo ""
# Print success if we reach this point
echo "SUCCESS!"
I'm looking for the proper way to make the invocation of CMake succeed and rebuild all the project from scratch when a toolchain change happens.
The proper way is to use a fresh binary directory. Either remove the binary directory when changing and let it recreate or just use a separate different directory for each toolchain.
Use Build/gcc10 binary directory for gcc10 build and Build/gcc9 for gcc9 builds.
No need to cd Build and mkdir with nowadays cmake - use cmake -S. -BBuild. Also do not use make - prefer cmake --build Build to let you switch generator later.
"If you change the toolchain, you should start with a fresh build. There are too many things that assume the toolchain doesn’t change and while you may be able to find workarounds which appear to work, I recommend you always use a fresh build tree for a different toolchain. This same logic also applies if you update the existing toolchain in-place (e.g. you update to a newer version of GCC on Linux, a newer version of Xcode on macOS, etc.). CMake queries compiler capabilities and caches the results. If you change the toolchain in a way that CMake can’t catch, then you end up with stale cached capabilities being used for the new/updated toolchain. Please don’t do that." - Craig Scott
So essentially I don't think it's possible. You just need to blow away your build. The best thing you can do is alert users if CMake isn't doing it for you.
Perhaps reply on this also:
https://discourse.cmake.org/t/how-to-change-toolchain-without-breaking-developer-workflows/1166
Or start another discourse.

cmake build dir stored in ramdisk and symlinked to project causes make to fail

I'm trying to speed up build process using ramdisk for build directory.
I've created ramdisk:
sudo mount -t tmpfs -o size=1024m tmpfs /mnt/ramdisk
On ramdisk I've created build dir:
mkdir -p /mnt/ramdisk/rust/hello3/build/
Then I've symlinked ramdisk build dir to project in which I want to use this directory:
cd /home/wakatana/rust/hello3
ln -s /mnt/ramdisk/rust/hello3/build/ build
After this I did classic combo for building project:
cd /home/wakatana/rust/hello3/build
cmake ..
make
But above command does not worked because relative path (cmake ..) is translated to /mnt/ramdisk/rust/hello3 and not to /home/wakatana/rust/hello3/ (I suspect that this is whole problem)
So instead of classic combo I did a little bit modified combo (when build dir is not symlinked this works):
cd /home/wakatana/rust/hello3/build
cmake /home/wakatana/rust/hello3
make
But this ends up with errors during make phase:
-- Configuring done
-- Generating done
-- Build files have been written to: /home/wakatana/rust/hello3/build
make[2]: *** No rule to make target '../src/lib.rs', needed by 'src/x86_64-unknown-linux-gnu/debug/libtest_lib.a'. Stop.
CMakeFiles/Makefile2:122: recipe for target 'src/CMakeFiles/test-lib_target.dir/all' failed
make[1]: *** [src/CMakeFiles/test-lib_target.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
Is it possible to somehow tell to cmake/make to deal symlinks correctly?
Just save yourself the trouble of creating symlinks and work on the ram disc:
cmake -S /home/wakatana/rust/hello3 -B /mnt/ramdisk/rust/hello3/build/
cmake --build /mnt/ramdisk/rust/hello3/build/
You could create the symlink, and then work from parent dir:
ln -s /mnt/ramdisk/rust/hello3/build/
cd /home/wakatana/rust/hello3
cmake -S . -B build
cmake --build build
# or expand the symlink before cmake has to:
cmake -S . -B "$(readlink -f "./build")"
cmake --build "$(readlink -f "./build")"
The other way is to rebind your RAM disk into your project tree instead of symlinking:
$ cd /home/wakatana/rust/hello3
$ mkdir -p build
$ mount --bind /mnt/ramdisk/rust/hello3/build build

Clang: Using Cmake to build a compile_commands.json for my project

I'm trying to create the compile_commands.json file by following these instructions: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
I don't see any option on the docs that allows be to build the compile_commands.json file against my own code. The command that I use when I follow the doc builds the json file, but the contents of the file contains files/directories in the llvm source directory. I'm assuming that if this file contains contents of my own project, then when I run run-clang-tidy.py (from here), then it will run clang-tidy against my own project.
So the question: How do I get Cmake to build the compile_commands.json to contain my own project?
It is unclear exactly what you want to achieve. In the link you provided, the author is building LLVM from source code, which is why the compilation database (compile_commands.json) refers to those sources.
In general to build the compilation database while building the source tree with CMake, you provide it with the -DCMAKE_EXPORT_COMPILE_COMMANDS=ON flag.
So, where the blog post you linked calls
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON path/to/llvm/sources
...you would exchange the path to the sources for your own source tree:
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON this/is/my/source/tree/path
...which should generate the json-file in the current (build) directory.
As in the article, you will probably want to symlink that file to the root of your source tree and then run your tools from there.
Here's a (very) simple build script that I wrote and sometimes use. Maybe it can be helpful to you (adjust to your own needs obviously). It should be run from the root of your source tree.
#!/usr/bin/env sh
type=Debug
if ! [[ -z "$1" ]]; then
type="$1"
mkdir -p build/$type
shift
fi
# Configure build
cmake -S . -B build/$type -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=$type .
# Build
cmake --build build/$type --parallel 4 --config $type "$#"
ln -fs build/$type/compile_commands.json .

wxWidgets library build garbled file name in linker

On attempting to build wxWidgets 3.1.0 libraries, I am getting this error
ar: gcc_mswu\moolib_fontmap.o: No such file or directory
A file does exists with a slightly different spelling
Directory of C:\Users\James\code\wxwidgets-3.1.0\build\msw\gcc_mswu
2017-01-05 02:01 PM 98,886 monolib_fontmap.o
It looks like a typo in the makefile, or like a letter is missed reading the makefile. Is that possible?
Except: if I redirect the console output to a file and open in an editor , the correct spelling shows up:
So the correct command is going to the linker, but the linker is looking for a garbled filename!
Here is the complete recipe for what I am doing:
Download wxWidgets source code from https://github.com/wxWidgets/wxWidgets/releases/download/v3.1.0/wxWidgets-3.1.0.7z
Unpack to a folder. On my system, I use C:\Users\James\code\wxwidgets-3.1.0
Open a command window.
cd to the code::blocks mingw folder. On my system this is C:\Program Files (x86)\CodeBlocks16\MinGW
Type mingwvars.bat
cd to wxwidgets folder. On my system C:\Users\James\code\wxwidgets-3.1.0
cd to ./build/msw
Type mingw32-make SHELL=CMD.exe -j4 -f makefile.gcc BUILD=release UNICODE=1 SHARED=0 MONOLITHIC=1
This seems to be the same problem as the one mentioned in the wiki. Apparently there is a bug in mingw32-make with very long command lines which makes it (sometimes?) eat characters in them...
Yes. Applying the recipe in the link you posted fixed the problem. Here are the details:
modify makefile.gcc as following:
From:
ifeq ($(MONOLITHIC),1)
ifeq ($(SHARED),0)
$(LIBDIRNAME)\libwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR).a: $(MONOLIB_OBJECTS)
if exist $# del $#
ar rcu $# $(MONOLIB_OBJECTS)
ranlib $#
endif
endif
Replace second occurence of $(MONOLIB_OBJECTS) with gcc_mswu\monolib*.o:
ifeq ($(MONOLITHIC),1)
ifeq ($(SHARED),0)
$(LIBDIRNAME)\libwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR).a: $(MONOLIB_OBJECTS)
if exist $# del $#
ar rcu $# gcc_mswu\\monolib*.o
ranlib $#
endif
endif

Compiling libical

I would like to compile libical and add it to my Xcode project.
I have read the README file and run the following commands in Terminal.app:
./configure
and
./configure --prefix=/proj/local/
Am I supposed to get compiled .a files somewhere that I can drag and drop into my project?
I am the person who originally created those build scripts located here...
http://code.google.com/p/mwiphonesdk/source/browse/trunk/iMADE/PrepTasks/05+Event+Calendar/Packers+Schedule/libical/build+scripts/
I have now updated the scripts to work with the latest iOS 6/Xcode 4.5 toolset. It is quite different and I have set it to use Clang. I did what I could to make this script adapt to new SDK releases.
http://www.smallsharptools.com/downloads/libical/
The scripts should be placed in the root of the libical folder and run from there. The main script runs the other 2 scripts to build the armv7 and armv7s binaries and then uses xcrun to run lipo for iphoneos to combine these binaries into a fat binary which can be used for an iOS project.
There are some refactorings which could easily be done but I have already spent a ton of time on it already. I hope this helps you make use of the library.
#!/bin/sh
# SEE: http://www.smallsharptools.com/downloads/libical/
PATH="`xcode-select -print-path`/usr/bin:/usr/bin:/bin"
# set the prefix
PREFIX=${HOME}/Library/libical
OUTPUTDIR=../libical-build
export ARCH=armv7
# Select the desired iPhone SDK
export SDKVER="6.0"
export DEVROOT=`xcode-select --print-path`
export SDKROOT=$DEVROOT/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${SDKVER}.sdk
export IOSROOT=$DEVROOT/Platforms/iPhoneOS.platform
# Includes
# find $DEVROOT -type d -name include|grep -i iphone|grep -i arm-apple-darwin|grep -vi install-tools|grep -vi simulator
# $SDKROOT/usr/include
# $DEVROOT/Platforms/iPhoneOS.platform/Developer/usr/llvm-gcc-4.2/lib/gcc/arm-apple-darwin10/4.2.1/include
if [ ! -d $DEVROOT ]
then
echo "Developer Root not found! - $DEVROOT"
exit
fi
echo "DEVROOT = $DEVROOT"
if [ ! -d $SDKROOT ]
then
echo "SDK Root not found! - $SDKROOT"
exit
fi
echo "SDKROOT = $SDKROOT"
if [ ! -d $IOSROOT ]
then
echo "iOS Root not found! - $IOSROOT"
exit
fi
echo "IOSROOT = $IOSROOT"
# finding ld
# find $DEVROOT -type f -name ld|grep -i iphone
# Set up relevant environment variables
export CPPFLAGS="-arch $ARCH -I$SDKROOT/usr/include -I$IOSROOT/Developer/usr/llvm-gcc-4.2/lib/gcc/arm-apple-darwin10/4.2.1/include"
export CFLAGS="$CPPFLAGS -pipe -no-cpp-precomp -isysroot $SDKROOT"
export CXXFLAGS="$CFLAGS"
export LDFLAGS="-L$SDKROOT/usr/lib/ -arch $ARCH"
export CLANG=$DEVROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
#export CC=$IOSROOT/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2
#export CXX=$IOSROOT/Developer/usr/bin/arm-apple-darwin10-llvm-g++-4.2
export CC=$CLANG
export CXX=$CLANG
export LD=$IOSROOT/Developer/usr/bin/ld
export AR=$IOSROOT/Developer/usr/bin/ar
export AS=$IOSROOT/Developer/usr/bin/as
export LIBTOOL=$IOSROOT/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/libtool
export STRIP=$IOSROOT/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/strip
export RANLIB=$IOSROOT/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib
HOST=arm-apple-darwin10
if [ ! -f $CC ]
then
echo "C Compiler not found! - $CC"
exit
fi
if [ ! -f $CXX ]
then
echo "C++ Compiler not found! - $CXX"
exit
fi
if [ ! -f $LD ]
then
echo "Linker not found! - $LD"
exit
fi
if [ -d $OUTPUTDIR/$ARCH ]
then
rm -rf $OUTPUTDIR/$ARCH
fi
find . -name \*.a -exec rm {} \;
make clean
./configure --prefix=$PREFIX --disable-dependency-tracking --host $HOST CXX=$CXX CC=$CC LD=$LD AR=$AR AS=$AS LIBTOOL=$LIBTOOL STRIP=$STRIP RANLIB=$RANLIB
make -j4
# copy the files to the arch folder
mkdir -p $OUTPUTDIR
mkdir -p $OUTPUTDIR/$ARCH
cp `find . -name \*.a` $OUTPUTDIR/$ARCH/
xcrun -sdk iphoneos lipo -info $OUTPUTDIR/$ARCH/*.a
echo $ARCH DONE
echo "See $OUTPUTDIR"
What you do is compile your libraries for both simulator and phone.
1.Make 2 new targets one for iphone one for simulator
2.compile
3.Take them and combine them with lipo.
This link will give you all the specific details.
How to make universal static libraries
Other answers to this question aren't helpful for specifically libical, because its configure script is finicky. You need to have a ton of environment variables right. These scripts have figured all them out for libical.
http://code.google.com/p/mwiphonesdk/source/browse/trunk/iMADE/PrepTasks/05+Event+Calendar/Packers+Schedule/libical/build+scripts/
Download the above scripts, and tweak the build_(platform).sh to find the right compilers and SDK folders. This will change depending on what you are targeting and how recent your Xcode developer tools are. Finding the right values should be pretty easy, just look in the same locations for what they are called on your system.
The output will be a fat ".a" files with binaries for the simulator and device.
In the case these files disappear, I've collected the truly important one (build_arm.sh, the cross-compile) below:
#!/bin/sh
# Created by Robert Carlsen on 15.07.2009.
# build an arm / i386 / x64 lib of standard linux project
#
# adopted from: http://latenitesoft.blogspot.com/2008/10/iphone-programming-tips-building-unix.html
#
# copied from: http://robertcarlsen.net/2009/07/15/cross-compiling-for-iphone-dev-884
#
# configured for libical
#
# Note:
# To run with the iPhone the assembly just be a Universal binary (FAT) with i386 arch for the simulator
# and arm arch for the iPhone hardware which has the arm processor.
# set the prefix
PREFIX=${HOME}/Library/libical
OUTPUTDIR=../libical-build
export ARCH=armv6
export GCCARCH=arm-apple-darwin9
export GCCVERSION=4.2.1
# Select the desired iPhone SDK
export DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer
export SDKROOT=$DEVROOT/SDKs/iPhoneOS3.1.2.sdk
if [ ! -d $DEVROOT ]
then
echo "Developer Root not found! - $DEVROOT"
exit
fi
echo "DEVROOT = $DEVROOT"
if [ ! -d $SDKROOT ]
then
echo "SDK Root not found! - $SDKROOT"
exit
fi
echo "SDKROOT = $SDKROOT"
# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT/usr/lib/gcc/$GCCARCH/$GCCVERSION/include/ -I$SDKROOT/usr/include/"
export CFLAGS="$CPPFLAGS -pipe -no-cpp-precomp -isysroot $SDKROOT"
export CPP="$DEVROOT/usr/bin/cpp $CPPFLAGS"
export CXXFLAGS="$CFLAGS"
export LDFLAGS="-L$SDKROOT/usr/lib/ "
CC=$DEVROOT/usr/bin/$GCCARCH-gcc-$GCCVERSION
CXX=$DEVROOT/usr/bin/$GCCARCH-g++-$GCCVERSION
HOST=arm-apple-darwin
if [ ! -f $CC ]
then
echo "C Compiler not found! - $CC"
exit
fi
if [ ! -f $CXX ]
then
echo "C++ Compiler not found! - $CXX"
exit
fi
# TODO: add custom flags as necessary for package
./configure --prefix=$PREFIX --disable-dependency-tracking CXX=$CXX CC=$CC LD=$DEVROOT/usr/bin/ld --host=$HOST
make -j4
# copy the files to the arch folder
mkdir -p $OUTPUTDIR
mkdir -p $OUTPUTDIR/$ARCH
cp `find . -name \*.a` $OUTPUTDIR/$ARCH/
lipo -info $OUTPUTDIR/$ARCH/*.a
echo $ARCH DONE
echo "See $OUTPUTDIR"
This question came up already a year ago, and it was solved. See Help on installing a library like libical into Xcode with hints for cross-compile and further link.