Introduce CMAKE_STAGING_PREFIX variable.
This variable can be useful in cross-compiling contexts where the sysroot is read-only or where the sysroot should otherwise remain pristine. If the new CMAKE_STAGING_PREFIX variable is set, it is used instead of CMAKE_INSTALL_PREFIX when generating the installation rules in cmake_install.cmake. This way, the CMAKE_INSTALL_PREFIX variable always refers to the installation prefix on the target device, regardless of whether host==target. If any -rpath paths passed to the linker contain the CMAKE_STAGING_PREFIX, the matching path fragments are replaced with the CMAKE_INSTALL_PREFIX. Matching paths in the -rpath-link are not transformed. The cross-prefix usr-move workaround is assumed not to require extension regarding CMAKE_STAGING_PREFIX. The staging area is a single prefix, so there is no scope for cross-prefix symlinks. The CMAKE_INSTALL_PREFIX is still used to determine the workaround path, and that variable remains the relevant one even if CMAKE_STAGING_PREFIX is used. If the generated export files are deployed to the target, the workaround will still be in place, and still be employed if required.
This commit is contained in:
parent
e776a2dae4
commit
7521da2852
|
@ -1,7 +1,9 @@
|
|||
The CMake variable CMAKE_FIND_ROOT_PATH specifies one or more
|
||||
directories to be prepended to all other search directories. This
|
||||
effectively "re-roots" the entire search under given locations. By
|
||||
default it is empty.
|
||||
effectively "re-roots" the entire search under given locations.
|
||||
Paths which are descendants of the :variable:`CMAKE_STAGING_PREFIX` are excluded
|
||||
from this re-rooting, because that variable is always a path on the host system.
|
||||
By default the CMAKE_FIND_ROOT_PATH is empty.
|
||||
|
||||
The :variable:`CMAKE_SYSROOT` variable can also be used to specify exactly one
|
||||
directory to use as a prefix. Setting :variable:`CMAKE_SYSROOT` also has other
|
||||
|
@ -18,4 +20,4 @@ overridden on a per-call basis. By using CMAKE_FIND_ROOT_PATH_BOTH
|
|||
the search order will be as described above. If
|
||||
NO_CMAKE_FIND_ROOT_PATH is used then CMAKE_FIND_ROOT_PATH will not be
|
||||
used. If ONLY_CMAKE_FIND_ROOT_PATH is used then only the re-rooted
|
||||
directories will be searched.
|
||||
directories and directories below :variable:`CMAKE_STAGING_PREFIX` will be searched.
|
||||
|
|
|
@ -110,6 +110,7 @@ Variables that Change Behavior
|
|||
/variable/CMAKE_PREFIX_PATH
|
||||
/variable/CMAKE_PROGRAM_PATH
|
||||
/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
|
||||
/variable/CMAKE_STAGING_PREFIX
|
||||
/variable/CMAKE_SYSTEM_IGNORE_PATH
|
||||
/variable/CMAKE_SYSTEM_INCLUDE_PATH
|
||||
/variable/CMAKE_SYSTEM_LIBRARY_PATH
|
||||
|
|
|
@ -3,11 +3,13 @@ CMAKE_FIND_NO_INSTALL_PREFIX
|
|||
|
||||
Ignore the :variable:`CMAKE_INSTALL_PREFIX` when searching for assets.
|
||||
|
||||
CMake adds the :variable:`CMAKE_INSTALL_PREFIX` to the
|
||||
CMake adds the :variable:`CMAKE_INSTALL_PREFIX` and the
|
||||
:variable:`CMAKE_STAGING_PREFIX` variable to the
|
||||
:variable:`CMAKE_SYSTEM_PREFIX_PATH` by default. This variable may be set
|
||||
on the command line to control that behavior.
|
||||
|
||||
Set :variable:`CMAKE_FIND_NO_INSTALL_PREFIX` to TRUE to tell find_package not
|
||||
to search in the :variable:`CMAKE_INSTALL_PREFIX` by default. Note that the
|
||||
to search in the :variable:`CMAKE_INSTALL_PREFIX` or
|
||||
:variable:`CMAKE_STAGING_PREFIX` by default. Note that the
|
||||
prefix may still be searched for other reasons, such as being the same prefix
|
||||
as the CMake installation, or for being a built-in system prefix.
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
CMAKE_STAGING_PREFIX
|
||||
--------------------
|
||||
|
||||
This variable may be set to a path to install to when cross-compiling. This can
|
||||
be useful if the path in :variable:`CMAKE_SYSROOT` is read-only, or otherwise
|
||||
should remain pristine.
|
||||
|
||||
The CMAKE_STAGING_PREFIX location is also used as a search prefix by the ``find_*``
|
||||
commands. This can be controlled by setting the :variable:`CMAKE_FIND_NO_INSTALL_PREFIX`
|
||||
variable.
|
||||
|
||||
If any RPATH/RUNPATH entries passed to the linker contain the CMAKE_STAGING_PREFIX,
|
||||
the matching path fragments are replaced with the :variable:`CMAKE_INSTALL_PREFIX`.
|
|
@ -9,8 +9,8 @@ appropriate subdirectories to the base directories. So FIND_PROGRAM()
|
|||
adds /bin to each of the directories in the path, FIND_LIBRARY()
|
||||
appends /lib to each of the directories, and FIND_PATH() and
|
||||
FIND_FILE() append /include . By default this contains the standard
|
||||
directories for the current system and the CMAKE_INSTALL_PREFIX. It
|
||||
is NOT intended to be modified by the project, use CMAKE_PREFIX_PATH
|
||||
for this. See also CMAKE_SYSTEM_INCLUDE_PATH,
|
||||
directories for the current system, the CMAKE_INSTALL_PREFIX and
|
||||
the :variable:`CMAKE_STAGING_PREFIX`. It is NOT intended to be modified by
|
||||
the project, use CMAKE_PREFIX_PATH for this. See also CMAKE_SYSTEM_INCLUDE_PATH,
|
||||
CMAKE_SYSTEM_LIBRARY_PATH, CMAKE_SYSTEM_PROGRAM_PATH, and
|
||||
CMAKE_SYSTEM_IGNORE_PATH.
|
||||
|
|
|
@ -43,6 +43,12 @@ if (NOT CMAKE_FIND_NO_INSTALL_PREFIX)
|
|||
# Project install destination.
|
||||
"${CMAKE_INSTALL_PREFIX}"
|
||||
)
|
||||
if(CMAKE_STAGING_PREFIX)
|
||||
list(APPEND CMAKE_SYSTEM_PREFIX_PATH
|
||||
# User-supplied staging prefix.
|
||||
"${CMAKE_STAGING_PREFIX}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# List common include file locations not under the common prefixes.
|
||||
|
|
|
@ -79,6 +79,12 @@ if (NOT CMAKE_FIND_NO_INSTALL_PREFIX)
|
|||
# Project install destination.
|
||||
"${CMAKE_INSTALL_PREFIX}"
|
||||
)
|
||||
if (CMAKE_STAGING_PREFIX)
|
||||
list(APPEND CMAKE_SYSTEM_PREFIX_PATH
|
||||
# User-supplied staging prefix.
|
||||
"${CMAKE_STAGING_PREFIX}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_CROSSCOMPILING AND NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
|
||||
|
@ -94,6 +100,11 @@ if (NOT CMAKE_FIND_NO_INSTALL_PREFIX)
|
|||
list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
|
||||
"${CMAKE_INSTALL_PREFIX}/bin"
|
||||
)
|
||||
if (CMAKE_STAGING_PREFIX)
|
||||
list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
|
||||
"${CMAKE_STAGING_PREFIX}/bin"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
|
||||
"${_CMAKE_INSTALL_DIR}/bin"
|
||||
|
|
|
@ -1902,6 +1902,10 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
|
|||
if(use_build_rpath || use_link_rpath)
|
||||
{
|
||||
std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
|
||||
const char *stagePath
|
||||
= this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX");
|
||||
const char *installPrefix
|
||||
= this->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
|
||||
cmSystemTools::ConvertToUnixSlashes(rootPath);
|
||||
std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
|
||||
for(std::vector<std::string>::const_iterator ri = rdirs.begin();
|
||||
|
@ -1916,6 +1920,14 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
|
|||
{
|
||||
d = d.substr(rootPath.size());
|
||||
}
|
||||
else if (stagePath && *stagePath && d.find(stagePath) == 0)
|
||||
{
|
||||
std::string suffix = d.substr(strlen(stagePath));
|
||||
d = installPrefix;
|
||||
d += "/";
|
||||
d += suffix;
|
||||
cmSystemTools::ConvertToUnixSlashes(d);
|
||||
}
|
||||
if(emitted.insert(d).second)
|
||||
{
|
||||
runtimeDirs.push_back(d);
|
||||
|
@ -1936,6 +1948,14 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
|
|||
{
|
||||
d = d.substr(rootPath.size());
|
||||
}
|
||||
else if (stagePath && *stagePath && d.find(stagePath) == 0)
|
||||
{
|
||||
std::string suffix = d.substr(strlen(stagePath));
|
||||
d = installPrefix;
|
||||
d += "/";
|
||||
d += suffix;
|
||||
cmSystemTools::ConvertToUnixSlashes(d);
|
||||
}
|
||||
if(emitted.insert(d).second)
|
||||
{
|
||||
runtimeDirs.push_back(d);
|
||||
|
|
|
@ -165,6 +165,9 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
|
|||
cmSystemTools::ConvertToUnixSlashes(*ri);
|
||||
}
|
||||
|
||||
const char* stagePrefix =
|
||||
this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX");
|
||||
|
||||
// Copy the original set of unrooted paths.
|
||||
std::vector<std::string> unrootedPaths = paths;
|
||||
paths.clear();
|
||||
|
@ -179,7 +182,9 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
|
|||
// already inside. Skip the unrooted path if it is relative to
|
||||
// a user home directory or is empty.
|
||||
std::string rootedDir;
|
||||
if(cmSystemTools::IsSubDirectory(ui->c_str(), ri->c_str()))
|
||||
if(cmSystemTools::IsSubDirectory(ui->c_str(), ri->c_str())
|
||||
|| (stagePrefix
|
||||
&& cmSystemTools::IsSubDirectory(ui->c_str(), stagePrefix)))
|
||||
{
|
||||
rootedDir = *ui;
|
||||
}
|
||||
|
|
|
@ -370,6 +370,11 @@ void cmLocalGenerator::GenerateInstallRules()
|
|||
prefix = "/usr/local";
|
||||
}
|
||||
#endif
|
||||
if (const char *stagingPrefix
|
||||
= this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX"))
|
||||
{
|
||||
prefix = stagingPrefix;
|
||||
}
|
||||
|
||||
// Compute the set of configurations.
|
||||
std::vector<std::string> configurationTypes;
|
||||
|
|
|
@ -269,6 +269,7 @@ if(BUILD_TESTING)
|
|||
ADD_TEST_MACRO(CompileOptions CompileOptions)
|
||||
ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
|
||||
ADD_TEST_MACRO(AliasTarget AliasTarget)
|
||||
ADD_TEST_MACRO(StagingPrefix StagingPrefix)
|
||||
ADD_TEST_MACRO(InterfaceLibrary InterfaceLibrary)
|
||||
set_tests_properties(EmptyLibrary PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
project(StagingPrefix)
|
||||
|
||||
# Wipe out the install tree
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/CleanupProject
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/ConsumerBuild
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/ProducerBuild
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/stage
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/prefix
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/ignored
|
||||
)
|
||||
add_custom_target(CleanupTarget ALL DEPENDS ${CMAKE_BINARY_DIR}/CleanupProject)
|
||||
set_property(
|
||||
SOURCE ${CMAKE_BINARY_DIR}/CleanupProject
|
||||
PROPERTY SYMBOLIC 1
|
||||
)
|
||||
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
set(NESTED_CONFIG_TYPE -C "${CMAKE_CFG_INTDIR}")
|
||||
else()
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
set(NESTED_CONFIG_TYPE -C "${CMAKE_BUILD_TYPE}")
|
||||
else()
|
||||
set(NESTED_CONFIG_TYPE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Build and install the producer.
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/ProducerProject
|
||||
COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
|
||||
--build-and-test
|
||||
${CMAKE_SOURCE_DIR}/Producer
|
||||
${CMAKE_BINARY_DIR}/ProducerBuild
|
||||
--build-noclean
|
||||
--build-project Producer
|
||||
--build-target install
|
||||
--build-generator ${CMAKE_GENERATOR}
|
||||
--build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
|
||||
--build-options
|
||||
-DCMAKE_VERBOSE_MAKEFILE=1
|
||||
"-DCMAKE_STAGING_PREFIX=${CMAKE_BINARY_DIR}/stage"
|
||||
"-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/prefix"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(ProducerTarget ALL DEPENDS ${CMAKE_BINARY_DIR}/ProducerProject)
|
||||
add_dependencies(ProducerTarget CleanupTarget)
|
||||
set_property(
|
||||
SOURCE ${CMAKE_BINARY_DIR}/ProducerProject
|
||||
PROPERTY SYMBOLIC 1
|
||||
)
|
||||
|
||||
if(NOT WIN32)
|
||||
file(WRITE
|
||||
"${CMAKE_BINARY_DIR}/ignored/${CMAKE_BINARY_DIR}/stage/include/ignored.h"
|
||||
"#define IGNORED\n"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Build and install the consumer.
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/ConsumerProject
|
||||
COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
|
||||
--build-and-test
|
||||
${CMAKE_SOURCE_DIR}/Consumer
|
||||
${CMAKE_BINARY_DIR}/ConsumerBuild
|
||||
--build-noclean
|
||||
--build-project Consumer
|
||||
--build-target install
|
||||
--build-generator ${CMAKE_GENERATOR}
|
||||
--build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
|
||||
--build-options
|
||||
"-DCMAKE_FIND_ROOT_PATH=${CMAKE_BINARY_DIR}/ignored"
|
||||
"-DCMAKE_STAGING_PREFIX=${CMAKE_BINARY_DIR}/stage"
|
||||
-DCMAKE_VERBOSE_MAKEFILE=1
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(ConsumerTarget ALL DEPENDS ${CMAKE_BINARY_DIR}/ConsumerProject)
|
||||
add_dependencies(ConsumerTarget ProducerTarget)
|
||||
set_property(
|
||||
SOURCE ${CMAKE_BINARY_DIR}/ConsumerProject
|
||||
PROPERTY SYMBOLIC 1
|
||||
)
|
||||
|
||||
add_executable(StagingPrefix main.cpp)
|
||||
add_dependencies(StagingPrefix ConsumerTarget)
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
cmake_minimum_required (VERSION 2.8.12)
|
||||
project(Consumer)
|
||||
|
||||
|
||||
add_executable(executable main.cpp)
|
||||
find_package(Foo CONFIG REQUIRED)
|
||||
target_link_libraries(executable Foo::foo)
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
find_package(Bar MODULE REQUIRED)
|
||||
include_directories(${Bar_INCLUDE_DIRS})
|
||||
target_link_libraries(executable ${Bar_LIBRARIES})
|
||||
|
||||
install(TARGETS executable DESTINATION bin)
|
||||
|
||||
if(NOT WIN32)
|
||||
find_path(IGNORED_INCLUDE_DIR ignored.h)
|
||||
if (IGNORED_INCLUDE_DIR)
|
||||
message(SEND_ERROR "Should not find this file. The search path should be excluded.")
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
find_path(_inc_prefix bar.h PATH_SUFFIXES bar)
|
||||
set(Bar_INCLUDE_DIRS ${_inc_prefix})
|
||||
|
||||
find_library(Bar_LIBRARY bar)
|
||||
set(Bar_LIBRARIES ${Bar_LIBRARY})
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
#include "foo.h"
|
||||
#include "bar.h"
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
Foo f;
|
||||
Bar b;
|
||||
return f.foo() + b.bar();
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
cmake_minimum_required (VERSION 2.8.12)
|
||||
project(Producer)
|
||||
|
||||
add_library(foo SHARED foo.cpp)
|
||||
|
||||
install(TARGETS foo EXPORT fooTargets
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
INCLUDES DESTINATION include/foo
|
||||
)
|
||||
install(FILES foo.h DESTINATION include/foo)
|
||||
install(EXPORT fooTargets
|
||||
FILE FooConfig.cmake
|
||||
NAMESPACE Foo::
|
||||
DESTINATION lib/cmake/Foo
|
||||
)
|
||||
|
||||
add_library(bar SHARED bar.cpp)
|
||||
install(TARGETS bar
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
install(FILES bar.h DESTINATION include/bar)
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "bar.h"
|
||||
|
||||
int Bar::bar()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
class
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
Bar
|
||||
{
|
||||
public:
|
||||
int bar();
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "foo.h"
|
||||
|
||||
int Foo::foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
class
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
Foo
|
||||
{
|
||||
public:
|
||||
int foo();
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
int main(int, char **)
|
||||
{
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue