How do I produce only an object file (*.o) from a CMake build target?

Nick picture Nick · Jan 22, 2011 · Viewed 9.3k times · Source

I'm trying to build an object file using CMake, but I can't seem to get CMake to build something other than a complete executable. I'm basically looking for the result of the following compilation (the result will be loaded on a VxWorks target and linked then):

$(CC) $(CFLAGS) $(INC_DIRS) -c src/object.c

I've tried changing the OUTPUT_NAME property of the target, but that doesn't seem to help, either.

I think I could work around this by using a custom command, but that seems like I'm also working around the nice things that CMake provides.

Thanks for your help!

Answer

watashi16 picture watashi16 · Mar 28, 2011

This answer was given to me in the CMake mailing list and it worked like a charm:

Look at the following ${CMAKE_SOURCE_DIR}/cpo script:

#!/bin/sh
d=$1; shift
while [ "$1" != "--" ]; do
    cp $1 $d/$(basename $1); shift
done

Now, look at the following CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(CPO C) 
FILE(WRITE ${CMAKE_BINARY_DIR}/f.c "void f(void){}\n")
ADD_LIBRARY(f SHARED f.c)
SET_TARGET_PROPERTIES(f PROPERTIES RULE_LAUNCH_LINK
    "${CMAKE_SOURCE_DIR}/cpo ${CMAKE_BINARY_DIR} <OBJECTS> --"
)

The launch script "cpo" makes the target "f" produce object files in the directory passed in as the first parameter instead of a library; everything else should be business as usual. The key is the script's access to the <OBJECTS> placeholder, so it can operate on the object files while the actual link command after the "--" is ignored. That way, you can use all of CMake's capabilities for the compilation and intercept right before linking takes place. IMO, that's a quite clean solution which should be easily adaptable to your needs; the downside is that the use of RULE_LAUNCH_LINK is limited to Makefile generators.