9

so im trying to setup a project, on windows, with cmake

this is what my project structure looks like:

  • GameEngine
    • .git
    • build
    • include
    • source
    • testing
    • CMakeLists.txt

the idea is that the "source" directory contain all the .cpp files for the GameEngine library, the "include" directory contain all the header files and the "testing" directory is for testing the library. So it should depend on the GameEngine.dll and GameEngine.lib (on windows).

my top level CMakesLists.txt contain:

    cmake_minimum_required(VERSION 2.7)
    PROJECT( GameEngine )

    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include )

    ADD_SUBDIRECTORY( source )
    add_subdirectory( testing )


the CMakeLists.txt in the "source" directory contain:

    project(GameEngineLib)

    file(GLOB src "*.cpp" "../include/*.h")

    add_library(${PROJECT_NAME} SHARED ${src})


and the CMakeLists.txt in the "testing" directory contain:

    project(Testing)

    file(GLOB src "*.h" "*.cpp")

    ADD_EXECUTABLE( ${PROJECT_NAME} ${src})
    target_link_libraries(${PROJECT_NAME} GameEngineLib)


This all works fine on linux.
when i build it, i get two folders (+ some others), "testing" and "source" and a Makefile that outputs an executable and a .so file.
and the executable already know where to find the .so file, so i can just run without any errors.


The problem comes when i build on windows with visual studio.
Everything works except that the Testing executable, that i get after building the "ALL_BUILD" project, gives me an error saying that it can't find GameEngineLib.dll.


I tried searching around on google on how to fix the problem, but most of the solutions i found just said that you had to manually change your settings in visual studio, to look for the dll, where its located.


but if i was working in a team with multiple developers, i wouldn't really want to have every developer that uses visual studio to have to go in and change settings in the project themselves.


isn't there a way to tell cmake to automatically copy the GameEngineLib.dll to the Tester.exe's folder?

  • One option that I use is to get rid of the project() from all but the top level and set the output folder in the root CMakeLists.txt before the add_subdirectory()s – drescherjm Jul 04 '17 at 16:02
  • `isn't there a way to tell cmake to automatically copy the GameEngineLib.dll to the Tester.exe's folder?` - There are [many questions](https://stackoverflow.com/search?q=%5Bcmake%5Dcopy+dll) on Stack Overflow about copiing `.dll` with CMake. Choose one of them and proceed. – Tsyvarev Jul 05 '17 at 07:39

2 Answers2

7

I'm trying to equip OpenCV 1.0.0 with CMake support and meet the very similar situation, i.e. in my own solution, there is a shared library(.dll) and a executable(.exe) built from my source and header files, and when executing that .exe file, how could we ensure .exe can find .dll?

As @drescherjm commented, the solution is: in root CMakeLists.txt, before add_subdirectory(), add these two lines:

set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
ChrisZZ
  • 1,521
  • 2
  • 17
  • 24
3

I had a similar problem whem trying to use cmocka lib to create tests.

Even thought CMake found your library with a find_library command like

find_library(<SOME_VAR> NAMES lib_name PATHS "where/to/search")

you'll still run into this problem.

Windows execution will not be able to find the .dll. You can solve this problem by adding this library stored in right next to your executable.

So if you have something like

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

in your CMakeLists.txt file, you'd only have to add

file(COPY ${SOME_VAR}
    DESTINATION ${EXECUTABLE_OUTPUT_PATH})

That's it.

Felipe Thorn
  • 114
  • 1
  • 4
  • `EXECUTABLE_OUTPUT_PATH` is deprecated; per CMake 3.18 they recommend `RUNTIME_OUTPUT_DIRECTORY`. – Joachim W Jun 29 '20 at 18:33
  • 1
    this is fine if you have multiple cmake projects in your solution, but can you automatically copy the files from external libraries? – FalcoGer Jul 08 '20 at 02:09