2

I have a CMake configuration file building two libraries:

  1. a third-party library (here called ThirdPartyLib) containing a real-time OS / board support package from a supplier. It is built outside CMake using the autotools toolchain.
  2. an extended version of the former library (here called ExtendedThirdPartyLib)

Unfortunately, some source code that I need (various tools) are not built in the ordinary build script for (1). Since I don't want to mess with the suppliers build script I want to add another library (2), building the missing files and thus extending the library from the supplier.

I want to able to do something like this in CMakeFiles.txt:

cmake_minimum_required(VERSION 3.2) project(bsp) include(ExternalProject) ExternalProject_Add( ThirdPartyLib URL <http://some.url/bsp.tar.bz2 BUILD_COMMAND make -C ../external/ThirdPartyLib/src ) set_target_properties(ThirdPartyLib PROPERTIES EXCLUDE_FROM_ALL TRUE) add_library(ExtendedThirdPartyLib ${CMAKE_CURRENT_BINARY_DIR}/some/path/missing_file1.c ${CMAKE_CURRENT_BINARY_DIR}/some/path/missing_file2.c ) add_dependencies(ExtendedThirdPartyLib ThirdPartyLib) target_include_directories(ExtendedThirdPartyLib PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/some/path/include ) target_link_libraries(ExtendedThirdPartyLib ThirdPartyLib) 

The problem here is that the path to missing_file1.c and missing_file2.c are not valid when CMake is generating the build files (they are extracted from the tarball from the supplier). CMake exits with an error output saying: "Cannot find source file".

Is there a neat way to make this work? I.e. is it possible to convince CMake that certain non-existant input files will exist when building of the library begins? Or is there any other recommended way to solve this issue?

(I have temporary made local copies of the files I need to build from the suppliers tarball, but that is of course not a good solution. If those files are changed in future versions of the suppliers package and I forget to overwrite my local copies it could be a horrible mess...

Another "solution" would be to create a small makefile outside CMake and use another ExternalProject_Add in the CMakeFiles.txt somehow. But that's not a good solution either, e.g. if compile and linker flags are modified I need to remember to change the makefile too.)

1 Answer 1

1

Personally, I dislike the ExternalProject_Add command, because it does way too many things for my taste, but I've digressed.

What if you do something like this, where bar is simulating your ExtendedThirdPartyLib target, since it depends on generated files

cmake_minimum_required(VERSION 3.11) project(lol C) set(SOURCES lol.c) # only this file exists add_library(lol ${SOURCES}) set(FOO_FILES "foo1.c" "foo2.c") add_custom_command(OUTPUT ${FOO_FILES} COMMAND ${CMAKE_COMMAND} -E touch ${FOO_FILES} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMENT "Creating ${FOO_FILES}" VERBATIM) add_custom_target(foo DEPENDS ${FOO_FILES}) add_library(bar ${FOO_FILES}) add_dependencies(bar foo) target_link_libraries(lol bar) 

The whole approach hinges on the fact that the method, where produced/generated files are procured, is explicitly defined via the custom command and associated custom target.

You should modify the custom command to extract the required files (e.g. could even call some external script) from the tarball (which might require downloading with curl or something similar).

Sign up to request clarification or add additional context in comments.

2 Comments

It seems to work! Although I don't quite understand why. If I understand it correctly a custom command is run during the actual build (not when generating build files). So the input source files to bar still don't exist when generating the build files, but CMake seems ok with that in this case.
@arghol yes, that's correct, plus the dependency 'link' between the custom command and custom target (see my comment after the dummy CMakeLists.txt that I posted). Also, have a look at the doc about those two commands, it's quite good and more complete than any answer I could give here.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.