How to compile C into a universal library that works with iOS architectures - ios

I'm trying to compile a very small amount of C source into a library that I can use in XCode for an iOS application.
The files are a single .c file and three header files. I'm very new to C, and no matter what I try I can't seem to get them to compile into a library that supports iOS architectures.
The files depend on the openssl library, and I've got that installed and working fine.
I just need to know the process of compiling these four files into a single library. I've found a plethora of information on the subject online, but I can't decipher which parts are necessary for what I'm trying to do.
I've tried the following:
gcc -fPIC -c main.c
gcc -shared -o mylib.so main.o -lcrypto -lssl
which seems to compile it for x86_64, (I've not tested the resulting file, just checked it's arch).
I've also tried
./configure --disable-shared --enable-utf8 --host=arm-apple-darwin CFLAGS="-arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk" CXXFLAGS="-arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk" LDFLAGS="-L." CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc" CXX="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++"
which only gives me errors
checking for arm-apple-darwin-gcc... no
checking for gcc... gcc
checking whether the C compiler works... no
configure: error: in `/Users/nathanf/compilec':
configure: error: C compiler cannot create executables
I've been scouring the internet for the last few days trying to figure this out, but it's so convoluted to cross compile just a few files and I'm frustrated so I came here for some input.
Any help would be greatly appreciated.

Related

Building FFmpeg for use in Swift

With the new XCode/Swift release comes the ability to use binary dependencies. This seems to me to be an ideal time to create an SPM package for FFMpeg.
However, while I've spent the last year learning to code i Swift, I'm actually not all that familiar with how to build libraries, especially those as complex as FFmpeg with all the configurable libraries and third-party dependencies.
There's kewlbear's iOS build scripts, but these are for iOS/tvOS and ideally an FFMpeg SPM package would be usable for MacOS also. It's also not updated for the newest Xcode and Swift versions.
My personal interest is simply in audio and I don't need a lot of bells and whistles, but I figure the ideal situation would be a full package with the entire source and whatever dependencies it needs, and then when it's used as a package dependency, the compiler will just use the parts it needs.
I guess my question is...how would I ideally compile the ffmpeg code for this purpose. I'm trying to follow the directions for compiling yourself, but I'm stuck at the point of compiling gettext because I'm not sure if I should follow the directions (in the gettext source code) for compiling a fat binary for multiple architectures, and when I try to run:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
I get the following error:
checking whether the C compiler works... no configure: error: in
`/Users/nolainecrusher/Downloads/FFMpeg-source/gettext-0.21/gettext-runtime':
configure: error: C compiler cannot create executables See
`config.log' for more details configure: error: ./configure failed for
gettext-runtime
and config.log doesn't really tell me anything useful:
This is what I see at the end of the log:
mkdir_p='$(MKDIR_P)' oldincludedir='/usr/include' pdfdir='${docdir}'
prefix='/usr/local' program_transform_name='s,x,x,' psdir='${docdir}'
sbindir='${exec_prefix}/sbin' sharedstatedir='${prefix}/com' subdirs='
gettext-runtime libtextstyle gettext-tools' sysconfdir='${prefix}/etc'
target_alias=''
I feel like maybe I'm going about this the wrong way, but I'm not sure what the right way is.
See the following:
A Swift wrapper package for FFmpeg and
A C wrapper package for FFmpeg
SwiftFFmpeg assumes ffmpeg is installed locally and will link with those libraries. Also, SwiftFFmpeg uses CFFmpeg as a package dependency, and your app can use SwiftFFmpeg as a dependency.
If you want to see a build script for compiling ffmpeg (x86_64 and arm64), check out my own audio player project.

Problems linking FFTW with gfortran (symbol(s) not found for architecture x86_64)

I am on macOS Catalina (10.15.5) and I have installed FFTW using brew install fftw. I also have GCC (version 10.2.0) installed which is symlinked to the commands I am using below.
I am able to compile and run a simple C++ program like so:
g++-10 test.cpp -L/usr/local/lib -I/usr/local/include -lfftw3 -lm
But, I had to modify the environment variable CPATH to make this work.
I am unable to get a simple Fortran FFTW example to work (I am using this one). The command I am using to compile is:
gfortran-10 test.f90 -L/usr/local/lib -I/usr/local/include -lfftw3 -lm
The error I get is as follows:
Undefined symbols for architecture x86_64:
"__gfortran_os_error_at", referenced from:
_MAIN__ in ccRvJaEQ.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
If I understand correctly, the linking step fails. Any inputs on how I might find the relevant paths that I may have to pass to the compiler would be very helpful. I searched for solutions and I wasn't able to find one. But, in case I missed something obvious, I apologise.
Thanks to msi_gerva's helpful hints through comments, I was able to solve the issue by downloading FFTW and compiling it to a custom directory following the installation directions.
Now, the linking doesn't fail if I pass the new locations of the libraries to gfortran like so:
gfortran-10 test.f90 -L/new/path/to/lib -I/new/path/to/include -lfftw3 -lm
Since /usr/local/ is the default installation path, it's possible that there is a mixing up of the FFTW library files from previous installations.

Problems Building MPFR using iOS SDK 8.3

I am having trouble building MPFR for iOS, armv7s architecture. I am using this command after successfully building GMP,
./configure CC=clang CPP="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -E" CPPFLAGS="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/ -miphoneos-version-min=8.0 -arch armv7s -target arm-apple-darwin" --host=aarch64-apple-darwin --disable-assembly --enable-static --disable-shared
However, I configure is giving me the error
libgmp not found or uses a different ABI.
I built GMP with the same configure settings as above, then make, make install, etc. After this, I copied the gmp.h file and libgmp.la file to
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/usr/include/
and
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/usr/lib
respectively, but I get the same error.
Any ideas?
Okay, I think being tired got to me, and I was using an x86_64 version of GMP to try to compile the armv7 mpfr. I retried today, and everything worked. Make sure to move the gmp header and the libgmp.a file to the iOS sdk directories as mentioned in the question, else you will get an error at configure time. Other than that, it should work.

GMP Library for iOS

I have a GMP Library that is used for BIG integer calculation in C++.
I am unable to compile the same in Xcode for iOS development.
Please Provide with details steps regarding how to compile GMP for iOS Development
I realize that there has been some considerable time gone by but none of the information in the previous answer worked for me. Here is how I was able to do it, hope this helps someone else in the future.
Grab the gmp snapshot from https://gmplib.org/download/snapshot/
It is in .lz format, it will need to be uncompressed. if you have a mac, uncompress it using lzip, install with homebrew brew install lzip
Once its uncompressed from lzip, then it will be a .tar file, the finder can take care of that for you. You will have a gmp folder with a bunch of files and other sub-folders.
You will need Xcode commandline tools installed. Make sure you have that pre-installed.
Run this configure line. Take care to note that you need to put in your path to the directory you want it to be stored, in --prefix.
./configure CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -fembed-bitcode -arch arm64e --sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk" CPPFLAGS="-fembed-bitcode -arch arm64e --sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk " --disable-shared --enable-static --host=arm-apple-darwin --disable-assembly --prefix="{ YOUR_PATH_HERE }/GMP_6_1_99/gmp-6.1.99-20200117/gmplib-iphoneos-arm64e"
Then you run (notice the same path as before for the log files)
make -j &> "{ YOUR_PATH_HERE }/gmp-6.1.99-20200117/gmplib-iphoneos-arm64e-build.log"
make install &> "{ YOUR_PATH_HERE }/gmp-6.1.99-20200117/gmplib-iphoneos-arm64e-install.log"
There are two main points to those lines that are changeable, the platform, and the architecture. The above uses the arm64e architecture but you can just as easily build for arm64, armv7, armv7s. Also you can change out the platform as well and build for macosx, watchos, iphonesimulator, or appletvos. To change the platform you need to find the sdk of where it lives on your machine. The other architecture options are x86_64 i386, To do that, type this into your terminal...
xcrun --sdk iphoneos --show-sdk-path
(replace "iphoneos" with the platform you are looking to use from above)
And replace the SDK path. Make sure you match with the correct architecture or else you will get an error, cannot find compiler.
As GenieWanted said, provide more information!!!
However, I compiled successfully the GMP library for iOS 7 64 bits following the next step:
./configure
CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
CPP="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
-E" CPPFLAGS="-target arm64-apple-darwin -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/
-miphoneos-version-min=7.0" --host=aarch64-apple-darwin --disable-assembly --enable-static --disable-shared --prefix=/your-path/
I would like to point out that it only creates the C library, I do not think is different for C++, however I will try this afternoon.
#bolnad's answer worked for me doing a small modification, removing the -fembed-bitcode flag both from CC and CPPFLAGS.
EDIT: it ended up not correctly compiling the different architectures, so I found this script on github https://github.com/FlowCrypt/GMP and was able to build correctly.

libtool failed with exit code 1

I attempt to Create a Xcode-WorkSpace,there are there projects in it. Now the first Project is a static library base on ZBar Code Reader.I already download the source code ,now I drag the finder named "src" into my first project. When I bulid it,here is the problem:
Libtool /Users/asset/Library/Developer/Xcode/DerivedData/huishow1-efdjffeirjufbndvocvtzkrzkwss/Build/Products/Debug-iphonesimulator/libZBarTest.a normal i386
cd /Users/asset/iPhone_Tmp/ZBarTest
setenv MACOSX_DEPLOYMENT_TARGET 10.6
setenv PATH "/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/libtool -static -arch_only i386 -syslibroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk -L/Users/asset/Library/Developer/Xcode/DerivedData/huishow1-efdjffeirjufbndvocvtzkrzkwss/Build/Products/Debug-iphonesimulator -L/Users/asset/iPhone_Tmp/ZBarTest/SDK -L/Users/asset/iPhone_Tmp/ZBarTest/SDK3 -filelist /Users/asset/Library/Developer/Xcode/DerivedData/huishow1-efdjffeirjufbndvocvtzkrzkwss/Build/Intermediates/ZBarTest.build/Debug-iphonesimulator/ZBarTest.build/Objects-normal/i386/ZBarTest.LinkFileList -lxml2 -ObjC -framework Foundation -lzbar -o /Users/asset/Library/Developer/Xcode/DerivedData/huishow1-efdjffeirjufbndvocvtzkrzkwss/Build/Products/Debug-iphonesimulator/libZBarTest.a
Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/libtool failed with exit code 1
Who can help me?
Sounds like a missing dependency. I'm not familiar with the ZBar code reader but I'd imagine it declares dependencies on some system frameworks that you haven't yet included in your app? Look in the docs for ZBar to determine which frameworks you need to link to when including it. Typically when you get these types of libtool errors when you don't include a framework or other dependency.

Resources