make arm architecture c library in mac - iphone

I'm trying to make my own c library in Mac and include it to my iphone program.
The c code is simple , like this:
math.h:
int myPow2(int);
math.c:
#include "math.h"
int myPow2(int num) {
return num*num;
}
I search how to make the c library file ( .a or .lib ..etc) seems need to use gcc compiler (Is there other methods?) so I use this command:
gcc -c math.c -o math.o
ar rcs libmath.a math.o
And include it in iPhone Project. Now it has the problem when build xcode iphone project.
"file was built for unsupported file
format which is not the architecture
being linked"
I found some pages discuss about the problem, but no detail how to make the i386/arm architecture library. And I finally use this command to do it:
gcc -arch i386 -c math.c -o math.o
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-gcc-4.2.1 -c math.c -o math.o
I dont know if this method is correct? Or there has another method to do it?

What Bavarious said.
Add a new target to your project. When XCode asks you what template to use, chose "Static Library".
Add the files for the library to that target. Add the static library target as a dependency of your main executable target. Add the library that gets built to your main executable target. Voila!

Related

How can I combine two different dylib into a simple one for my Mac application?

I am trying to build ffmpeg for Intel and M1 platform for my application.
I got some problem, because when I put arm64 dylibs I got error that no x86_64 dylibs available. And I got arm64 dylibs not available when I put x86_64 dylibs.
Can I combine these two set of dylibs into a single one then I don't need to change the dylibs on different platform?
XCFramework or ??
Thank you.
Eric
You can create so called "fat" library. It is dylib which combine several architectures for one platform (MacOS in your case).
lipo -create libx86_64.dylib libarm64.dylib -output libcombined.dylib
Resulted dylib you can include in your project and it will compile fine for both archs.
If you want it more comfortable you can build framework from combined library and header folder
xcodebuild -create-xcframework -library libcombined.dylib -headers path/to/headers/directory -output output.xcframework
In this case you'll need to include only framework in your project

Clang: How to see contents of pcm-file - clang precompiled module

I am troubleshooting Swift build compile issues and want to see all C definitions inside pcm file (i.e. /.../sample-package/.build/aarch64-unknown-linux-android/debug/ModuleCache/3H5CVD7WO3N6R/SwiftGlibc-2G37BC3YW3KOQ.pcm).
How to do it? Is the any clang or llvm tool which can dump all symbols defined on C language side and included into precompiled clang module?
Using the command line tool strings
strings file.pcm
With Swift you can use:
swiftc -dump-pcm path/to/foo.pcm -target something ...
Where you do have to pass at least some of the flags you used to compile the module. In my testing you at least need -target and -sdk to be correct.
If you have a pcm generated by clang, you can use:
clang -module-file-info path/to/foo.pcm

Convert XCodeProj to Package.swift

I have recently inherited a swift project and would prefer to do my development on a Linux VM, rather then the under powered Mac I have. I have found lots of tutorials on how to got from a Package.swift to a xcodeproj. But I haven't found anything to go the other direction (xcodeproj to Package.swift). It seems that I need the Package.swift to be able to use the swift cli (swift build).
Is there a way to build without the Package.swift file?
Is there a way to do this that I haven't found?
Is there a technical reason that we can't go from a xcodeproj to a Package.swift?
1./2.
A Package.swift file is internally translated to a set of swiftc commands.
If you run swift build -v (verbose) on a fully working Swift package, you can see the commands that are being run. Using these commands, you may be able to figure out how to compile any collection of Swift sources without a Package.swift.
For a framework, one command could look something like this:
swiftc -module-name TestPackage -emit-dependencies -emit-module -c Path/to/Sources/*.swift -Onone -g -enable-testing -j8 -DSWIFT_PACKAGE -DDEBUG -Xfrontend -color-diagnostics
When compiling an executable, there may be additional commands to link the standard library, etc.
3.
The feature set of Xcode far exceeds the capabilities of Swift packages (e.g. .app bundles, Storyboards, Metal source files, ObjC, C, C++, etc.)
However, you can convert your command line project to a Swift package by running swift package init --type library|executable to create a Package.swift file. You can then specify a path parameter for the target in the Package.swift file:
.target(name: "YourTarget", path: "Path/To/Your/Swift/Files")

Swift fat framework w/Objective-C Cocoapod

I've built a framework in Swift. The framework uses Cocoapods, one of the pods is written in Objective C.
I also use a custom script to make the framework a fat framework so it supports 32/64 bit systems. (This runs in a separate target on the project and I'm wondering if that has something to do with it?)
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: Detected, stopping"
else
export ALREADYINVOKED="true"
// Step 1. Build Device and Simulator versions
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
//Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
// Step 3. Copy Swift modules (from iphonesimulator build) to the copied framework directory
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
// Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
// Step 5. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
// Step 6. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"
fi
When I create this fat framework and put it into a project I'd like to use it on the compiler always fails b/c the project can't see the objective C cocoa pod module.
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ld: framework not found Pusher for architecture x86_64
It is not found for any architecture when I change the build platform.
Any solution where I can produce a framework that I can use in a separate Xcode project (for all iOS or OS X) would be awesome.
You can't run xcodebuild with -target when using CocoaPods. When you use -target, Xcode will only consider the active project and fail to pull in the Pod dependencies, similar to if you just opened the project file in Xcode and tried building.
You should be running xcodebuild -workspace "${PROJECT_NAME}.xcworkspace" -scheme "${PROJECT_NAME}" ..., assuming that CocoaPods generated the workspace and Xcode generated a scheme using the target name. You will also need to make sure your scheme is marked as shared if running this on another device.
Once your framework is built you will need to include it and the frameworks it depends on in apps that will be using it. For your framework, that means including it in General > Embedded Binaries and General > Linked Frameworks and Libraries. For frameworks you depend on, (e.g. AlamoFire), you could instruct users to include it in their Podfile, you could package it and ship it along with your framework, or you could do both and let the user do what works for them.
Apparently you are missing the 64bit architecture for Simulator.
When you build a target from Xcode, depending on what kind of simulator you have selected - the produced library will contains i386 or x86_64 respectively for selected 32bit or 64bit version of the simulator.
I guess that the cli build is producing only i386 version.
You can try to set the architectures in the script:
xcodebuild -target "${PROJECT_NAME}" ARCHS="i386 x86_64" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
As an alternative You can try to build by hand using 64bit simulator (iPhone 5S +), then extract the missing architecture and then put it into the final library using lipo command.

no product after "build success" of a cocoa touch static library project

I have searched so many problem but there is no the same as me.
on Xcode 4.3.2(4.3.1)
I added several files to a new cocoa touch static library project and use iPhone Simulator to build it, then receive build success, but no .a file in products group (the .a file is red in the files list, left of Xcode)
When I change the "iPhone Simulator" to IOS Device, also receive build success, but now I can see .a file is not red and I can find in the product folder^
After I use lipo -info to check the .a file, it shows that it only supports arm7 architecture, thus confirms my first action(no product built in Simulator)^ so the .a file can't be used in my another project(i know it only can be used in simulator by supporting i386 architecture)
Use the command line. Here is a simple script I built a while back, it will even lipo your binaries together for you!
#!/bin/bash
#build the device
echo building for ARM architecture
xcodebuild -sdk iphoneos4.3 "ARCHS=armv6 armv7" build > /dev/null
#build the simulator
echo building for the i386 architecture
xcodebuild -sdk iphonesimulator4.3 "ARCHS=i386 x86_64" "VALID_ARCHS=i386 x86_64" build > /dev/null
#make the folder
mkdir "Fat Binary"
#lipo suck it together
echo lipo binaries together
lipo -output Fat\ Binary/libMyLib.a -create build/Release-iphoneos/liblibMyLib.a build/Release-iphonesimulator/libMyLib.a
echo lipo binary saved at $./Fat Binary/libMyLib.a
echo coping headers
cp -R build/Release-iphoneos/usr "Fat Binary"
echo [COMPLETE]
Just replace occurrences of libMyLib.a with the name of your library.