cmake external projects command seems to ignore INSTALL_DIR
Asked Answered
B

1

12

First off, I'm relatively new to cmake. I'm trying to use cmake to build a project with a single external dependency. I specify the INSTALL_DIR for the external project to be CMAKE_INSTALL_PREFIX, so it installs to the same place as the parent project. But when I run make, it ignores it and tries to install to /usr/local/lib.

Here's my CMakeList.txt:

cmake_minimum_required( VERSION 2.8 )
include( ExternalProject )
project( capture )
add_library( capture SHARED capture.cc )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )

ExternalProject_Add( proj_exceptions 
    GIT_REPOSITORY /home/user/workspace/exceptions 
    INSTALL_DIR ${CMAKE_INSTALL_PREFIX} 
)

add_library( exceptions SHARED IMPORTED )
set_property( TARGET exceptions 
    PROPERTY IMPORTED_LOCATION ${CMAKE_INSTALL_PREFIX}/lib/libexceptions.so 
)
add_dependencies( exceptions proj_exceptions )
include_directories( ${CMAKE_INSTALL_PREFIX}/include )
target_link_libraries( capture exceptions )
install( TARGETS capture DESTINATION lib )
install( FILES capture.h DESTINATION include )

CMakeLists.txt for the external project looks like this:

cmake_minimum_required( VERSION 2.8 )
project( exceptions )
add_library( exceptions SHARED exceptions.cc )
install( TARGETS exceptions DESTINATION lib )
install( FILES exceptions.hh DESTINATION include )

It clones and builds the external project just fine, but it chokes on the install step:

Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/libexceptions.so
CMake Error at cmake_install.cmake:42 (file):
  file INSTALL cannot copy file
  "/home/user/workspace/capture/build/proj_exceptions-prefix/src/proj_exceptions-build/libexceptions.so"
  to "/usr/local/lib/libexceptions.so".
Makefile:66: recipe for target 'install' failed

As you can see, the install configuration is empty. Looking through the generated config for the external project, I found this in cmake_install.cmake:

if(NOT DEFINED CMAKE_INSTALL_PREFIX)
  set(CMAKE_INSTALL_PREFIX "/usr/local")
endif()

So, it seems that passing INSTALL_DIR to ExternalProject_Add doesn't set the install prefix. The install step succeeds, if I instead use:

ExternalProject_Add( proj_exceptions 
    GIT_REPOSITORY /home/djones/workspace/exceptions 
    CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" 
)     

So what's the purpose of INSTALL_DIR then?

Brocket answered 18/4, 2015 at 22:31 Comment(0)
C
6

You're right for the purpose of INSTALL_DIR, but you may have missed some steps.

According the cmake 2.8 doc about external project:

Install Step

The INSTALL_DIR is underneath the calling project’s binary directory. Use INSTALL_DIR to specify a different location. Note that in addition to setting INSTALL_DIR, you also have to pass -DCMAKE_INSTALL_PREFIX or --prefix to the CMake or configure command. It is not used automatically in the configure step since not all projects follow this convention.

# [INSTALL_DIR dir]

You can refer to the install directory in your configure command, for example:

CONFIGURE_COMMAND SOURCE_DIR/configure --prefix=INSTALL_DIR

 # [INSTALL_COMMAND cmd...]

CMake-based projects use ‘cmake--build’ to build the install target. Other projects use ‘make install’. Use INSTALL_COMMAND to customize the install step. Use INSTALL_COMMAND “” to omit the install step. The install command executes with the working directory set to .

So try to update your cmake command, or use the custom INSTALL_COMMAND feature.

Corot answered 9/9, 2015 at 7:14 Comment(2)
I"m using CMAKE_ARGS to set CMAKE_INSTALL_PREFIX for the the external project now, and don't need to use INSTALL_DIR. However, I'm marking this as the correct answer for pointing to the relevant documentation.Brocket
It might be because I'm using a newer CMake version (3.14-rc1), but it should be in pointy parentheses: --prefix=<INSTALL_DIR>From

© 2022 - 2024 — McMap. All rights reserved.