View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0015223CMakeCMakepublic2014-10-28 12:072015-04-06 09:07
ReporterEmmanuel Blot 
Assigned To 
PrioritynormalSeveritymajorReproducibilityalways
StatusclosedResolutionno change required 
PlatformAnyOSOS Version
Product VersionCMake 3.0 
Target VersionFixed in Version 
Summary0015223: Object OUTPUT_EXTENSIONs selection is hard - if ever possible - to manage with cross compilation
DescriptionFor some (historical?) reasons, CMake considers the default object extension tas ".obj", which is quite unusual but on Windows.

CMake "Modules" files define:
IF (UNIX)
 set(CMAKE_<LANG>_OUTPUT_EXTENSION .o)
ELSE ()
 set(CMAKE_<LANG>_OUTPUT_EXTENSION .obj)
ENDIF ()

which makes the Unix style the exception, and Windows style the default rule.

However, when cmake is used to cross compile, many (if not most) OSes use the Unix style, even if they are not Unix-based.

The trouble is that UNIX variable seems to be mostly defined from the host environment, not from the target environment.

The net result is that ".obj" extension is enforced for non-Windows targets, which in turn rapidly becomes a nightmare to manage.

Forcing UNIX to 1 from a CMakeLists.txt sometimes helps for C source files - although it is definitely a hack - but does not with ASM files for example.

Setting CMAKE_<LANG>_OUTPUT_EXTENSION from a CMakeLists.txt does not seem to be recommended - from previous CMake ML posts - and does not work anyway.

Although I would personally favour .o to be the default extension and Windows the exception, I guess that for at least compatibility with previous CMake version this cannot be changed.

However, being able to easily define the extension for a non Unix project, or for a cross compiled one is definitely a real need.

Additional InformationI've failed - up to know - to find a way to choose the proper extension, which forced me to write ugly workaround in CMakeLists.txt files.
TagsNo tags attached.
Attached Files

 Relationships

  Notes
(0037085)
Brad King (manager)
2014-10-28 12:34

CMake is widely used for cross-compiling with many toolchains. Please provide a specific and complete example of what you're doing and what goes wrong: source tree, command lines used, etc.
(0037112)
Emmanuel Blot (reporter)
2014-10-31 09:16

While trying to find the smallest possible example, I found the root cause of the issue:

  PROJECT (demo)
  SET (CMAKE_SYSTEM_NAME Generic)

outputs '.o' files, while

  SET (CMAKE_SYSTEM_NAME Generic)
  PROJECT (demo)

outputs '.obj' files! (the initial issue)

with the following CMakeLists.txt file:

  CMAKE_MINIMUM_REQUIRED (VERSION 3.0.0)
  INCLUDE (CMakeForceCompiler)
  FIND_PROGRAM (xcc arm-eabi-gcc)
  CMAKE_FORCE_C_COMPILER (${xcc} GNU)
  CMAKE_FORCE_CXX_COMPILER (${xcc} GNU)
  PROJECT (demo)
  SET (CMAKE_SYSTEM_NAME Generic)
  ENABLE_LANGUAGE (ASM)
  ADD_LIBRARY(demolib
              asm.S
              cc.c)

While PROJECT and ENABLE_LANGUAGE order is well documented, I did not noticed that SET(CMAKE_SYSTEM_NAME ...) should have been used **after** the PROJECT command

Maybe that some other commands ordering are wrong in my CMake scripts. It is not the first time I fail to find/guess the proper order of commands, or more explicitly which commands apply to whatever context.
(0037113)
Brad King (manager)
2014-10-31 09:38
edited on: 2014-10-31 09:38

Re 0015223:0037112: Actually CMAKE_SYSTEM_NAME should be set before the project command. Typically it is done in a toolchain file specified with CMAKE_TOOLCHAIN_FILE. The first project or enable_language command loads the toolchain file as part of initializing the target platform information. See:

 http://www.cmake.org/cmake/help/v3.1/manual/cmake-toolchains.7.html#cross-compiling [^]
 http://www.cmake.org/Wiki/CMake_Cross_Compiling [^]

The CMAKE_SYSTEM_NAME contributes to which compiler/platform information files get loaded from the language init modules:

 http://www.cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/CMakeCInformation.cmake;hb=v3.0.2#l15 [^]

Since you're setting it to "Generic" CMake does not load any of the unix information so nothing sets "UNIX" to 1. Therefore the default object extension is ".obj". If you also add

 set(UNIX 1)

to your toolchain file then you will get ".o".

(0037116)
Emmanuel Blot (reporter)
2014-10-31 10:45
edited on: 2014-10-31 10:52

So actually, the ordering is really hard to understand/solve:

# First case
PROJECT (demo)
ENABLE_LANGUAGE (ASM)
SET (CMAKE_SYSTEM_NAME Generic)

-> Generates .o files, but use the wrong archiver, i.e. /usr/bin/ar instead of arm-eabi-ar to archive the library files

# Second case
ENABLE_LANGUAGE (ASM)
PROJECT (demo)
SET (CMAKE_SYSTEM_NAME Generic)

-> Generate .o files, use the proper archive, but contradicts the CMake documentation that states that ENABLE_LANGUAGE should be set after PROJECT statement

# Third case
SET (CMAKE_SYSTEM_NAME Generic)
PROJECT (demo)
ENABLE_LANGUAGE (ASM)

--> Generate .obj files, use the proper archiver.

Adding SET (UNIX 1) before PROJECT -or- after ENABLE_LANGUAGE does not help with this issue, but:

# Forth case
SET (CMAKE_SYSTEM_NAME Generic)
PROJECT (demo)
SET (UNIX 1)
ENABLE_LANGUAGE (ASM)

--> Generate .o for .S file, .obj for .c file, use the proper archiver.

# Fifth case
SET (CMAKE_SYSTEM_NAME Generic)
ENABLE_LANGUAGE (ASM)
SET (UNIX 1)
PROJECT (demo)

--> Generate .obj for S file, .o for .c file!, use the proper archiver.

So it seems the only working combination is (2), but contradict both the documentation and your previous comment, so I guess it works but should not.

At this point, I am totally lost on the proper sequence to use

(0037117)
Brad King (manager)
2014-10-31 11:02

Re 0015223:0037116: Everything about the choice of target system should be set before enable_language or project. By setting the information later than that you are actually configuring with information about the host platform. It appears to work because you happen to be using unix host.

Try this:

$ cat Platform/MySystem.cmake
include(Platform/Generic)
set(UNIX 1)
$ cat CMakeLists.txt
cmake_minimum_required (VERSION 2.8.12)
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
set (CMAKE_SYSTEM_NAME MySystem)
project (demo C ASM)
...
(0037121)
Emmanuel Blot (reporter)
2014-10-31 12:48

Works perfectly. Thanks **a lot**
I think the ticket can be closed.
(0038436)
Robert Maynard (manager)
2015-04-06 09:07

Closing resolved issues that have not been updated in more than 4 months.

 Issue History
Date Modified Username Field Change
2014-10-28 12:07 Emmanuel Blot New Issue
2014-10-28 12:34 Brad King Note Added: 0037085
2014-10-31 09:16 Emmanuel Blot Note Added: 0037112
2014-10-31 09:38 Brad King Note Added: 0037113
2014-10-31 09:38 Brad King Note Edited: 0037113
2014-10-31 10:45 Emmanuel Blot Note Added: 0037116
2014-10-31 10:46 Emmanuel Blot Note Edited: 0037116
2014-10-31 10:52 Brad King Note Edited: 0037116
2014-10-31 11:02 Brad King Note Added: 0037117
2014-10-31 12:48 Emmanuel Blot Note Added: 0037121
2014-10-31 12:56 Brad King Status new => resolved
2014-10-31 12:56 Brad King Resolution open => no change required
2015-04-06 09:07 Robert Maynard Note Added: 0038436
2015-04-06 09:07 Robert Maynard Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team