Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake install project doesn't copy my executable to the folder I specify

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).

like image 935
Simon Orsborn Avatar asked Aug 27 '14 06:08

Simon Orsborn


People also ask

How does CMake install work?

CMake provides the install command to specify how a project is to be installed. This command is invoked by a project in the CMakeLists file and tells CMake how to generate installation scripts. The scripts are executed at install time to perform the actual installation of files.

What does Add_subdirectory do in CMake?

Add a subdirectory to the build. Adds a subdirectory to the build. The source_dir specifies the directory in which the source CMakeLists.

Where is the executable after CMake?

Run cmake-gui.exe, which should be in your Start menu under Program Files, there may also be a shortcut on your desktop, or if you built from source, it will be in the build directory.

How do I specify the install directory in CMake?

The installation directory is usually left at its default, which is /usr/local . Installing software here ensures that it is automatically available to users. It is possible to specify a different installation directory by adding -DCMAKE_INSTALL_PREFIX=/path/to/install/dir to the CMake command line.


1 Answers

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
like image 123
Fraser Avatar answered Sep 28 '22 04:09

Fraser