Linker Error when upgrading to XCTest - build

I've upgraded my project from sentest to xctest.
However I can't run tests because of the error:
building for iOS Simulator, but linking against dylib built for MacOSX file '/Applications/Xcode.app/Contents/Developer/Library/Frameworks/XCTest.framework/XCTest' for architecture x86_64
Clearly there is a problem with the reference to the XCTest library, but I'm not sure how to resolve it.
Several similar questions refer to the Framework Search Paths which I have as follows:
$(SDKROOT)/Developer/Library/Frameworks
$(inherited)
$(DEVELOPER_FRAMEWORKS_DIR)

Had to answer my own one. -1 to stackoverflow.
What I was missing that there is a different target for tests.
When I switched to the tests target (there's an up and down target selector on the project settings page top left) I noticed that the paths where screwed up with extra / chars and " chars.

Related

Cmake - cross compiling C++ project for iOS

There is no quite a good tutorial for Cmake integration for iOS projects. There are very few found on internet, but lags information. I have a C++ project and I want to cross compile it for my iOS project. I am really not an expert in C++ and Cmake topics. Though, I followed a blog which I was what exactly looking for.
As mentioned in the blog, I used toolchain to execute the Cmake command
mkdir build/ && cd build/ && cmake -G "Xcode" -DCMAKE_TOOLCHAIN_FILE=../ios-cmake/ios.toolchain.cmake ../../xxx-cpp -DPLATFORM=OS64COMBINED
And it generated the .xcodeproj in the build directory.
As instructed, I included the generated Xcode solution to my main iOS project and added the C++ project to "Frameworks, Libraries, and Embedded Content" and "Dependencies". Actually I wanted to build the library for iOS devices, so, as mentioned in the comment in the same blog, "The Xcode project generated from Cmake does not require any signing itself. Instead you include that generated Xcode project in another Xcode project that DOES have signing configured", my iOS project was already code signed. When I tried to build the project, I got build error saying "Signing for "xxx" requires a development team. Select a development team in the Signing & Capabilities editor."
Here are my observations
Build main iOS project for devices: BUILD FAILED
Signing for "xxx" requires a development team. Select a development team in the Signing & Capabilities editor.
Build main iOS project for simulator: BUILD FAILED
clang: error: no such file or directory: '/Users/user/Workspace/Cmake/Cmake Sample/build/lib/{C++ project}/core/Debug-iphonesimulator/libxxx.dylib'
Command Ld failed with a nonzero exit code
Build generated Xcode project for devices: BUILD FAILED
Choosing ALL_BUILD target
For .app targets: Bundle identifier is missing. xxx doesn't have a bundle identifier. Add a value for PRODUCT_BUNDLE_IDENTIFIER in the build settings editor.
For .dylib targets: Signing for "xxx" requires a development team. Select a development team in the Signing & Capabilities editor.
Build generated Xcode project for simulator: BUILD SUCCEEDED
Choosing ALL_BUILD target
I have no idea where to find the solution and I have already invested more time in analysing and doing many trial and errors. I really need some advise in cross compiling the Cpp libraries for iOS devices. Thanks in advance!!
Another gentleman is facing a same issue
There are multiple ways to solve this problem.
You sign the library manually everytime after building the library with iOS-cmake using codesign command by providing appropriate signing identity. This involves lot of manual work, so I would prefer you to go with approach
You can automatically sign all the included libraries using run script by adding below command codesign -f -s "$EXPANDED_CODE_SIGN_IDENTITY" "$BUILT_PRODUCTS_DIR/$FRAMEWORKS_FOLDER_PATH/<library_name>"
Here signing identity can be either "$EXPANDED_CODE_SIGN_IDENTITY" or "$CODE_SIGN_IDENTITY", it depends on your workspace structure if you are using cocoapods or not
The idea in the second approach is, xcode (xcodebuild) provides few environment variables while building the project, so we try to leverage the same signing identity which was used for signing the application to sign the library.
Also with respect to the way you are integrating the native library, I personally don't recommend doing that because if you change any setting in the generated xcode project, it would be disappeared if you generate the xcode project again
We have a similar dependency in our project, so we took the route of building the libraries in the command line (you can choose to build it using xcode generator or directly with cmake and make). Then we had to set few settings into our project
Adding the build dependency :- For this we have updated framework search paths build setting which points to the library which was generated before (this you can customize depending on arm64 [devices] or x86_64 [simulator])
Give that build dependency is sorted out, but in-order to have them at run time, we have to include these libraries in frameworks directory of .app folder, so we have added a run script to copy these libraries to frameworks directory. Using something like below
# Retrieve architecture type
ARCHITECTURE=""
if [ $NATIVE_ARCH == "i386" ] || [ $NATIVE_ARCH == "x86_64" ] ; then
ARCHITECTURE="x86_64"
else
ARCHITECTURE="arm64"
fi
# Retrieve build configuration
BUILD_CONFIG=""
if [ $CONFIGURATION == "Debug" ] ; then
BUILD_CONFIG="Debug"
else
BUILD_CONFIG="Release"
fi
# Copying library
cp -r <path_to_your_library> "$BUILT_PRODUCTS_DIR/$FRAMEWORKS_FOLDER_PATH/"
Path_to_your_library might vary depending on x86_64, arm64, debug and release builds.
The steps 1 and 2 are automatically taken care by xcode if you go with your route but it has lot of caveats, but configuring these settings is a one time activity which is smooth in day-to-day development process
If you maintain proper directory structure you can smoothly add them to the run script something like
Debug/arm64 for debug arm64 variant
Release/arm64 for release arm64 variant
Debug/x86_64 for debug x86_64 variant
Release/x86_64 for release x86_64 variant
Also make sure that you build framework instead of dylib, else Apple will throw warning and reject while uploading to appstore

Can't add dynamic frameworks to Command Line Tool

Goals
I added Command Line Tool target to an iOS app and linked with swift frameworks. (tested with Realm and SwiftyJSON)
Expected Results
Build Command Line tool with those libraries.
Actual Results
Xcode output:
dyld: Library not loaded: #rpath/libswiftCore.dylib
Referenced from: .../Xcode/DerivedData/.../Build/Products/Debug/RealmSwift.framework/Versions/A/RealmSwift
Reason: Incompatible library version: RealmSwift requires version 1.0.0 or later, but libswiftCore.dylib provides version 0.0.0
Steps to Reproduce
Create empty Swift Command Line Tool and link Realm frameworks
Code Sample
CommandLineTest.zip
Version of Frameworks and Tooling
Realm version: github "realm/realm-cocoa" "master"
SwiftyJSON version: github "acegreen/SwiftyJSON" "swift3"
Xcode version: 8 GM (which is on the App Store)
Dependency manager + version: Carthage 0.18
Command-line tools are best with static archives because everything is distributed as a single binary. Looking at Realm, I don't see that there is a static archive option. They do have an iOS static framework that I got compiling for macOS but that's not quite what you want. You might want to try playing with Realm's source a bit more to see if you can get it to produce a static archive.
In the mean time, as a workaround, you'll need to tell Xcode where to find the dylibs at runtime and also to install them somewhere.
In your Build Settings, go down to "Runpath Search Paths" and add "#rpath".
In Build Phases, under Copy Files, click the + button and add both Realm.framework and RealmSwift.framework from your project.
Because Realm is compiled with an older version of Swift, you also need to specify "Use Legacy Swift Language Version" in Build Settings.
That will get your project building and finding the Realm libraries but now it will fail to find libswiftCore.dylib. That's because normally command-line tools are statically linked with the Swift library but as soon as you add a framework/dylib, the linker no longer includes the static version.
Go back to Build Phases, Copy Files, and add the following:
libswiftObjectiveC.dylib
libswiftIOKit.dylib
libswiftFoundation.dylib
libswiftDispatch.dylib
libswiftDarwin.dylib
libswiftCoreGraphics.dylib
libswiftCore.dylib
You can find them inside your Xcode installation and then ./Contents/Developer/Toolchains/Swift_2.3.xctoolchain/usr/lib/swift/macosx/
WARNING: Keep in mind that you will need to distribute the frameworks and the dylibs with your command-line tool and they will need to be in the same directory as the tool. You can put them somewhere else on the system by specifying a different runpath but you'll still need them distributed with your tool.
The nice thing about a .app bundle is that it gives you a place to put this stuff and users can just drag-and-drop it to install it. If you could get a static archive version of Realm, you could distribute everything in one binary.

Xcode Cannot find a Static Library During Linking even though it is a referenced product

I have two pre-existing Xcode workspaces. One, Parent.xcworkspace is an iOS application. The other SomeChild.xcworkspace is a C++ static library. The SomeChild workspace is in a git submodule of the Parent workspace.
I want to take one project from the SomeChild workspace and add it to the Parent.xcworkspace so that the code is built and statically linked when dependent projects in the Parent workspace are built.
It almost works, but at link time when building the Parent workspace iOS application the linker emits
clang: error: no such file or directory: '/Users/me/Library/Developer/Xcode/DerivedData/Parent-hagqyrdsdfsdfsdfphgbsolz/Build/Products/Debug-iphonesimulator/libSomeChild.a'
It's true, libSomeChild.a does not exist in the directory ending with -iphonesimulator/
libSomeChild does exist in
/Users/me/Library/Developer/Xcode/DerivedData/Parent-hagqyrdsdfsdfsdfphgbsolz/Build/Products/Debug/
So, in summary: The lib is being output to a path that is almost the same as in the error, except without the -iphonesimulator suffix.
How do I fix this build?
Edit:
This question is very similar but doesn't really have an answer
Xcode 6.1 static library .a for iOS not generated
This isn't a complete answer because I didn't solve the problem. But the root cause seems to be that the child project is building for x86_64 architectures but the iOS project requires the arm architectures.
In my case it was simpler to add the child code files to the iOS target instead of trying to build the child xcproj and link to the static library.

Installing OpenCV 3 on Mac OS X as a framework

I wanted to make an app on OS X El Capitan using OpenCV. I decided to use the latest version, version 3.0.0 released on June 4th, 2015. I had installed version 2.4.x using brew, but since version 3 now has a build script for osx that builds a framework, I wanted to use that method.
After downloading version 3 from the OpenCV.org, I opened a terminal window in the opencv-3.0.0 directory and executed the build_framework.py script as follows:
platforms/osx/build_framework.py osx
(The osx argument tells the script to make a directory named osx to output the framework there)
Everything built without a hitch so I then added the framework built in the osx directory to my project.
Much to my surprise my project would not build without errors. First of all were the two following problems. Here is a screenshot of the first:
If the first problem did not show up, the #ifndef __cplusplus # error for each header file in the opencv2.framework would get triggered.
It turns out that problem was that the C++ headers need to be called before the Objective-C headers, so I added the following to a PCH file to the project:
You can actually add this code to the header file that need the opencv.hpp header file instead of make a PCH file for the project. You should also be sure to say #include and not #import, but they should both work.
Once I figured out those problems I was still stuck with 39 undefined symbols for architecture x86_64.
At first I thought the framework was not including the x86_64 versions, but a quick check revealed that it included both i386 and x86_64 versions of the object files and that my Project settings were all correct.
Next I looked up the names of some of the undefined symbols and found that they were part of a project named OpenCL. OpenCL is supposed to accelerate some of the functions and was included in opencv3. At first I thought that the module was not getting built, but after reading through the build_framework.py build script I found that it was getting its settings from the CMakeLists.txt file. Reading this showed that following OpenCL flags:
WITH_OPENCL
WITH_OPENCLAMDFFT
WITH_OPENCLAMDBLAS
were being set
A little more reading lead me to believe that Mac OS X El Capitan is not compatible with OpenCL, as it appears there needs to be kernel support. So I changed the CMakeLists.txt file to not build OpenCL by adding "AND NOT APPLE"
WITH_OPENCL
WITH_OPENCLAMDFFT
WITH_OPENCLAMDBLAS
After the changes to the CMakeLists.txt file and building the framework again, my program was able to link with opencv2.framework (not sure why they still call it opencv2 instead of opencv3) and run.
It took me more time than I would like to admit, so I thought I would share my experience here in the hopes that it save someone else all the frustration getting OpenCV 3 working with their Mac OS X app. Cheers!
After nearly 2 years, I encountered the same problem. However, I found a more decent solution.
Contrary to your thought, macOS actually is compatible with OpenCL, although it is not linked into the OpenCV2.framework. I tried to link my binary with liblapack.tbd, libcblas.tbd and OpenCL.framework before I link opencv2.framework and it works like a charm.
So just go to the Project Settings -> Build Phases -> Link Binary With Libraries and add the following:
Link Binary With Libraries section

Following a Lynda.com c++ tutorial and having problems setting up paths on Eclipse (OSX 10.9.3)

I am currently learning C++ using Lynda.com tutorials, I am a complete beginner and am following the tutorials on how to set up Eclipse on my Mac.
When I initially run the version-test.cpp program provided, it runs fine with the expected output (GCC version 4.2.1)
The tutorial requires my Mac to be running GCC version 4.7.0 or above and it explains how to upgrade GCC. The tutorial instructs me to save the updated GCC files within my home directory within the folder hpc-gcc and then follows on to explain the method to set my PATHs to find this folder.
Now when I run the version-test.cpp program it fails with the following error
dyld: Library not loaded: /usr/local/lib/libmpc.3.dylib
Referenced from: /Users/gary/hpc-gcc/bin/../libexec/gcc/x86_64-apple-darwin13.1.0/4.9.0/cc1plus
Reason: image not found
So from this message I can see that the system cannot find the required files within /usr/local/lib.
I am able to copy the files from hpc-gcc/bin to /usr/local/lib and have the program compile and run correctly but I am hoping to find out why Eclipse cannot read the required files directly from ~/hpc-gcc/bin
I have spent the last 2 hours searching forums and search engines for the answer but I am no further forward. I realise I can simply have the GCC files within /usr/local/lib and it will work but I want to understand where I am going wrong.
Solved.
You need to go into the properties of the Working folder (if you are following the lynda.com program you will understand the working folder) and under C/C++ Build -> Environment menu (Where we added in the LIBRARY_PATH, PATH, AND CPATH variables) and add in DYLD_LIBRARY_PATH with a value of ${HOME}/hpc-gcc/lib.
Remember the C/C++ Build "menus" are for build and debug, so the project is not able to find the library for the building process.
And you will be good to go.