<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7233.69">
<TITLE>Proposal for full CMake cross compiler support</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/rtf format -->
<P><FONT SIZE=2 FACE="Arial">Hi,</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">I've been working on adding support for a TI DSP compiler to CMake. Initially I started off down the same route as the current UseEcos.cmake support, however this didn't really work out for a number of reasons, one main one being if you don't have a native platform compiler (e.g. Visual Studio under Windows) then you won't be able to build.</FONT></P>
<P><FONT SIZE=2 FACE="Arial">It occurs to me that what is really needed is the ability to add cross compilers as first class citizens, in place of the native compiler. What you really want to be able to do is something like this (where cl6x is the TI DSP compiler support):</FONT></P>
<P> <FONT SIZE=2 FACE="Arial">cmake -G "NMake Makefiles" -DCMAKE_CROSS_COMPILER:string=cl6x</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">I've managed to get an initial attempt at this working, with minimal patches to CMake's Modules directory. </FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">The concept is to follow a similar idea to CMake's existing modules and platforms, by having a hierarchy of include files, based on the proposed new CMAKE_CROSS_COMPILER:</FONT></P>
<UL>
<LI><FONT SIZE=2 FACE="Arial">CrossCompiler.cmake</FONT></LI>
<LI><FONT SIZE=2 FACE="Arial">CrossCompiler-cl6x.cmake</FONT></LI>
<LI><FONT SIZE=2 FACE="Arial">CrossCompiler-Generic-cl6x.cmake</FONT></LI>
<LI><FONT SIZE=2 FACE="Arial">Linux-cl6x.cmake</FONT></LI>
<LI><FONT SIZE=2 FACE="Arial">Windows-cl6x.cmake</FONT></LI>
<BR>
</UL>
<P><FONT SIZE=2 FACE="Arial">The include hierarchy is:</FONT>
</P>
<UL>
<LI><FONT SIZE=2 FACE="Arial">CrossCompiler.cmake</FONT></LI>
<UL>
<LI><FONT SIZE=2 FACE="Arial">CrossCompiler-cl6x.cmake</FONT></LI>
</UL>
<LI><FONT SIZE=2 FACE="Arial">Linux-cl6x.cmake</FONT></LI>
<UL>
<LI><FONT SIZE=2 FACE="Arial">CrossCompiler-Generic-cl6x.cmake</FONT></LI>
</UL>
<LI><FONT SIZE=2 FACE="Arial">Windows-cl6x.cmake</FONT></LI>
<UL>
<LI><FONT SIZE=2 FACE="Arial">CrossCompiler-Generic-cl6x.cmake</FONT></LI>
<BR>
</UL></UL>
<P><FONT SIZE=2 FACE="Arial">The actual build flags/rules for the cross compiler are in the common file CrossCompiler-Generic-cl6x.cmake, this can then be included (with any override tweaks) for a specific platform (e.g., I run this EXE compiler under Windows, and using Wine on Linux).</FONT></P>
<P><FONT SIZE=2 FACE="Arial">One key issue is getting in early enough in the config process, it seems that CMakeDetermineSystem.cmake is the first module included (anyone know better?), so an initial include is added to this file:</FONT></P>
<P><FONT SIZE=2 FACE="Arial">CMakeDetermineSystem.cmake:</FONT>
<UL>
<P><FONT SIZE=2 FACE="Arial">IF (CMAKE_CROSS_COMPILER)</FONT>
<BR> <FONT SIZE=2 FACE="Arial">INCLUDE (Platform/CrossCompiler)</FONT>
<BR><FONT SIZE=2 FACE="Arial">ENDIF (CMAKE_CROSS_COMPILER)</FONT>
</P>
<BR>
</UL>
<P><FONT SIZE=2 FACE="Arial">The CrossCompiler.cmake then contains the commands to disable the testing of the native compiler.</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">CrossCompiler.cmake:</FONT>
<UL>
<P><FONT SIZE=2 FACE="Arial">#</FONT>
<BR><FONT SIZE=2 FACE="Arial"># Set the compiler name to stop automatic searching for compilers.</FONT>
<BR><FONT SIZE=2 FACE="Arial"># This name is used as the CMAKE_BASE_NAME part which is used to include</FONT>
<BR><FONT SIZE=2 FACE="Arial"># the 'Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}.cmake' later.</FONT>
<BR><FONT SIZE=2 FACE="Arial">#</FONT>
<BR><FONT SIZE=2 FACE="Arial">SET (CMAKE_C_COMPILER ${CMAKE_CROSS_COMPILER})</FONT>
<BR><FONT SIZE=2 FACE="Arial">SET (CMAKE_CXX_COMPILER ${CMAKE_CROSS_COMPILER})</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">#</FONT>
<BR><FONT SIZE=2 FACE="Arial"># Inhibit compiler compatibility tests.</FONT>
<BR><FONT SIZE=2 FACE="Arial"># Stop test to see if our compilers work.</FONT>
<BR><FONT SIZE=2 FACE="Arial"># Stop auto GNU test.</FONT>
<BR><FONT SIZE=2 FACE="Arial">#</FONT>
<BR><FONT SIZE=2 FACE="Arial">SET (CMAKE_SKIP_COMPATIBILITY_TESTS 1)</FONT>
<BR><FONT SIZE=2 FACE="Arial">SET (CMAKE_C_COMPILER_WORKS 1)</FONT>
<BR><FONT SIZE=2 FACE="Arial">SET (CMAKE_CXX_COMPILER_WORKS 1)</FONT>
<BR><FONT SIZE=2 FACE="Arial">SET (CMAKE_COMPILER_IS_GNUCC_RUN 1)</FONT>
<BR><FONT SIZE=2 FACE="Arial">SET (CMAKE_COMPILER_IS_GNUCXX_RUN 1)</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">#</FONT>
<BR><FONT SIZE=2 FACE="Arial"># Allow optional cross compiler specific override.</FONT>
<BR><FONT SIZE=2 FACE="Arial">#</FONT>
<BR><FONT SIZE=2 FACE="Arial">INCLUDE (Platform/CrossCompiler-${CMAKE_CROSS_COMPILER} OPTIONAL)</FONT>
</P>
<BR>
</UL>
<P><FONT SIZE=2 FACE="Arial">This then also pulls in a optional cross compiler target specific file that allows changing of the object extension (this has to be changed very early on in the config process, as it gets generated as a cached file and can't be easily changed at the platform or project CMakeLists.txt level later).</FONT></P>
<P><FONT SIZE=2 FACE="Arial">CrossCompiler-cl6x.cmake:</FONT>
<UL>
<P><FONT SIZE=2 FACE="Arial">#</FONT>
<BR><FONT SIZE=2 FACE="Arial"># We must set the object extension type prior to the (skipped) compiler test,</FONT>
<BR><FONT SIZE=2 FACE="Arial"># as this gets embedded in the inference rule and attempts to change it later</FONT>
<BR><FONT SIZE=2 FACE="Arial"># will be ignored.</FONT>
<BR><FONT SIZE=2 FACE="Arial">#</FONT>
<BR><FONT SIZE=2 FACE="Arial">SET (CMAKE_C_OUTPUT_EXTENSION .obj)</FONT>
<BR><FONT SIZE=2 FACE="Arial">SET (CMAKE_CXX_OUTPUT_EXTENSION .obj)</FONT>
</P>
<BR>
</UL>
<P><FONT SIZE=2 FACE="Arial">CMakeCCompiler.cmake.in and CMakeCXXCompiler.cmake.in have to be patched as they both unconditionally set the object extension based on running on Linux or Windows, I've changed it to only set this if it isn't already set:</FONT></P>
<P><FONT SIZE=2 FACE="Arial">CMakeCCompiler.cmake.in:</FONT>
<UL>
<P><FONT SIZE=2 FACE="Arial">IF (NOT CMAKE_C_OUTPUT_EXTENSION)</FONT>
<BR><FONT SIZE=2 FACE="Arial"> IF(UNIX)</FONT>
<BR><FONT SIZE=2 FACE="Arial"> SET(CMAKE_C_OUTPUT_EXTENSION .o)</FONT>
<BR><FONT SIZE=2 FACE="Arial"> ELSE(UNIX)</FONT>
<BR><FONT SIZE=2 FACE="Arial"> SET(CMAKE_C_OUTPUT_EXTENSION .obj)</FONT>
<BR><FONT SIZE=2 FACE="Arial"> ENDIF(UNIX)</FONT>
<BR><FONT SIZE=2 FACE="Arial">ENDIF (NOT CMAKE_C_OUTPUT_EXTENSION)</FONT>
</P>
<BR>
</UL>
<P><FONT SIZE=2 FACE="Arial">CMakeTestCCompiler.cmake has to be modified to stop it from trying to check the size of a "void*" (it looks like this is an oversight, as all other size testing is turned off by CMAKE_SKIP_COMPATIBILITY_TESTS):</FONT></P>
<P><FONT SIZE=2 FACE="Arial">CMakeTestCCompiler.cmake:</FONT>
<UL>
<P><FONT SIZE=2 FACE="Arial"> IF (NOT CMAKE_SKIP_COMPATIBILITY_TESTS)</FONT>
<BR><FONT SIZE=2 FACE="Arial"> CHECK_TYPE_SIZE("void*" CMAKE_SIZEOF_VOID_P)</FONT>
<BR><FONT SIZE=2 FACE="Arial"> ENDIF (NOT CMAKE_SKIP_COMPATIBILITY_TESTS)</FONT>
</P>
<BR>
</UL>
<P><FONT SIZE=2 FACE="Arial">Has anyone else tried to implement anything similar for cross compiler support?</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">What do you think of this approach? Is it suitable for thinking about as a generic CMake solution for any cross platform compiler?</FONT></P>
<P><FONT SIZE=2 FACE="Arial">Comments welcome.</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">- TrevK</FONT>
</P>
<BR>
<BR>
<BR>
</BODY>
</HTML>