36

I have an add_custom_target that triggers a make for a project (that project does not use cmake!) and generates an object file. I would like to add this object file to an executable target in my project's cmake. Is there a way to do this?

bstpierre
  • 30,042
  • 15
  • 70
  • 103
mkmostafa
  • 3,071
  • 2
  • 18
  • 47
  • As of Cmake 3.9.6 you can import object libraries, see: https://stackoverflow.com/q/51344020/1151724 ...Although it is probably more ponderous for a single object who's path could just be put in a variable. – CodeClown42 Jul 15 '18 at 12:28

4 Answers4

21
SET(OBJS
  ${CMAKE_CURRENT_SOURCE_DIR}/libs/obj.o
)

ADD_EXECUTABLE(myProgram ${OBJS} <other-sources>)

SET_SOURCE_FILES_PROPERTIES(
  ${OBJS}
  PROPERTIES
  EXTERNAL_OBJECT true
  GENERATED true
)

That worked for me. Apparently one must set these two properties, EXTERNAL_OBJECT and GENERATED.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
mkmostafa
  • 3,071
  • 2
  • 18
  • 47
  • 6
    The code snippet lacks of `add_executable()` call with object file as one of its argument. It confuses some readers, like this one: https://stackoverflow.com/questions/48209751/cmake-mingw-compiler-flag-finstrument-functions. – Tsyvarev Jan 11 '18 at 19:54
  • @Tsyvarev Your comment is very valuable. I suggest you edited the answer yourself since almost a year has passed – kyriakosSt Dec 17 '18 at 10:26
21

I've done this in my projects with target_link_libraries():

target_link_libraries(
    myProgram 
    ${CMAKE_CURRENT_SOURCE_DIR}/libs/obj.o
)

Any full path given to target_link_libraries() is assumed a file to be forwarded to the linker.


For CMake version >= 3.9 there are the add_library(... OBJECT IMPORTED ..) targets you can use.

See Cmake: Use imported object


And - see also the answer from @arrowd - there is the undocumented way of adding them directly to your target's source file list (actually meant to support object file outputs for add_custom_command() build steps like in your case).

Florian
  • 39,996
  • 9
  • 133
  • 149
  • 1
    It's assuming i'm trying to link a library, not a regular .o file when I try this. –  Jul 19 '17 at 10:19
  • @DrEval Yes, you need to know what CMake is doing here and that's the ugly part about this approach. I think it's also about your personal taste: Is an external object file more a "source file" or an "something to link with file". – Florian Jul 19 '17 at 19:33
4

You can list object files along sources in add_executable() and addlibrary():

add_executable(myProgram
   source.cpp
   object.o
)

The only thing is that you need to use add_custom_command to produce object files, so CMake would know where to get them. This would also make sure your object files are built before myProgram is linked.

arrowd
  • 33,231
  • 8
  • 79
  • 110
  • I have tried this but it does not work! I did a verbose cmake and the object file is not mentioned at all during linking! I'm giving the full path using ${CMAKE_CURRENT_SOURCE_DIR}/libs/objectfile.o – mkmostafa Jul 27 '16 at 09:52
  • Does it exist at the moment you run CMake? – arrowd Jul 27 '16 at 10:25
  • I've found the solution. It's similar to what you suggested only with a small adaptation. :) – mkmostafa Jul 27 '16 at 10:28
  • 14
    @mkmostafa When you find the solution and take the time to comment, it'd be great to actually post what that was. – Josh Sep 15 '17 at 04:14
  • @josh the solution that mkmostafa found is the accepted answer – skelliam Feb 06 '21 at 16:31
1

Starting from CMake version 3.9:

# Imported object library
add_library(someObjsLib OBJECT IMPORTED)

set_property(TARGET someObjsLib PROPERTY 
    IMPORTED_OBJECTS /some/path/obj1.o
                     /some/path/obj2.o
)

add_executable(myExe $<TARGET_OBJECTS:someObjsLib>)

IMPORTED_OBJECTS && Professional CMake

Ernie Sanderson
  • 382
  • 2
  • 10