So I know there’s a couple of questions that sound similar to this topic, but I’ve yet to actually find a good/working solution to this.
My project has the following dependency chain: application → core tech → external libraries. There are multiple applications each depending on a single core tech library, and many external libraries all pulled in as dependencies by that same single core tech library. The core tech library is built as a static library and linked into each executable. (This of it as a game engine with games using the engine library, and the engine library depending on external / third party stuff)
This is all working great except now I need to add a new external library that requires a folder to be placed at a specific path relative to each executable. (For reference this is Microsoft’s Agility SDK, which requires constants of the relative path and a version number to be compiled into, and exported from, each executable, and those additional files to be placed at that location relative to the executable).
This library doesn’t come with any import libs or direct dependency runtime libs or anything of concern to the linker, it just offers more recent include files (d3d12.h et.al.) that are to be placed earlier in the include path to shadow the ones offered by the Windows SDK. However, since I need to link and export that hardcoded path and current version number into the executable, I’m generating a cxx file and building this as a static library instead of an imported library (but I could change that if it has any significant impact on the available solutions).
Now the million dollar question is: how can I ensure that this folder of additional files gets copied next to each executable that sets up a dependency on the core tech library?
What I am doing right now is a horrible hack of passing the source path as a variable all the way up the chain (set PARENT_SCOPE in many CMakeLists files) and for each add_executable target manually adding a POST_BUILD command copy_directory_if_different that makes sure the folder gets copied next to the executable. However, I would really like the top-level executable to not have to be bothered with internal details of any indirect dependency that might need to copy files.
Is there a proper / more automatic way of achieving this? Note that I’m not looking for an install solution since this also needs to work when just building and debugging binaries.
There’s no mechanism for adding commands as usage requirements. I’m not sure how that would work either, in general.
I think the easiest thing to do here might be to prep the directory once and put all executables in a common location (e.g., set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") or something).
I don’t think that will work since the location needs to be compiled into the exe. I would have to move the files for install at which point they would no longer match the compiled path.
You can add a definition as a usage requirement to provide the (relative?) path to the executable.
As for install locations, I would recommend having the build tree look as much like the install tree as possible so that these kinds of path lookups can be shared between them.
Thanks for the suggestions, but perhaps I’m misunderstanding your intention. My build tree looks roughly like this
app1
|- build
|- x64-dbg-clang
|- binaries here
|- x64-rel-clang
|- binaries here
|- x64-dbg-msvc
|- binaries here
.....
app2
|-build
|- x64-dbg-clang
|- binaries here
.....
Since the library doesn’t know anything about what might be using it, I assume you mean I should copy the additional files to a folder at sibling level to app1/app2, and then the compiled in path would either be ../../../shared_prebuilt, or an absolute path? That’s what I meant with not matching the install layout, when installed I need the path to be something like ./prebuilt. (I don’t think I would want to put all my apps and targets into a single binary folder, so if that’s what you meant that’s not really an option for me.)
What I’ve “resigned” to doing now is defining some “well-known” properties that targets can set if they have stuff that needs copying, and I made a function that is essentially target_link_libraries_and_copy_additionals that will optionally copy anything that might need copying. It still requires some awareness of the fact and explicit effort when adding dependencies for an exe, but at least it’s a single function replacement and not extra code that has to be copy-pasted directly into each exe make lists.