# generate .o files from compiler instead of .obj files

**URL:** https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690
**Category:** Usage
**Tags:** os:windows, gen:makefiles
**Created:** [February 4, 2021, 6:49am UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690 "2021-02-04T06:49:31Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![deepan](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/d/7bcc69/32.png) [@deepan](https://discourse.cmake.org/u/deepan)
#### Post date: [February 4, 2021, 6:49am UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/1 "2021-02-04T06:49:31Z")

</div>

I am working in an embedded project.  
target : ppc  
compiler : windriver  
Host environment : windows 10  
build generator : cmake, MinGW makefiles

during compilation i see .c.obj getting generated.  
I want .o instead of .c.obj.  
from cmake side can we do this or it is compiler specific ?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [February 4, 2021, 2:46pm UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/2 "2021-02-04T14:46:58Z")

</div>

The extension is compiler-specific. Why does the extension matter in this case?

And the `.c` is always going to be there under CMake (some projects have `foo.c` _and_ `foo.cxx` and CMake’s strategy avoids this conflict unconditionally).

---

<div class="post-metadata">

### Author: ![Laur59](https://discourse.cmake.org/user_avatar/discourse.cmake.org/laur59/32/4200_2.png) [@Laur59](https://discourse.cmake.org/u/Laur59)
#### Post date: [January 19, 2024, 7:28am UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/3 "2024-01-19T07:28:14Z")

</div>

Sorry to revive this topic, but I have the same issue. cmake is used to build a project for embedded device (e.g. STM32 controlllers). The toolchain used is arm-none-eabi-gcc.  
I created a configuration file as described in cmake documentation about embedded.  
CMakeLists.txt typically contains :

```auto
cmake_minimum_required(VERSION 3.26)
set(CMAKE_TOOLCHAIN_FILE $ENV{PATH_UKOS_KERNEL}/Ports/Mkfiles/Toolchains_cmake/cortex-m.cmake)

project(
  Nucleo_L4R5_Variant_Test
  VERSION 1.0
  LANGUAGES C)

```

The extension .obj is not chosen by arm-none-eabi-gcc by defaults. This extension is set by the command generated by cmake. This is seen using VERBOSE=1 to build the system, for instance

```auto
[1%] Building C object CMakeFiles/rtcb_p.dir/Users/Dev/u169/os-kernel-iv/Ports/EquatesModels/Generic/Runtime/crt0.obj
/opt/embedded/cross/gcc-current/cortex-M/bin/arm-none-eabi-gcc -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -g3 -pedantic -std=c2x -Os -o CMakeFiles/rtcb_p.dir/Users/Dev/u169/os-kernel-iv/Ports/EquatesModels/Generic/Runtime/crt0.obj -c /Users/Dev/u169/os-kernel-iv/Ports/EquatesModels/Generic/Runtime/crt0.c

```

The extension .obj is forced by the compiler option  
-o CMakeFiles/rtcb\_p.dir/Users/Dev/u169/os-kernel-iv/Ports/EquatesModels/Generic/Runtime/crt0\*\*.obj\*\*

I tried to use `set(CMAKE_C_OUTPUT_EXTENSION .o)` but nothing changes.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [January 19, 2024, 7:40am UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/4 "2024-01-19T07:40:28Z")

</div>

Unless the extension is causing something to fail, just ignore it. You’re fighting a battle you don’t need to otherwise.

---

<div class="post-metadata">

### Author: ![Laur59](https://discourse.cmake.org/user_avatar/discourse.cmake.org/laur59/32/4200_2.png) [@Laur59](https://discourse.cmake.org/u/Laur59)
#### Post date: [January 19, 2024, 7:51am UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/5 "2024-01-19T07:51:23Z")

</div>

It is just making harder to support building project either using legacy make or cmake because need to provide different linker scripts, which is weird as the toolchain used is the same in both cases

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [January 19, 2024, 11:47am UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/6 "2024-01-19T11:47:07Z")

</div>

> [@Laur59](#):
>
> need to provide different linker scripts

Ok, that addresses the “why does the extension matter” question. Where did you try setting `CMAKE_C_OUTPUT_EXTENSION`? I think it should be part of the toolchain file.

---

<div class="post-metadata">

### Author: ![Laur59](https://discourse.cmake.org/user_avatar/discourse.cmake.org/laur59/32/4200_2.png) [@Laur59](https://discourse.cmake.org/u/Laur59)
#### Post date: [January 19, 2024, 12:00pm UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/7 "2024-01-19T12:00:59Z")

</div>

I tried to put it in the file describing the toolchain, also in the CMakeLists.txt of the project, just after the command project().  
(sorry as new user I cannot upload the toolchain file)  
I am using cmake 3.28.1  
the command i Have try is

```auto
set(CMAKE_C_OUTPUT_EXTENSION .o)

```

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [January 19, 2024, 12:08pm UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/8 "2024-01-19T12:08:27Z")

</div>

Can you try passing `--trace-expand` to the initial configure (and put `stderr` into a file for analysis) to see if the variable is set anywhere else?

---

<div class="post-metadata">

### Author: ![Laur59](https://discourse.cmake.org/user_avatar/discourse.cmake.org/laur59/32/4200_2.png) [@Laur59](https://discourse.cmake.org/u/Laur59)
#### Post date: [January 19, 2024, 12:14pm UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/9 "2024-01-19T12:14:52Z")

</div>

I hope you can dowload the file produced by

cmake -S . -B build --trace-expand

[stdout](https://privatebin.portal.csem.ch/?8dc50008a573e0ae#oFvUsKJzAde8cckM6nen5uF4ftzW6moa7DkbHK3x97M)

Indeed it is set elswhere else

```auto

/Applications/CMake.app/Contents/share/cmake-3.28/Modules/CMakeCInformation.cmake(18): set(CMAKE_C_OUTPUT_EXTENSION .obj )

```

---

<div class="post-metadata">

### Author: ![Laur59](https://discourse.cmake.org/user_avatar/discourse.cmake.org/laur59/32/4200_2.png) [@Laur59](https://discourse.cmake.org/u/Laur59)
#### Post date: [January 19, 2024, 12:21pm UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/10 "2024-01-19T12:21:52Z")

</div>

Here is the content of the file defining the toolchain (cortex-m.cmake)

```auto
if(NOT DEFINED ENV{PATH_GCC_CORTEXM})
    message( FATAL_ERROR "Environment variable PATH_GCC_CORTEXM is not defined." )
endif()

option(USE_PICOLIBC "Use library picolibc instead of newlib" OFF)
if(DEFINED ENV{USE_PICOLIB})
	set(USE_PICOLIBC ON)
endif(DEFINED ENV{USE_PICOLIB})

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR ARM)
set(CMAKE_C_OUTPUT_EXTENSION .o)

set(PREFIX arm-none-eabi-)
set(PATH_TOOLCHAIN_PREFIX $ENV{PATH_GCC_CORTEXM}/bin/arm-none-eabi-)
set(CMAKE_C_COMPILER "${PATH_TOOLCHAIN_PREFIX}gcc")
set(CMAKE_CXX_COMPILER "${PATH_TOOLCHAIN_PREFIX}g++")
set(CMAKE_AR "${PATH_TOOLCHAIN_PREFIX}ar")
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
set(CMAKE_LINKER "${PATH_TOOLCHAIN_PREFIX}ld")
set(CMAKE_OBJCOPY "${PATH_TOOLCHAIN_PREFIX}objcopy")
set(CMAKE_OBJDUMP "${PATH_TOOLCHAIN_PREFIX}objdump")
set(CMAKE_RANLIB "${PATH_TOOLCHAIN_PREFIX}ranlib")
set(CMAKE_STRIP "${PATH_TOOLCHAIN_PREFIX}strip")
set(CMAKE_SIZE "${PATH_TOOLCHAIN_PREFIX}size")

set(GENERATE_LST ${PATH_TOOLCHAIN_PREFIX}objdump -f -p -D -d -h -t -s)
set(GENERATE_DIS ${PATH_TOOLCHAIN_PREFIX}objdump -S)

set(CORE_ENDIANNESS "LITTLE_ENDIAN")

# Common flags for arm bare-metal
if(USE_PICOLIBC OR DEFINED ENV{USE_PICOLIB})
set(CMAKE_C_FLAGS_INIT "--specs=picolibc.specs -mthumb")
else()
set(CMAKE_C_FLAGS_INIT "-mthumb")
endif()
set(CMAKE_CXX_FLAGS_INIT "-fno-rtti -fno-exceptions")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-nostartfiles")

```

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [January 19, 2024, 6:00pm UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/11 "2024-01-19T18:00:52Z")

</div>

It looks like it is supposed to be the compiler module that overrides it based on the comment before the setting you found. I think an issue might be in order to allow toolchain files to set it by guarding it with `if (NOT CMAKE_C_OUTPUT_EXTENSION)`. Can you please [file an issue](https://gitlab.kitware.com/cmake/cmake/-/issues) about this?

---

<div class="post-metadata">

### Author: ![fdk17](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/ea666f/32.png) [@fdk17](https://discourse.cmake.org/u/fdk17)
#### Post date: [January 19, 2024, 11:21pm UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/12 "2024-01-19T23:21:12Z")

</div>

Isn’t this the same issue? [https://gitlab.kitware.com/cmake/cmake/-/issues/18713](https://gitlab.kitware.com/cmake/cmake/-/issues/18713)

---

<div class="post-metadata">

### Author: ![Laur59](https://discourse.cmake.org/user_avatar/discourse.cmake.org/laur59/32/4200_2.png) [@Laur59](https://discourse.cmake.org/u/Laur59)
#### Post date: [January 20, 2024, 12:20pm UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/13 "2024-01-20T12:20:40Z")

</div>

Yes, looks like similar issue. It has not been addressed in 5 years, shall file a new issue anyway??

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [January 20, 2024, 9:33pm UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/14 "2024-01-20T21:33:46Z")

</div>

No point filing a new issue, it would just be closed as a duplicate of the existing one.

---

<div class="post-metadata">

### Author: ![dimich-dmb](https://discourse.cmake.org/user_avatar/discourse.cmake.org/dimich-dmb/32/6124_2.png) [@dimich-dmb](https://discourse.cmake.org/u/dimich-dmb)
#### Post date: [May 6, 2026, 3:45am UTC](https://discourse.cmake.org/t/generate-o-files-from-compiler-instead-of-obj-files/2690/15 "2026-05-06T03:45:09Z")

</div>

I encountered the same issue while building bare metal project under Linux host. Minimal reproducible CMakeLists.txt:

```auto
cmake_minimum_required(VERSION 3.16)

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(TOOLCHAIN_PREFIX arm-none-eabi-)

set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy)
set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump)

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

project(test C)

add_compile_options(-mcpu=cortex-m4 -mthumb -ffreestanding)
add_library(${PROJECT_NAME} STATIC foo.c)

```

`foo.c` is just empy file.

Since conventional suffix for ELF object files is `.o` (e.g. `gcc -c` produces `.o` if no explicit output name specified), I would expect `libtest.a` containing `foo.c.o`, but

```auto
$ ar -t build/libtest.a 
foo.c.obj

```

I used custom tool to analyze sections contents in object files. It relies on `.o` suffix, so I spent an hour trying to figure out why it fails.  
In most cases suffix actually has no functional impact, but at least it is very unexpected.

Dirty workaround is to configure project with `cmake -DUNIX=1`. Unfortunately, this doesn’t work when specified in CMakeLists.txt as `set(UNIX, 1)`. Also I’m not sure about possible unwanted side effects of such workaround.

Possible fix could be

- Fallback to a suffix specific for HOST if not defined explicitly for TARGET (`Generic` in this case).  
or
- Autodetect compiler’s default suffix during configuration, i.e. run `gcc -c ...` without `-o` and check for produced output file. But this seems too complicated.  
or
- Allow to override suffix in `CMakeLists.txt` or toolchain .cmake file.
