Since this question is unanswered and I spent the majority of a semester figuring it I thought I would post how to Cross compiling FreeTDS 0.91 to iPhone ARMv6, ARMv7 architecture. This was done using Xcode 4.2 and iOS 5 SDK.
The reason this question is asked it because you are developing an app for an iOS device that requires connecting to an Mircosoft SQL Sever, which requires using the Tabular Data Stream (TDS) protocol as it is Microsoft proprietary.
I will also mention that you need some level of technical skill to even attempt this. This is a very condensed version of what took me nearly two months to figure out (I left all the things you shouldn't do).
Other documentation relating to this:
Basic How To on using FreeTDS http://www.freetds.org/userguide/samplecode.htm
Microsoft's TDS API documentation
http://msdn.microsoft.com/en-us/library/aa936985(v=sql.80)
See my answer below.
Also see saskathex answer for Xcode 4.5 updated files.
For those like me that will spend hours finding the documentation for these standard configure flags (for running ./configure make make install)
./configure --build is used for specifing the architecture you want to complie for
./configure --host is used to specify the ark of the machine doing the compileing (running xcode)
./configure --target seems to be an alias
Now then to solving the problem.
1) Get the latest version of the FreeTDS http://www.freetds.org/
2) The next step is to make your own bash shell files that correctly run the FreeTDS ./configure. You will need two as the simulator is i386/i686 architecture and an apple device (iPhone, iPod, etc.) is ARM architecture. Also, your compiler files/version within the iPhone development directories may be different, just find what makes logical sense and has similar naming convention. The mac host architecture is supplied with the command uname -p.
Here is my example for building for use on the simulator (i386) build_for_simulator_i386.sh:
#!/bin/sh
#unset some shell variables
unset CC
unset CFLAGS
unset CPP
export buildPath=`pwd`
# make i386 (Simulator) target
export CC=/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/i686-apple-darwin11-llvm-gcc-4.2
export CFLAGS="-isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk"
# if you want Windows Authentication (NTLM) support you must use at least tds version 7
# the default is 5
./configure --build=i386 --host=i386 --target=i386 --with-tdsver=7.1
Example for configuring for ARM compilation (build_for_device_armv7.sh):
#!/bin/sh
# unset some shell variables
unset CC
unset CFLAGS
unset CPP
export buildPath=`pwd`
# make arm target
export CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2
export CFLAGS="-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk"
export CPP=/usr/bin/cpp
./configure --build=arm-apple-darwin10 --host=x86_64-apple-darwin11.3.0 --target=armv7 --with-tdsver=7.1
3) Next cd to the root freetds directory that resulted from unzipping the freetds download, mine was freetds_0.91
4) Run one of your scripts. You can only compile for ONE architecture at a time
sh build_for_(desiered build)
this runs ./configure for you with the correct options
(tds version 7 required for NTLM authentication)
5) Once the configure process completes you have to hack the configuration file. Open freetds_0.91/include/config.h then on line 172 change #define HAVE_ICONV 1 to #define HAVE_ICONV 0
6) If you previously ran ./configure, make, make install then run these commands. Especially if your switching architectures as you will get errors running make without doing this
sudo make clean
sudo make uninstall
7) Perform the compilation using make
make all
sudo make install
The make procedure does through some error on purpose, but if you see errors within six or seven lines of shell prompt, once it returns, you have problems and need to fix them before proceeding. Lets just say lots of things can go wrong at this point.
8) After installing the binary complied file that is the culmination of all the little .o files that freetds makes is /usr/local/lib/libsybdb.a Trust me you don't want to pull a .o file for just the library you want. Copy /usr/local/lib/libsybdb.a to the appropriate folder in your project. What I did was have two separate folders, one per architecture, named "compiled_freetds-0.91_simulator_i386" and "compiled_freetds-0.91_device_armv7."
9) Since you want to make you life easy and have xcode figure out which compiled file to use follow this subset of steps to perform the dynamic linking.
a) Select you project settings on the left had side of xcode
(the blue think with the name of your project on it)
b) Select the Target (usual the same name as your app)
c) Navigate to **build settings**, scroll down to **linking > other linker flags**
d) On the left side of Other Linker Flags a mouse over will reveal an expander,
expanding will reveal Debug and Release rows.
e) Add the appriate architectures by selecting the plus on the right side of
either Debug or Release. When the new row appears select the architecture,
double click the first editable field from the right to open an entry box
that you can then drag the appropriate complied file into it to be dynamically
linked. You must do this for both files and when done correctly the file
under ARMv7 will be used when building for the device and the one for Any iOS
Simulator SDK will be used when running on the simulator.
**Note:** You may also need to add the -all_load flag to resolve linking issues.
10) The final step which seems to avoid problem of dynamic linking error involving libsybdb.5.dylib when running code on device is to make uninstall. Also, when running on the device you will also get lots of warnings, in increments of 36, about CPU_SUBTYPE_ARM_ALL being deprecated, that is normal, but annoying.
sudo make uninstall
I hope this helps.
I used the above bash files but since XCode 4.5 the Developer Tools are inside the app bundle. So I modified the scripts to run with my MacOS Lion and the current XCode Version "4.5.2 (4G2008a)"
build_for_simulator_i386.sh:
#!/bin/sh
# unset some shell variables
unset CC
unset CFLAGS
unset CPP
# make i386 (Simulator) target
export CC=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/i686-apple-darwin11-llvm-gcc-4.2
export CFLAGS="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.0.sdk"
export CPP=/usr/bin/cpp
./configure -build=i686-apple-darwin11 --host=i686-apple-darwin11 --target=i686-apple-darwin11 --with-tdsver=7.1
build_for_device_armv7.sh:
#!/bin/sh
# unset some shell variables
unset CC
unset CFLAGS
unset CPP
# make arm target
export CC=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2
export CFLAGS="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk"
export CPP=/usr/bin/cpp
./configure --build=arm-apple-darwin10 --host=x86_64-apple-darwin11 --target=armv7 --with-tdsver=7.1
A nice add-on is to use lipinfo to merge two static libraries into one by
lipo compiled_freetds-0.91_device_armv7/libsybdb.a compiled_freetds-0.91_simulator_i386/libsybdb.a -create -output universal_libsybdb.a
and just adding this to the project's settings.
Wanted to share it, since the above scripts saved me a lot of time.
Related
I have installed the latest version of Eclipse on my Windows 7 64-bit machine and the mingw compiler. In setting up a Hello World project, all goes well until I am asked for the Cross Settings what the Prefix is and the Path. The Path is obvious, it's the path to the compiler. However, I haven't the slightest idea what the Prefix is and Googling for much of the day hasn't enlightened me other than finding that a lot of other people have asked the question. Unfortunately the answers I've found appear to be for specific hardware. All I want to do is to produce an executable that will run on a Windows 32 bit or 64 bit machine.
So, what is the Prefix and how do I find what it should be?
What is probably happening here is that CDT is not locating your MingW or GCC installations.
simple - but unlikely reason - covering bases
There can be many reasons, from the simple - but unlikely at this point:
You don't have mingw installed
You don't have GCC installed
This can be tested easily by starting a shell and running gcc --version.
CDT heuristic not working
To more complicated reasons relating to your installation not being detected because the heuristic in CDT did not work on your machine. To find the correct settings, CDT will do:
Check $MINGW_HOME/bin for existence
Check <Eclipse install location>/mingw/bin for existence
Look for mingw32-gcc.exe or x86_64-w64-mingw32-gcc.exe on the PATH
Check C:\MinGW for existence
If CDT cannot find any of the above, you may lead to the situation you are in.
So, how to fix it!
Option 1
Start Eclipse from within a mingw set up shell. i.e. the one you can successfully run gcc --version from. That way Eclipse will inherit an environment that can launch GCC successfully.
Option 2
Set your environment up so that MINGW_HOME is properly defined. You can do this at the system level or within the build settings in Eclipse CDT. For example, on my machine in the build settings for the project (Right-click on the project, choose Properties, then choose C/C++ -> Environment) I have set:
MINGW_HOME to C:\MinGW
MSYS_HOME to C:\MinGW\msys\1.0
PATH to ${MINGW_HOME}\bin;${MSYS_HOME}\bin;<my normal path>
and this allows Eclipse to launch gcc as part of the build process.
NOTE The above setting were done automatically on my machine because mingw was correctly located by the heuristic.
Here is a screenshot of the build settings if it helps:
Prefix: Under the hood
To try and answer part of your original question about what Prefix is, I provide the below information. It is unlikely to be particularly helpf
Prefix, in GCC parlance, refers to the directory under which all the related GCC files are placed. With different prefixes you can have multiple GCC installed on your machine.
From the GCC FAQ:
It may be desirable to install multiple versions of the compiler on
the same system. This can be done by using different prefix paths at
configure time and a few symlinks.
The concept comes from autotools in general. Autotools is the standard GNU make system (where you do ./configure && make - simplified). The prefix is the command line option to the configure stage (--prefix) to specify where to install the tool to. GCC above uses the --prefix to allow multiple GCCs on your system.
If you really want to know more about this, read the autobook. The section on configuring covers --prefix:
‘--prefix=prefix’
The –prefix option is one of the most frequently
used. If generated ‘Makefile’s choose to observe the argument you pass
with this option, it is possible to entirely relocate the
architecture-independent portion of a package when it is installed.
For example, when installing a package like Emacs, the following
command line will cause the Emacs Lisp files to be installed in
‘/opt/gnu/share’:
$ ./configure --prefix=/opt/gnu
It is important to stress that this behavior is dependent on the generated files making use of this
information. For developers writing these files, Automake simplifies
this process a great deal. Automake is introduced in Introducing GNU
Automake.
Additionally, Mingw takes advantage of all this prefix options. Read more about that on mingw's site. But the short of it is that the main prefix for mingw is /mingw.
I'm having trouble cross compiling PostgreSQL for my TI Sitara AM335x EVM SK. My host system is an i386 machine running Ubuntu 12.04.
My application is written in C++ using Qt. When I try and compile, I get the error that libpq.so is incompatible. I believe this is because the cross compiler is trying to use the host libpq.so instead of one for the target system (which as I have found out, doesn't exist).
I've downloaded the source for PostgreSQL with the intention of cross compiling that in order to give me the libpq.so library that will be compatible with my target system, however there is virtually no information on how to do this.
I have tried using the CC argument with the configure file to change my compiler to the following: CC=/home/tim/ti-sdk-am335x-evm-06.00.00.00/linux-devkit/sysroots/i686-arago-linux/usr/bin/arm-linux-gnueabihf-gcc but the configure script gives me this error: configure: error: cannot run C compiled programs. If you meant to cross compile, use --host.
The configure file makes a small reference to the --host option, but the only information in the file that I could find is in reference to mingw and windows, which isn't what I want.
I've done some quick searching through the configure file, and it references the --host option, but with no explanation of what is a valid host. I'm assuming that with --host option there will be an associated --target.
What arguments can I give the configure script so that it will cross compile with the correct compiler to generate a library that my target device can use? Are there any resources out there that I haven't found in regards to how the --host/--target works or how to use them?
OK, so after fiddling around for a little while, I think I was actually able to cross compile PostgreSQL and answer my own question.
Before I went any further, I had realized I had forgotten to add the path to my cross compiler to the PATH environment variable. I used the command export PATH=/path/to/cross/compiler:$PATH to insert the compiler path to the PATH environment variable.
Next, I did some experimenting with the --host option. To start off with I tried using ./configure --host=arm-linux-gnueabihf and running the configure script. The configure script seemed to accept this as the host argument. I then went to the next step of running the makefile. Running this makefile resulted in errors being generated. The errors were selected processor does not support Thumb mode. I did a quick search to see what information I could find about this error and came to this webpage: http://www.postgresql.org/message-id/E1Ra1sk-0000Pq-EL#wrigleys.postgresql.org.
This webpage gave me a bit more information since it seemed like the person was trying to do something very similar to me. One of the responders to the post mentioned that --disable-spinlocks is intended for processors that aren't supported by default by PostgreSQL. I emulated the arguments that were used in the website listed above and used the command: ./configure --host=arm-linux CC=arm-linux-gnueabihf-gcc AR=arm-linux-gnueabihf-ar CPP=arm-linux-gnueabihf-cpp --without-readline --without-zlib --disable-spinlocks to generate my makefile. This makefile actually generated all of the files, including the libpq.so library file I was needing.
Hope this helps somebody else in the future!
I have installed dmd and ddt as instructed:
DMD64 D Compiler v2.066.0
Copyright (c) 1999-2014 by Digital Mars written by Walter Bright
Documentation: http://dlang.org/
but when I create a dub project in eclipse, I dot an error that says standard libray not found:
(source: p.im9.eu)
any ideas?
OS: Mac OSX 10.9
Eclipse: 4.4
DDT: 0.10.2
I've also posted a temporary workaround in the discussion group (link):
# cd /usr/share/dmd
# mkdir dummy
# mkdir dummy/bin
# touch dummy/bin/dmd
# launchctl setenv DUB_COMPILERS_PATH /usr/share/dmd/dummy/bin
# killall Dock
Note that the DUB_COMPILERS_PATH variable shouldn't point to the binary itself, it acts like an additional PATH variable, i.e should contain bin dirs.
To make this survive a reboot, add the launchctl line to /etc/launchd.conf:
launchctl setenv DUB_COMPILERS_PATH /usr/share/dmd/dummy/bin
You might need to create it if it doesn't already exist.
This seems to be a reported bug of DDT:
https://github.com/bruno-medeiros/DDT/issues/75
Basically, it boils down to the directory structure of the installed dmd. As they are many distributions and many installers, each one with its own convention, DDT missed some.
They should be added and recognized shortly, in the pending release.
Please follow the reported issue on github/DDT page.
Yes, I know this thread is really old, and yes DDT seems to be no longer in development.
However, for those of us who are new to D, Eclipse and DDT, and relatively new to using Linux (I'm using Mint 19.3), I have the following solution which worked for me. No doubt this is common knowledge somewhere, but I had to scratch around quite a lot to discover this. (Of course, your dmd version number may be different.)
Note that dub is automatically installed along with dmd in:
$HOME/dlang/dmd-2.090.1/linux/bin64/dub
The command
source ~/dlang/dmd-2.090.1/activate
will modify the $PATH variable to allow access to the compiler.
NOTE that this only changes the path for the shell where the command is issued... and only for the current session!
If you want the path change to be permanent (who doesn't?), add the following to ~/.profile using a text editor, e.g. nano ~/.profile or xed ~/.profile , etc.:
# Add dlang dmd compiler path
if [ -d "$HOME/dlang/dmd-2.090.1/linux/bin64" ] ; then
PATH="$HOME/dlang/dmd-2.090.1/linux/bin64:$PATH"
fi
This corrects the Eclipse error:
"D Standard Library [Error: none found]"
in the Project tree, and also allows dub to be run from any directory, e.g. from a terminal.
HTH.
Can anyone recommend either:
an ARM disassembler that runs in either Windows or MacOS and which can ideally understand the executable format used by iOS
within MacOS, a way to call the cross-compiling GCC installed by XCode directly from the command line (so that I can run it on a small test file and ask for assembly output).
Basically, I'm interested in seeing how certain things get compiled for ARM/iOS by XCode/gcc to help me with optimisation. As you can see, although I have both a Windows and Linux background, I'm not fundamentally a Mac specialist so I'm not too familiar with e.g. where XCode intsalls all its gubbinry or the ins and outs of whatever binary format iOS uses.
I don't particularly care whether I have to do the "disassembly" under Mac OS or Windows, but what I was trying to avoid is installing a brand new copy of GCC configured to cross-compile to ARM, as XCode presumably has a perfectly good installation already sitting there somewhere... Any help appreciated.
You can always use otool disassembler. It's rather basic but does the job.
IDA Pro can disassemble ARM Mach-O files used in iOS. Using it is (in my biased opinion) much better experience that looking at the dead listing. You can check how it works with the demo version.
Disclaimer: I work for Hex-Rays.
an ARM disassembler that runs in either Windows or MacOS and which can ideally understand the executable format used by iOS
I can suggest you a LLVM. If it is built with default options, llvm-objdump will disassemble ARM.
Also, looks like http://developer.apple.com/technologies/tools/whats-new.html Apple is using LLVM toolchain in iOS SDK.
There is already an ARM cross compile toolchain built into Xcode. You can debug your iOS applications at the source and ASM level with the gdb debugger support already built into Xcode. For example, open your iOS app and select Device and Debug. Then set a breakpoint at a source line and run your program until the breakpoint is hit. Now select "Run -> Debugger" from the menu. When the debugger is showing, select "Run -> Debugger Display -> Source and Disassembly" and you will see a window on the right side that shows the ARM asm code that was generated from your source code. You can step through the code a source line at a time using the buttons. If you want to step one ARM asm instruction at a time, open up the gdb console and use the "stepi" instruction (type it once, then just hit enter to repeat).
Take a look at Hopper. It's darn cheap compared to IDA (though not as powerful) and the recent versions can handle ARM.
Within MacOS, a way to call the cross-compiling GCC installed by XCode directly from the command line (so that I can run it on a small test file and ask for assembly output).
Use this script for a gcc that compiles for iphone:
#!/bin/bash
# Note: The "/Applications/Xcode.app/Contents" prefix is only required on 10.7.2 and
# later (where Xcode is installed through app store rather than as a package).
# If running 10.6 or earlier, cut out that prefix.
PLATFORM=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
# Change this to the iOS version you want to compile for (you must have the platform
# SDK installed in Xcode)
VER=6.1
$PLATFORM/Developer/usr/bin/gcc -arch armv7 -framework IOKit -framework CoreFoundation -F $PLATFORM/Developer/SDKs/ iPhoneOS$VER.sdk/System/Library/Frameworks -I $PLATFORM/DeviceSupport/Latest/Symbols/usr/include -L $PLATFORM/Developer/SDKs/iPhoneOS$VER.sdk/usr/lib -L $PLATFORM/Developer/SDKs/iPhoneOS$VER.sdk/usr/lib/system $*
Source: newosxbook.com
Take a look at Radare2 it is an open Source tool that is rising it's Feature-Set constantly and already supports ARM disassembling.
Everything builds and runs in the simulator fine ... but when I attempt to run on device I get:
"arm-apple-darwin10-gcc-4.2.1:
..../three20/Build/Products/Debug-iphoneos/libextThree20JSON+YAJL.a:
No such file or directory"
I check that directory and indeed the file doesn't exist. It does exist in the "Debug-iphoneosimulator" though (which I guess explains why it works in the simulator).
So what gives and what can I do to correct this?
Thanks
This is fixed by adding the library via the python script from Three20. Do this in the command line:
python src/scripts/ttmodule.py -p ~/MyApp/MyApp.xcodeproj -c Debug -c Release extThree20JSON:extThree20JSON+SBJSON
OR
python src/scripts/ttmodule.py -p ~/MyApp/MyApp.xcodeproj -c Debug -c Release extThree20JSON:extThree20JSON+YAJL
depending on which library you need.
Are you building libextThree20JSON+YAJL.a from source, or did you just copy that .a file into your project? If the latter, the problem is probably that it is built for your computer's architecture (probably i386 or x86_64) and not ARM, what the iPhone/iPad use. To work on the device you need to either add the ARM-built version to your project, or add the library's source to your project so that it will automatically be built for the correct architecture with the rest of your code.
I switched from SBJSON to YAJL and for me a Clean Build Folder helped.