My project has 3 shared libraries, and 2 executables.
During the Install phase, everything is copied to the correct location. However when debugging, the shared libraries must be copied into the directory where the executable being debugged is created.
This is easy enough to do using add_custom_command( TARGET exe POST_BUILD <COPY_CMD>)
Where the copying of the file command is <COPY_CMD>
However, I need this function to be run not only when the executable is linked, but when the shared library is built as well. Otherwise the executable can be run on the old shared library.
Ive tried the add_custom_command for the shared library, because the
The copy command, in general is something like
${CMAKE_COMMAND} -e copy srcfile $<TARGET_FILE_DIR:executable>
which leaves me to the following problem
CMake Error at (add_custom_command):
TARGET âexecutableâ was not created in this directory.
A common alternative solution to Windowsâ lack of something like RPATH is to set the output directory of all executables and shared libraries to the same location. It isnât always feasible (and personally I dislike it, since the clutter is considerable for large projects), but if it suits your situation, that is probably the simplest way to get easily debuggable binaries. Projects taking this approach typically set CMAKE_RUNTIME_OUTPUT_DIRECTORY sufficiently high in their directory structure to capture all the executables and shared libraries the project defines. You would also need to check how this might affect dependencies also built by the project. Another wrinkle is test executables - sometimes there could be very many of these, and you might not want them mixed in with the non-test executables.
I generally discourage copying around DLLs in POST_BUILD rules. You end up with multiple copies of your DLLs littered around your build directory and itâs easy to end up using an out-of-date DLL. As youâve discovered, it isnât always easy to get the DLLs you want copied, and it gets combinatorially worse the more executables you have that need your DLLs. Furthermore, you may also need to copy around PDBs (I donât recall if thatâs needed or not). Given the downsides, if you can avoid copying DLLs around like this, that would be better.
List of DLLs that the target depends on at runtime. This is determined by the locations of all the SHARED and MODULE targets in the targetâs transitive dependencies. Using this generator expression on targets other than executables, SHARED libraries, and MODULE libraries is an error. On non-DLL platforms, it evaluates to an empty string.
This generator expression can be used to copy all of the DLLs that a target depends on into its output directory in a POST_BUILD custom command. For example:
Imported Targets are supported only if they know the location of their .dll files. An imported SHARED or MODULE library must have IMPORTED_LOCATION set to its .dll file. See the add_library imported libraries section for details. Many Find Modules produce imported targets with the UNKNOWN type and therefore will be ignored.
Do you know if the variable is modifiable? or only determinable by the system.
Ill have to investigate how âruntimeâ is determined in "depends on at runtime. My bet its defined as statically bound shared libraries, that the executable requires to launch properly. Which means I may need to tweak it a bit, because I have a couple of âdynamically bound when needed by the executableâ runtime dependencies (plug ins)
2 of them are dynamically bound, dynamically loaded image formats (One is a viewer for BIF/Roku index images for Qt, the other is a Multi-Frame GIF writer for Qt as well)
The main application, doesnt even know they âexistsâ until the Qt image system loads them up. But they have to be placed in the correct location, and updated if they change.
One of the remaining two, is statically bound dynamically loaded. When the exe is built, its easy to add a custom command (and now using the TARGET_RUNTIME_DLLS variable) to copy those files into the correct location for debugging.
The final dll, is statically bound inside the previous dll. So I am working to use TARGET_RUNTIME_DLLS on the other DLL to get this DLL for copy.
However, what I cant figure out, is what is the best way to copy the DLLs (all 4) when any of them is built.
Meaning, I tweaked my image processing DLL, and I need to copy it into the image format directory. Nothing in its API changed, so there were no triggers to rebuild the main executableâŚ
The only good solutions are either RUNTIME_OUTPUT_DIRECTORY target property or a qt.conf (but IIRC you can only specify one directory for each setting).
The problem with the external libraries for Qt, is they have to be in the correct location. For me, since two are image formats, in the âexecutable/imageformatsâ directory
So VS_DEBUGGER_ENVIRONMENT for PATH alone wont work, I forget if Qt has another env var I can set for find plugins
On Windows, libraries are split into a .lib for the linker and a runtime part, the .dll. These can go into two different directories.
The problem is, it always adds Debug/Release etc after the OUTPUT_DIRECTORY
I need to set both LIBRARY_OUTPUT_DIRECT and RUNTIME_OUTPUT_DIRECTORY if I want the .lib, .pdb and .dll in the same directory. Once I realized the DLL/PDB are runtime targets I was able to set this up.
Unfortunately, due to linux limitations, you can not set the OUTPUT_NAME to âŚ/libname