DEV Community

Jacob Hummer
Jacob Hummer

Posted on • Edited on • Originally published at jcbhmr.me

1

Use cosmocc to cross‐compile a CMake project

We know how to compile an Autotools project using cosmocc but how do you compile a CMake project with cosmocc?

Here's an example project:

main.c

#include <stdio.h>

int main() {
    puts("Hello world!");
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

CMakeLists.txt

cmake_minimum_required(VERSION 3.29)
project(hello-world LANGUAGES C)
add_executable(hello-world main.c)
Enter fullscreen mode Exit fullscreen mode

You can almost just do CC=cosmocc cmake ... and call it day. Almost. But not quite! 😉 There are some other CMake settings you need to set to get things to work well with cosmocc.

First, you'll need to add a CMAKE_USER_MAKE_RULES_OVERRIDE file to define the object suffix as .o instead of .obj. cosmocc currently doesn't work if the object extension is not .o. 🤷‍♀️

cosmocc-override.cmake

set(CMAKE_ASM_OUTPUT_EXTENSION .o)
set(CMAKE_C_OUTPUT_EXTENSION .o)
set(CMAKE_CXX_OUTPUT_EXTENSION .o)
Enter fullscreen mode Exit fullscreen mode

Why can't we just specify -DCMAKE_C_OUTPUT_EXTENSION=".o" on the command line? It needs to be defined after the Generic configuration is loaded so it doesn't get reset to the default .obj. CMAKE_USER_MAKE_RULES_OVERRIDE is the recommended way to do it. https://gitlab.kitware.com/cmake/cmake/-/issues/18713

ASM="cosmocc" \
CC="cosmocc" \
CXX="cosmoc++" \
cmake \
  -DCMAKE_SYSTEM_NAME="Generic" \
  -UCMAKE_SYSTEM_PROCESSOR \
  -DCMAKE_USER_MAKE_RULES_OVERRIDE="$PWD/cosmocc-override.cmake" \
  -DCMAKE_AR="$(command -v cosmoar)" \
  -UCMAKE_RANLIB \
  -B build
Enter fullscreen mode Exit fullscreen mode
-- The C compiler identification is GNU 12.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /somewhere/cosmocc/bin/cosmocc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done (2.9s)
-- Generating done (0.0s)
-- Build files have been written to: /somewhere/hello-world/build
Enter fullscreen mode Exit fullscreen mode

Do I have to specify CMAKE_SYSTEM_NAME and CMAKE_SYSTEM_PROCESSOR? Yes. They configure some CMake magic internally and configure what your CMakeLists.txt thinks it's compilation target is.

Why not CMAKE_SYSTEM_NAME="Linux"? So that if(LINUX) and other Linux-specific stuff in CMakeLists.txt doesn't activate for unknown-unknown-cosmo.

Why not CMAKE_SYSTEM_PROCESSOR="unknown"? unset is what means unknown-unknown-cosmo to CMake. CMake internals use if(CMAKE_SYSTEM_PROCESSOR), not if(CMAKE_SYSTEM_PROCESSOR STREQUAL unknown).

Why does CMAKE_AR need to be an absolute path? Unfixed issue. https://gitlab.kitware.com/cmake/cmake/-/issues/18087

Why does CMAKE_RANLIB need to be unset? CMake gates using ranlib behind if(CMAKE_RANLIB) so it must be unset not just an empty string. cosmocc doesn't bundle a cosmoar.

Why can't we do AR="cosmoar" like CC and CXX? Unfixed issue. https://gitlab.kitware.com/cmake/cmake/-/issues/18712

Now that the project is configured with all the compiler settings and other magic✨ we can run the build step:

cmake --build build
Enter fullscreen mode Exit fullscreen mode
[ 50%] Building C object CMakeFiles/hello-world.dir/main.c.o
[100%] Linking C executable hello-world
[100%] Built target hello-world
Enter fullscreen mode Exit fullscreen mode

You just made a magic✨ binary! 🥳

On Windows you need to rename it or symlink it to have an .exe or .com suffix to execute it.

./build/hello-world     
Enter fullscreen mode Exit fullscreen mode
Hello world!
Enter fullscreen mode Exit fullscreen mode

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (0)

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay