0

I am trying to copy an output of my CMake Project to another directory, but it does not work. It says : Error copying file .

My project looks like this:

A----
    |----B 
    |    |
    |    |
    |    |-----CmakeListB 
    |
    | 
    |
    | 
    |
    |-----C
    |     |
    |     |
    |     |------CmakeListC       
    |
    |
    |-----CmakeListA   

And A is my topest project. B is A sub project , to build dll C is A sub project , to build exe

What I describe above does not matter.

I try to copy dll built by B to another dir, I write command like this, but it not work.(On Windows7, VS2017)

   add_custom_command(
TARGET HOOK_SRC POST_BUILD 
COMMAND ${CMAKE_COMMAND} -E copy    
${CMAKE_CURRENT_BINARY_DIR}/MSP_S_HOOK.dll 
${CMAKE_CURRENT_BINARY_DIR}/1/MSP_S_HOOK.dll)  

CmakeList like below


project(eSDK_MSP C CXX)

cmake_minimum_required(VERSION 3.8)

foreach (policy
        CMP0074)
    if (POLICY ${policy})
        cmake_policy(SET ${policy} NEW)
    endif ()
endforeach ()


if (POLICY CMP0074)
    cmake_policy(SET CMP0074 NEW)
endif ()

set(CMAKE_CXX_STANDARD 11)

if (MSVC)

endif ()
if (MINGW OR CYGWIN)
    add_definitions(-O3)
    link_libraries(ws2_32 mswsock)
    if (USE_32BITS)
        message("build x86 target")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
    else ()
        message("build x64 target")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64")
    endif (USE_32BITS)
endif ()

ADD_DEFINITIONS(-DBOOST_COROUTINES_NO_DEPRECATION_WARNING)

macro(get_WIN32_WINNT version)
    if (WIN32 AND CMAKE_SYSTEM_VERSION)
        set(ver ${CMAKE_SYSTEM_VERSION})
        string(REPLACE "." "" ver ${ver})
        string(REGEX REPLACE "([0-9])" "0\\1" ver ${ver})
        set(${version} "0x${ver}")
    endif ()
endmacro()

get_WIN32_WINNT(ver)
add_definitions(-D_WIN32_WINNT=${ver})


set(Boost_USE_STATIC_LIBS ON) # enable dynamic linking
set(Boost_USE_MULTITHREAD ON)  # enable multithreading
set(Boost_USE_STATIC_RUNTIME OFF)
message(${CMAKE_BINARY_DIR})

find_package(BOOST REQUIRED)

if (NOT Boost_FOUND)
    message("not found boost package")
else ()
    message("found boost package")
    include_directories(${Boost_INCLUDE_DIR})
    LINK_DIRECTORIES(${CMAKE_LIBRARY_PATH} $ENV{BOOST_LIBRARYDIR})
    message("includes: ${Boost_INCLUDE_DIRS}")
    message("libs: $ENV{BOOST_LIBRARYDIR}")
endif ()


include_directories("."
        "../MSP_S/src/window"
        )

set(HOOK_SRC
        dllmain.cpp
        ../MSP_S/src/window/ShmUtils.h
        HOOK.def)

ADD_LIBRARY(HOOK_SRC SHARED ${HOOK_SRC})
target_link_libraries(HOOK_SRC wsock32 ws2_32 )
#MESSAGE(..)

if (MSVC)
#    if (CMAKE_CL_64)
#        add_custom_command(TARGET HOOK_SRC POST_BUILD
#                COMMAND ${CMAKE_COMMAND} -E copy
#                "MSP_S_HOOK.dll"
#                ${OUTPUT_DIR}"MSP_S_HOOKx64.dll")
#    else ()
#        add_custom_command(TARGET HOOK_SRC POST_BUILD
#                COMMAND ${CMAKE_COMMAND} -E copy
#                "MSP_S_HOOK.dll"
#                ${OUTPUT_DIR}"MSP_S_HOOKx86.dll")
#    endif ()
endif ()

message("hook "  ${TARGET_FILE_DIr})


add_custom_command(
TARGET HOOK_SRC POST_BUILD 
COMMAND ${CMAKE_COMMAND} -E copy    
${CMAKE_CURRENT_BINARY_DIR}/MSP_S_HOOK.dll 
${CMAKE_CURRENT_BINARY_DIR}/1/MSP_S_HOOK.dll)

set_target_properties(HOOK_SRC PROPERTIES LINK_FLAGS "/INCREMENTAL:NO" LINKER_LANGUAGE C)

What could I do to fix this ?

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
vainman
  • 377
  • 1
  • 5
  • 18
  • 1
    Have you checked that file `MSP_S_HOOK.dll` exists **exactly** in the build directory? As far as I remember, MSVC places output artifacts of `add_library` / `add_executable` into a **subdirectory** based on build configuration ("Debug", "Release" and so on). – Tsyvarev May 16 '19 at 13:40
  • Why do you want to copy the artifact. CMake has install and package support for those purposes. – John May 16 '19 at 14:15
  • @Tsyvarev It really exists. Variable ${CMAKE_CURRENT_BINARY_DIR} is the dir that named ".../vs-build/x86/debug/..."like this – vainman May 16 '19 at 16:49
  • @John How? I find no docs to make me figure that out. I am not native english, and I my region there are not that much C++ programmers, not even CMakeList, that's why I come SOF to find answer. – vainman May 16 '19 at 16:52
  • @vainman You could start with [cpack](https://cmake.org/cmake/help/v3.14/manual/cpack.1.html) and [install](https://cmake.org/cmake/help/v3.14/command/install.html) for starters. And no one is going to read your entire CMakeLists.txt file. Cut out all the irrelevant parts for the question. – John May 16 '19 at 17:09
  • Are you sure about content of `${CMAKE_CURRENT_BINARY_DIR}`? Have you obtained it via `message()` call? BTW, you may execute `cmake -E copy` with the same arguments from the command line, and check whether it works here. You may refer to the `.dll` created by `add_library()` via `$`. Also, instead of copying the created dll you may ask CMake to place it directly into specified directory by setting `CMAKE_RUNTIME_OUTPUT_DIRECTORY` variable, as described in that answer: https://stackoverflow.com/a/34445220/3440745. – Tsyvarev May 16 '19 at 20:30

1 Answers1

1

Have you tried to use ${PROJECT_BINARY_DIR} instead of the ${CMAKE_CURRENT_BINARY_DIR}? I believe the ${CMAKE_CURRENT_BINARY_DIR} is just taking the main binary dir of the CMake project you are working on. The code below could work for copying the dlls correctly.

add_custom_command(
       TARGET HOOK_SRC POST_BUILD 
       COMMAND ${CMAKE_COMMAND} -E copy_if_different    
       ${PROJECT_BINARY_DIR}/MSP_S_HOOK.dll 
       ${PROJECT_BINARY_DIR}/1/MSP_S_HOOK.dll
       $<TARGET_FILE_DIR:HOOK_SRC>)
thecatbehindthemask
  • 413
  • 1
  • 6
  • 15