CMake install project doesn't copy my executab

2019-04-07 12:45发布

问题:

I am just starting out with CMake. I've successfully set up the most minimal Hello, World! C++ application possible for Visual Studio 2012 on Windows 7, but I've got one last nagging thing that's not quite right and I can't figure out why :(

My folder structure is:

[cmakeTest]
- [build]
- [source]
  - [helloWorld]
    - main.cpp
    - CMakeLists.txt
  - CMakeLists.txt

My main.cpp file is just:

#include <iostream>

int main()
{
    std::cout << "Hello World!";
}

source/CMakeLists.txt is:

cmake_minimum_required (VERSION 3.0.1)

# Specifies project name for Visual Studio solution.
# Visual Studio projects will be made for each CMake target specified

project(cmakeTesting)

# Set the install directory
set(CMAKE_INSTALL_PREFIX ${cmakeTesting_BINARY_DIR}/bin)

# Generate organiser projects
# Creates "CMakePredefinedTargets" folder with INSTALL and ZERO_CHECK

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

# Queue up CMakeLists from subdirectories

add_subdirectory(helloWorld)

source/helloWorld/CMakeLists.txt is:

# Set Properties->General->Configuration Type to Application (.exe)
# Creates helloWorld.exe with the listed sources (main.cxx)
# Adds sources to the Solution Explorer

add_executable (helloWorld main.cpp)

# Creates a folder called "executables" and adds target
# project (helloWorld.vcproj) under it

set_property(TARGET helloWorld PROPERTY FOLDER "executables")

# Adds logic to INSTALL.vcproj to copy helloWorld.exe to dest dir

install (TARGETS helloWorld RUNTIME DESTINATION ${PROJECT_BINARY_BIN}/bin)

What does work:

  • It creates the Visual Studio solution/project stuff in the build directory

  • The project builds and runs in debug and release mode

  • It creates EXE files in /build/helloWorld/Debug/ and /build/helloWorld/Release (which work)

What doesn't work:

  • Visual Studio says it has copied the EXE file to /bin/helloWorld.exe, but it hasn't >:-(

.

1>------ Build started: Project: ZERO_CHECK, Configuration: Release Win32 ------

2>------ Build started: Project: ALL_BUILD, Configuration: Release Win32 ------

2> Build all projects

3>------ Build started: Project: INSTALL, Configuration: Release Win32 ------

3> -- Install configuration: "Release"

3> -- Up-to-date: /bin/helloWorld.exe

========== Build: 3 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========

.

I know it seems fussy, but I'm trying to make sure I understand everything that's going on before steamrolling into more complex stuff (P.S. I'm using the CMake client, not the command line).

回答1:

This probably just boils down to being a typo. In the last line of source/helloWorld/CMakeLists.txt I guess you meant PROJECT_BINARY_DIR rather than PROJECT_BINARY_BIN?

What's happening here is that ${PROJECT_BINARY_BIN}/bin resolves to /bin (dereferencing an undefined string in CMake unfortunately doesn't generate a warning) and /bin is an absolute path. If your project is in the C: drive, I expect you'll find that C:\bin\helloWorld.exe actually does exist: Visual Studio hasn't been lying to you :-)

Just as an aside, it's usual to specify relative paths in the install command to allow the user to select the install root. Likewise, it's not really user-friendly to hard code the CMAKE_INSTALL_PREFIX (at least without a warning).

In this case, I'd change the install command to:

install (TARGETS helloWorld RUNTIME DESTINATION bin)

and remove set(CMAKE_INSTALL_PREFIX ...) from source/CMakeLists.txt.

Say your project's root is C:\myProject, then from a Visual Studio command prompt, you can do:

cd C:\myProject\build
cmake -DCMAKE_INSTALL_PREFIX="C:\myProject\build" ..\source
cmake --build . --config Release --target INSTALL
bin\helloWorld.exe