0

My top-level project has a number of "subprojects".

Each of those subprojects uses a different compiler toolchain than my top-level project. Each subproject has a toolchain file. Some subprojects build host executables, others generate executables for use on other platforms.

In my top-level project, I generate the CMakeLists.txt for each subproject using configure_file()...

project(topProject ...)
...
configure_file(${CMAKE_SOURCE_DIR}/cmake/subproject_template.cmake
               ${CMAKE_CURRENT_BINARY_DIR}/subA/CMakeLists.txt
               @ONLY)
...

I cannot use add_subdirectory(subA) here, because that file needs a different toolchain, so I presume I need to create a custom target (still in the top-level project) to actually build that subproject...

add_custom_target(build_subA
  DEPENDS ...
  COMMAND
    ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/subA/build
  COMMAND
    ${CMAKE_COMMAND}
      -DCMAKE_TOOLCHAIN_FILE="${CMAKE_SOURCE_DIR}/cmake/toolchain_subA.cmake"
      -G${CMAKE_GENERATOR}
      -S${CMAKE_CURRENT_BINARY_DIR}/subA
      -B${CMAKE_CURRENT_BINARY_DIR}/subA/build
  COMMAND
    ${CMAKE_COMMAND}
      --build ${CMAKE_CURRENT_BINARY_DIR}/subA/build
      --target subA
  )

Of course, elements in the subproject can depend on elements in my top-project. That seems straightforward as subproject_template.cmake will define IMPORTED libraries from my topProject (and will use find_executable() and find_file(), etc. DEPENDS in the build_subA target above will ensure that everything is ready for the subproject.

Dependencies the OTHER way seem more difficult. It's difficult to import subA back into topProject...

# I cannot do this (or similarly for add_library) because these are
# typically not for the host platform, and the file does not exist when
# cmake builds on the topProject
add_executable(subA)
set_target_properties(subA PROPERTIES
                    # This file does not exist when cmake builds topProject
  IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/subA/build/subA_target_file.exe
)  # Cannot use `$<TARGET_FILE_DIR>` or `$<TARGET>` from other projects either...?


# What I can do is directly *use* the things in the subprojects...
add_custom_target(
  DEPENDS  build_subA
  COMMAND
    foo --elf=${CMAKE_CURRENT_BINARY_DIR}/subA/build/subA_target_file.exe ...
)

What's the right way to do this? Thank you!

Lance E.T. Compte
  • 932
  • 1
  • 11
  • 33
  • 2
    "What I can do is directly *use* the things in the subprojects" - Yes, this is a proper way for use files created by a custom target. Not sure what kind of "the right way" you are looking for. You could also replace `add_custom_target(build_subA)` with corresponding ExternalProject, see e.g. [that question](https://stackoverflow.com/q/15175318/3440745) and its answers. – Tsyvarev May 08 '23 at 22:42
  • @Tsyvarev, should I declare my subproject with `ExternalProject_Add()` so I can use its build and things like `ExternalProject_Get_Property()` to fetch target names, directories, etc.? – Lance E.T. Compte May 08 '23 at 23:13
  • @LanceE.T.Compte where did you get that you can get target and directory names using [`ExternalProject_Get_Property`](https://cmake.org/cmake/help/latest/module/ExternalProject.html#command:externalproject_get_property)? – starball May 08 '23 at 23:35
  • 1
    @LanceE.T.Compte: If you want to access in the super-project targets, which a defined in a sub-project, then you need to configure a sub-project as a part of super-project, by using `add_subdirectory` approach (or its specialization, FetchContent). If you build a sub-project by using `add_custom_target` (or its specialization, ExternalProject), then you have no access to its targets. That is, both approaches - `add_subdirectory` and `add_custom_target` - have their own advantages and disadvantages. – Tsyvarev May 09 '23 at 08:36
  • I understand @Tsyvarev... Thanks again... It's just difficult to say... `This thing has dependencies in the top project. Once they are all ready, go build the thing using a different toolchain. Once that is done, other things in top-project can continue.` What I sortof find myself wanting to do is to `set_target_property()` on a `TOOLCHAIN` property so it will use a different toolchain to build that target. People used to use project-level things like `include_direcories()` and now we use `target_include_directories()`. It's the same idea I find myself thinking about... – Lance E.T. Compte May 09 '23 at 16:12

0 Answers0