0
  1. I have target for shared and want it to run command after build ONLY if the Target output file changed, or same for me if build is updating. In my example command runes every time when I build project, but I need it to run Only if after build Target output file changed
cmake_minimum_required(VERSION 3.21)

project(myexp)

add_library(Example SHARED source.cpp)

set_target_properties(Example  PROPERTIES 
        RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin$<0:>"
    )

add_custom_command(TARGET Example POST_BUILD  
        COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:Example> ${CMAKE_CURRENT_SOURCE_DIR}/new
        DEPENDS Example
    )

DEPENDS doesnt work here

from documentation - add_custom_command

The second signature adds a custom command to a target such as a library or executable. 
This is useful for performing an operation before or after building the target. 
The command becomes part of the target and will only execute when the target itself is 
built. 
If the target is already built, the command will not execute.

maybe my understanding of this is wrong

  1. is there a way to Multi-OUTPUT

THANK YOU

  • `DEPENDS doesnt work here` In what way it does not work? How doyou know it does not work? `is there a way to Multi-OUTPUT` What does that mean? What is "Multi-OUTPUT"? – KamilCuk Sep 01 '21 at 11:17
  • @KamilCuk I have target for shared and want it to run command after build if the Target output file changed – Hayk Poghosyan Sep 01 '21 at 11:45
  • @KanilCuk Multi-OUTPUT - output dll file to more then one directories – Hayk Poghosyan Sep 01 '21 at 11:48
  • Remove `DEPENDS Example`. The form with `POST_BUILD` does not use it. It runs `POST_BUILD` it already knows when to run. – KamilCuk Sep 01 '21 at 12:54
  • @KamilCuk it runes COMMAND every time I build, but I need it to run Only if after build - Target output file (Example.dll) changed – Hayk Poghosyan Sep 01 '21 at 13:00
  • Despite the same command name, signatures `add_custom_command(OUTPUT)` and `add_custom_command(TARGET)` denote very **different cases**. If you want to run a command conditionally, then use the first signature, with OUTPUT. Have you tried that? In that case you also need `add_custom_target`, which depends on OUTPUT of the custom command. – Tsyvarev Sep 01 '21 at 13:22
  • @Tsyvarev yes I know about that. but with `add_custom_command(TARGET)` I can be sure that the command will be executed after build, becouse I use POST_BUILD. But I find another interesting fact , that if I build with visual studio, it works ok , if I build with cmake --build . I have this problem – Hayk Poghosyan Sep 01 '21 at 14:06
  • "I can be sure that the command will be executed after build" - If you want to run the command after the target `Example` is built, then `DEPENDS Example` serves exactly that purpose. Standard Makefile-like dependencies are expressed with signature `add_custom_command(OUTPUT)`. Despite being shorter (it doesn't require additional `add_custom_target`), the signature `add_custom_command(TARGET)` is almost always a **wrong tool** for that purpose. – Tsyvarev Sep 01 '21 at 14:12
  • @Tsyvarev : You meen this way ` set_target_properties(Example PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin$<0:>" ) ``` add_custom_command(OUTPUT dummy.file COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_SOURCE_DIR}/new DEPENDS Example )``` – Hayk Poghosyan Sep 02 '21 at 06:54
  • Yes, you could use something like this. Do not forget `add_custom_target` which depends on `dummy.file`. – Tsyvarev Sep 02 '21 at 06:57
  • @Tsyvarev: and how to do custom_target build every time I build solution? – Hayk Poghosyan Sep 02 '21 at 07:02
  • Probably you asked about `ALL` option for `add_custom_target`. See also that question: https://stackoverflow.com/questions/43885692/build-custom-target-by-default-in-cmake – Tsyvarev Sep 02 '21 at 07:07
  • @Tsyvarev: OK it works with `ALL`, but if dummy file is really exist, if I understand right, we can't use fake dummy file, we need really create it or use file which is exists . thank You for the help – Hayk Poghosyan Sep 02 '21 at 07:21
  • Ideally, `add_custom_command` should specify in OUTPUT "useful" file(s) which it produces. In your case, it is `${CMAKE_CURRENT_SOURCE_DIR}/new/$`, which is result of copying of the executable. But OUTPUT clause in CMake doesn't support generator expression. – Tsyvarev Sep 02 '21 at 07:31
  • Note also, that when building the project, you normally don't want to create anything in the **source tree** (under `${CMAKE_CURRENT_SOURCE_DIR}/new` in your case). If you want to **deliver** some build artifacts to the user, then **install** the project. CMake has rich support for project's installation, which doesn't required to be a system-wide installation: you could specify any directory where the project will be installed. – Tsyvarev Sep 02 '21 at 07:35
  • @Tsyvarev: I created an example to understand how everything works, on a real project, of course, I need to do everything as it should, I have another question please: how to make targets so that some are not built if Linux gcc and vice versa, and how do targets built in special order except add_dependencies method – Hayk Poghosyan Sep 02 '21 at 07:54
  • "how to make targets so that some are not built if Linux gcc and vice versa" - Just define this targets conditionally, under `if` clause. About checking OS, see [that question](https://stackoverflow.com/questions/9160335/os-specific-instructions-in-cmake-how-to), about checking compiler see [that question](https://stackoverflow.com/questions/10046114/in-cmake-how-can-i-test-if-the-compiler-is-clang). "how do targets built in special order except add_dependencies method" - It is impossible. `add_dependencies`, `target_link_libraries` and DEPENDS clauses are the only which can affect ordering. – Tsyvarev Sep 02 '21 at 08:03

0 Answers0