[CMake] One project, one platform, 2 compilers

Michael Hertling mhertling at online.de
Mon Nov 21 09:55:05 EST 2011


On 11/18/2011 06:17 PM, Paul Hansen wrote:
> Thank you very much for the answers, David and Michael.
> 
> I am trying to get a QNX compiler to work with CMake. My host comp runs
> Ubuntu.
> I did:
> 
> cmake -G "Unix Makefiles -D CMAKE_C_COMPILER=qcc -D CMAKE_CXX_COMPILER=QCC
> ..
> but get
> dpkg-architecture: warning: Couldn't determine gcc system type, falling
> back to default (native compilation)
> cc: unknown option: '-dumpmachine'
> 
> I have of course google'd and found out that I probably have to make a new
> toolchain file.
> Does that seem correct?

Yes, it does.

> qcc is basicly gcc with modifications and other libraries.
> Is there an example toolchain file I can use as basis?
> 
> Is there any documentation about what should be set up in a toolchain file?

http://www.cmake.org/Wiki/CMake_Cross_Compiling and the ML, of course.

Regards,

Michael

> On Fri, Nov 18, 2011 at 2:26 PM, Michael Hertling <mhertling at online.de>wrote:
> 
>> On 11/17/2011 05:18 PM, Paul Hansen wrote:
>>> Hi
>>>
>>> I have a project that has to be compiled with two different compilers on
>>> the same computer.
>>>
>>> Can I do that from the same CMakeLists.txt file?
>>
>> What do you mean exactly?
>>
>> (1) Compile the project twice, each time completely with a different
>> compiler? If so, use two different build trees, as already outlined
>> in the meantime.
>>
>> (2) A part of your project must be compiled with a different compiler
>> than the remaining parts? Difficult - besides a custom-command-based
>> approach, you might outsource the concerned part and reintegrate it
>> as an external project which can be configured independently with a
>> different toolchain. Look at the following example:
>>
>> # CMakeLists.txt:
>> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
>> PROJECT(MAIN C)
>> SET(CMAKE_VERBOSE_MAKEFILE ON)
>> SET(SUBCC ${CMAKE_C_COMPILER} CACHE FILEPATH "Subproject C compiler")
>> INCLUDE(ExternalProject)
>> ExternalProject_Add(sub
>>    SOURCE_DIR ${CMAKE_SOURCE_DIR}/sub
>>    CMAKE_CACHE_ARGS
>>        -DCMAKE_C_COMPILER:FILEPATH=${SUBCC}
>>        -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/sub)
>> ADD_LIBRARY(f SHARED IMPORTED)
>> SET_TARGET_PROPERTIES(f PROPERTIES
>>    IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/sub/lib/libf.so)
>> ADD_DEPENDENCIES(f sub)
>> FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
>> ADD_EXECUTABLE(main main.c)
>> TARGET_LINK_LIBRARIES(main f)
>> ADD_DEPENDENCIES(main f)
>>
>> sub/CMakeLists.txt:
>> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
>> PROJECT(SUB C)
>> SET(CMAKE_VERBOSE_MAKEFILE ON)
>> FILE(WRITE ${CMAKE_BINARY_DIR}/f.c "void f(void){}\n")
>> ADD_LIBRARY(f SHARED f.c)
>> INSTALL(TARGETS f LIBRARY DESTINATION lib)
>>
>> Configure with the desired SUBCC to see the subproject being built with
>> that instead of the overall project's C compiler. The downside is that
>> you can't use FIND_*() on the subproject's targets since they're built
>> after the overall project is already configured, so you must predict
>> their locations. Additionally, there may be issues w.r.t. the correct
>> handling of dependencies. Moreover, if the subproject is to share the
>> overall project's cache, you need to pass the concerned variables to
>> ExternalProject_Add() individually, or do some trickery with LOAD_
>> CACHE(). Alternatively, you might use the so-called super-build
>> approach, but be prepared for other issues then, cf. [1].
>>
>>> Specifically I am wondering:
>>> - CMake finds a compiler and makes a test. A colleague has tried to
>> change
>>> the compiler variables but CMake made the test and overwrote his settings
>>> (from the CMakeLists.txt file) in CMakeCache.txt
>>
>> The toolchain can't be changed without a complete reconfiguration, and
>> during the latter, CMake even forgets the cache settings specified on
>> the command line, cf. [2].
>>
>>> - With target_link_directories I can point out specifically which
>> libraries
>>> should be used with each executable. But what about header files?
>>> include_directories() is not specified for each executable. Is there
>> anyway
>>> to control what is in the include path at different points in the
>>> CMakeLists.txt. I have tried to use set_directory_properties(PROPERTIES
>>> INCLUDE_DIRECTORIES "") to reset include path at one point. The deletion
>>> works but just not at that specific point on CMakeLists.txt.
>>
>> The INCLUDE_DIRECTORIES directory property is read-only.
>>
>>> - If split up into compiler1.cmake and compiler2.cmake I still get the
>>> include_directories() problem since values are "inherited"
>>
>> In general, I'd recommend to invoke INCLUDE_DIRECTORIES() sufficiently
>> deep within the CMakeLists.txt files' hierarchy to limit the scope of
>> its impact. Possibly, you even need to reorganize your project a bit,
>> i.e. split one CMakeLists.txt in two and have INCLUDE_DIRECTORIES()
>> called for the latters with the correct directories separately.
>>
>> Regards,
>>
>> Michael
>>
>> [1] http://www.mail-archive.com/cmake@cmake.org/msg36170.html
>> [2] http://www.mail-archive.com/cmake@cmake.org/msg37060.html


More information about the CMake mailing list