title: Building ARM code on OS X
body: <p>I am targeting the Cortex-A7 (ARMv7-A)</p>
  
  <p>As a test:</p>
  
  <p><strong>bootstrap.s</strong></p>
  
  <pre><code>.globl _start
  _start:
      mov sp,#0x00010000
      bl main
  hang: b hang
  </code></pre>
  
  <p><strong>main.c</strong></p>
  
  <pre><code>int main(void) { return 0; }
  </code></pre>
  
  <p>Trying:</p>
  
  <pre><code>$ as -arch armv7 -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 bootstrap.s -o bootstrap.o
  $ file bootstrap.o
  bootstrap.o: Mach-O object arm
  $ clang -c -arch armv7 -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 main.c -o main.o
  $ file main.o
  notmain.o: Mach-O object arm
  </code></pre>
  
  <p>Confirms the compilation of Mach-O arm object files (also verified using <code>hexdump</code>, <code>otool</code>, <code>gobjdump</code>)</p>
  
  <p>But now we try to link them together:</p>
  
  <pre><code>$ ld -e _start -arch armv7 bootstrap.o main.o -o foo
  ld: warning: -ios_version_min not specified, assuming 6.0
  ld: building for iOS, but linking in object file built for OSX, file 'bootstrap.o' for architecture armv7
  </code></pre>
  
  <p>And we have some issues. Not sure what's going on here. I haven't asked to link-in any iOS-related stuff. Using the <code>-t</code> linker flag confirms that no other objects are being linked in. Not sure why it thinks <code>bootstrap.o</code> is built for OS X when it clearly is a Mach-O arm file. Not sure if I'm passing the right flags to the assembler (pretty much all of them are undocumented?) or the linker</p>
  
  <p>Note that this is for a bare-metal mini-project running on RPi2. I'm going to <code>gobjcopy</code> the linked executable object to a flat binary anyways. I'm just working with Mach-O since that's the only object type the system linker on OS X is capable of working with (and fat Mach-O). If I built a separate cross-compiler, I would be doing the exact same thing, instead I'd be linking ELF files before converting them to flat binary (I can output ELF32 files using clang/llvm anyways, I just cant link them). Seems silly to build a separate cross-compiler when clang/llvm is a perfectly suitable cross-compiler that's able to target my microarchitecture</p>