Discussion:
[CMake] DESTDIR behaviour with different variable name
Tomasz Grobelny
2011-04-11 13:16:59 UTC
Permalink
I need behaviour that is available with DESTDIR (that is changing location
of installation root after configuration and build is done) but with
different name of environment variable (eg. MYDESTDIR). Is it possible with
cmake?
--
Regards,
Tomasz Grobelny
Michael Wild
2011-04-11 14:07:36 UTC
Permalink
Post by Tomasz Grobelny
I need behaviour that is available with DESTDIR (that is changing location
of installation root after configuration and build is done) but with
different name of environment variable (eg. MYDESTDIR). Is it possible with
cmake?
export MYDESTDIR=$PWD/mydestdir
make install DESTDIR=$MYDESTDIR

HTH

Michael
Tomasz Grobelny
2011-04-11 15:54:04 UTC
Permalink
Post by Michael Wild
Post by Tomasz Grobelny
I need behaviour that is available with DESTDIR (that is changing location
of installation root after configuration and build is done) but with
different name of environment variable (eg. MYDESTDIR). Is it possible with
cmake?
export MYDESTDIR=$PWD/mydestdir
make install DESTDIR=$MYDESTDIR
Ok, but is there a way to achieve the same effect so that the user can
type just "make install" and not know anything about DESTDIR environment
variable (provided he knows about MYDESTDIR)? Maybe it is possible to put
this "DESTDIR=$MYDESTDIR" in the generated Makefiles somehow...
--
Regards,
Tomasz Grobelny
Tyler
2011-04-11 16:01:09 UTC
Permalink
On Mon, Apr 11, 2011 at 8:54 AM, Tomasz Grobelny
Post by Tomasz Grobelny
Ok, but is there a way to achieve the same effect so that the user can
type just "make install" and not know anything about DESTDIR environment
variable (provided he knows about MYDESTDIR)? Maybe it is possible to put
this "DESTDIR=$MYDESTDIR" in the generated Makefiles somehow...
If I understand your use case right (which I might not as you haven't
described what you're trying to do, just how you're trying to do it),
maybe you can just override CMAKE_INSTALL_PREFIX.

If you go this route, check the archives because of the whole
_INITIALIZED_TO_DEFAULT aspect of that particular cache variable.

tyler
Tomasz Grobelny
2011-04-11 16:22:02 UTC
Permalink
Post by Tyler
On Mon, Apr 11, 2011 at 8:54 AM, Tomasz Grobelny
Post by Tomasz Grobelny
Ok, but is there a way to achieve the same effect so that the user can
type just "make install" and not know anything about DESTDIR
environment
Post by Tyler
Post by Tomasz Grobelny
variable (provided he knows about MYDESTDIR)? Maybe it is possible to put
this "DESTDIR=$MYDESTDIR" in the generated Makefiles somehow...
If I understand your use case right (which I might not as you haven't
described what you're trying to do, just how you're trying to do it),
maybe you can just override CMAKE_INSTALL_PREFIX.
If you go this route, check the archives because of the whole
_INITIALIZED_TO_DEFAULT aspect of that particular cache variable.
I already tried playing with CMAKE_INSTALL_PREFIX but the problem was that
value of MYDESTDIR was read (and saved to CMAKE_INSTALL_PREFIX) only when
configuring first time. That's why DESTDIR mechanism comes closer to what
I'm trying to achieve. My use case is something like that:
1. User has some default MYDESTDIR to non writable location.
2. User executes "cmake . && make install".
3. The installation fails because user has no rights to $MYDESTDIR.
4. User changes MYDESTDIR to another location (writable this time).
5. User executes "make install" once again and it should succeed.

Of course the user could set MYDESTDIR to correct location before building
but people often forget that. Now the tricky part is that users are already
used to this mechanism (for particular variable name, called MYDESTDIR
here). So taking different environment variable instead of DESTDIR would
allow me to minimize confusion among users. Otherwise I'll just tell them
to set yet another variable (DESTDIR). But I would like to avoid that if at
all possible.
--
Regards,
Tomasz Grobelny
Alexander Neundorf
2011-04-11 19:55:48 UTC
Permalink
Post by Tomasz Grobelny
Post by Tyler
On Mon, Apr 11, 2011 at 8:54 AM, Tomasz Grobelny
Post by Tomasz Grobelny
Ok, but is there a way to achieve the same effect so that the user can
type just "make install" and not know anything about DESTDIR
environment
Post by Tyler
Post by Tomasz Grobelny
variable (provided he knows about MYDESTDIR)? Maybe it is possible to
put
Post by Tyler
Post by Tomasz Grobelny
this "DESTDIR=$MYDESTDIR" in the generated Makefiles somehow...
If I understand your use case right (which I might not as you haven't
described what you're trying to do, just how you're trying to do it),
maybe you can just override CMAKE_INSTALL_PREFIX.
If you go this route, check the archives because of the whole
_INITIALIZED_TO_DEFAULT aspect of that particular cache variable.
I already tried playing with CMAKE_INSTALL_PREFIX but the problem was that
value of MYDESTDIR was read (and saved to CMAKE_INSTALL_PREFIX) only when
configuring first time. That's why DESTDIR mechanism comes closer to what
1. User has some default MYDESTDIR to non writable location.
2. User executes "cmake . && make install".
3. The installation fails because user has no rights to $MYDESTDIR.
4. User changes MYDESTDIR to another location (writable this time).
5. User executes "make install" once again and it should succeed.
Of course the user could set MYDESTDIR to correct location before building
but people often forget that. Now the tricky part is that users are already
used to this mechanism (for particular variable name, called MYDESTDIR
here). So taking different environment variable instead of DESTDIR would
allow me to minimize confusion among users. Otherwise I'll just tell them
to set yet another variable (DESTDIR). But I would like to avoid that if at
all possible.
DESTDIR has a different purpose.
Installing to DESTDIR does not necessarily lead to a working and correct
installation, mainly when paths are involved, like e.g. RPATH settings.
Assuming that CMAKE_INSTALL_PREFIX would be /opt/foo, your executable might
get /opt/foo/lib as RPATH, also when installed to $DESTDIR/opt/foo.
So they will not have a correct RPATH.
You really should set CMAKE_INSTALL_PREFIX.

Alex
Tomasz Grobelny
2011-04-11 20:42:11 UTC
Permalink
Post by Alexander Neundorf
Post by Tomasz Grobelny
Post by Tyler
On Mon, Apr 11, 2011 at 8:54 AM, Tomasz Grobelny
Post by Tomasz Grobelny
Ok, but is there a way to achieve the same effect so that the user can
type just "make install" and not know anything about DESTDIR
environment
Post by Tyler
Post by Tomasz Grobelny
variable (provided he knows about MYDESTDIR)? Maybe it is possible to
put this "DESTDIR=$MYDESTDIR" in the generated Makefiles somehow...
If I understand your use case right (which I might not as you haven't
described what you're trying to do, just how you're trying to do it),
maybe you can just override CMAKE_INSTALL_PREFIX.
If you go this route, check the archives because of the whole
_INITIALIZED_TO_DEFAULT aspect of that particular cache variable.
I already tried playing with CMAKE_INSTALL_PREFIX but the problem was
that value of MYDESTDIR was read (and saved to CMAKE_INSTALL_PREFIX)
only when configuring first time. That's why DESTDIR mechanism comes
closer to what I'm trying to achieve. My use case is something like
1. User has some default MYDESTDIR to non writable location.
2. User executes "cmake . && make install".
3. The installation fails because user has no rights to $MYDESTDIR.
4. User changes MYDESTDIR to another location (writable this time).
5. User executes "make install" once again and it should succeed.
Of course the user could set MYDESTDIR to correct location before
building but people often forget that. Now the tricky part is that users
are already used to this mechanism (for particular variable name, called
MYDESTDIR here). So taking different environment variable instead of
DESTDIR would allow me to minimize confusion among users. Otherwise I'll
just tell them to set yet another variable (DESTDIR). But I would like
to avoid that if at all possible.
DESTDIR has a different purpose.
Installing to DESTDIR does not necessarily lead to a working and correct
installation, mainly when paths are involved, like e.g. RPATH settings.
Assuming that CMAKE_INSTALL_PREFIX would be /opt/foo, your executable might
get /opt/foo/lib as RPATH, also when installed to $DESTDIR/opt/foo.
So they will not have a correct RPATH.
You really should set CMAKE_INSTALL_PREFIX.
I'd like to. But CMAKE_INSTALL_PREFIX does not get recomputed when I change
MYDESTDIR and try to do "make install" again. Or at least I don't know how to
make it behave this way.
Besides, I don't use RPATH (at least not explicitely, hopefully cmake is not
doing anything nasty behind the scenes).
--
Regards,
Tomasz Grobelny
Michael Hertling
2011-04-12 01:44:04 UTC
Permalink
Post by Tomasz Grobelny
Post by Alexander Neundorf
Post by Tomasz Grobelny
Post by Tyler
On Mon, Apr 11, 2011 at 8:54 AM, Tomasz Grobelny
Post by Tomasz Grobelny
Ok, but is there a way to achieve the same effect so that the user can
type just "make install" and not know anything about DESTDIR
environment
Post by Tyler
Post by Tomasz Grobelny
variable (provided he knows about MYDESTDIR)? Maybe it is possible to
put this "DESTDIR=$MYDESTDIR" in the generated Makefiles somehow...
If I understand your use case right (which I might not as you haven't
described what you're trying to do, just how you're trying to do it),
maybe you can just override CMAKE_INSTALL_PREFIX.
If you go this route, check the archives because of the whole
_INITIALIZED_TO_DEFAULT aspect of that particular cache variable.
I already tried playing with CMAKE_INSTALL_PREFIX but the problem was
that value of MYDESTDIR was read (and saved to CMAKE_INSTALL_PREFIX)
only when configuring first time. That's why DESTDIR mechanism comes
closer to what I'm trying to achieve. My use case is something like
1. User has some default MYDESTDIR to non writable location.
2. User executes "cmake . && make install".
3. The installation fails because user has no rights to $MYDESTDIR.
4. User changes MYDESTDIR to another location (writable this time).
5. User executes "make install" once again and it should succeed.
Of course the user could set MYDESTDIR to correct location before
building but people often forget that. Now the tricky part is that users
are already used to this mechanism (for particular variable name, called
MYDESTDIR here). So taking different environment variable instead of
DESTDIR would allow me to minimize confusion among users. Otherwise I'll
just tell them to set yet another variable (DESTDIR). But I would like
to avoid that if at all possible.
DESTDIR has a different purpose.
Installing to DESTDIR does not necessarily lead to a working and correct
installation, mainly when paths are involved, like e.g. RPATH settings.
Assuming that CMAKE_INSTALL_PREFIX would be /opt/foo, your executable might
get /opt/foo/lib as RPATH, also when installed to $DESTDIR/opt/foo.
So they will not have a correct RPATH.
You really should set CMAKE_INSTALL_PREFIX.
I'd like to. But CMAKE_INSTALL_PREFIX does not get recomputed when I change
MYDESTDIR and try to do "make install" again. Or at least I don't know how to
make it behave this way.
Besides, I don't use RPATH (at least not explicitely, hopefully cmake is not
doing anything nasty behind the scenes).
But some day, you might want to use RPATH features as they are very
convenient in certain situations, or you might want to incorporate
the installation prefix or derivatives like CMAKE_INSTALL_PREFIX/lib
/${PROJECT_NAME} in your binaries which can be quite convenient, too.
Moreover, you can hardly prevent your project's users to use RPATH on
their own, see the CMAKE_INSTALL_RPATH/CMAKE_BUILD_WITH_INSTALL_RPATH
variables, e.g. In this regard, using the DESTDIR Makefile/environment
variable bears the risk of subtle failures and isn't worth the effort,
IMO. Thus, you should take Alex's warning absolutely seriously, or in
other words: Changing the installation prefix does invalidate your
already built targets, so you do need to reconfigure and rebuild.

Anyway, see [1] for a chance to add "DESTDIR=$MYDESTDIR" to the
generated Makefiles, provided that you are using GNU Make, but
even this won't work as expected since DESTDIR is hard-coded
in CMake, AFAIK, and due to other reasons.

Regards,

Michael

[1] http://www.mail-archive.com/***@cmake.org/msg34344.html
Tomasz Grobelny
2011-04-12 14:36:28 UTC
Permalink
Post by Michael Hertling
Post by Tomasz Grobelny
Post by Alexander Neundorf
Post by Tomasz Grobelny
Post by Tyler
On Mon, Apr 11, 2011 at 8:54 AM, Tomasz Grobelny
Post by Tomasz Grobelny
Ok, but is there a way to achieve the same effect so that the user can
type just "make install" and not know anything about DESTDIR
environment
Post by Tyler
Post by Tomasz Grobelny
variable (provided he knows about MYDESTDIR)? Maybe it is possible to
put this "DESTDIR=$MYDESTDIR" in the generated Makefiles somehow...
If I understand your use case right (which I might not as you haven't
described what you're trying to do, just how you're trying to do it),
maybe you can just override CMAKE_INSTALL_PREFIX.
If you go this route, check the archives because of the whole
_INITIALIZED_TO_DEFAULT aspect of that particular cache variable.
I already tried playing with CMAKE_INSTALL_PREFIX but the problem was
that value of MYDESTDIR was read (and saved to CMAKE_INSTALL_PREFIX)
only when configuring first time. That's why DESTDIR mechanism comes
closer to what I'm trying to achieve. My use case is something like
1. User has some default MYDESTDIR to non writable location.
2. User executes "cmake . && make install".
3. The installation fails because user has no rights to $MYDESTDIR.
4. User changes MYDESTDIR to another location (writable this time).
5. User executes "make install" once again and it should succeed.
Of course the user could set MYDESTDIR to correct location before
building but people often forget that. Now the tricky part is that users
are already used to this mechanism (for particular variable name, called
MYDESTDIR here). So taking different environment variable instead of
DESTDIR would allow me to minimize confusion among users. Otherwise I'll
just tell them to set yet another variable (DESTDIR). But I would like
to avoid that if at all possible.
DESTDIR has a different purpose.
Installing to DESTDIR does not necessarily lead to a working and correct
installation, mainly when paths are involved, like e.g. RPATH settings.
Assuming that CMAKE_INSTALL_PREFIX would be /opt/foo, your executable might
get /opt/foo/lib as RPATH, also when installed to $DESTDIR/opt/foo.
So they will not have a correct RPATH.
You really should set CMAKE_INSTALL_PREFIX.
I'd like to. But CMAKE_INSTALL_PREFIX does not get recomputed when I change
MYDESTDIR and try to do "make install" again. Or at least I don't know how to
make it behave this way.
Besides, I don't use RPATH (at least not explicitely, hopefully cmake
is
Post by Michael Hertling
Post by Tomasz Grobelny
not
doing anything nasty behind the scenes).
But some day, you might want to use RPATH features as they are very
convenient in certain situations, or you might want to incorporate
the installation prefix or derivatives like CMAKE_INSTALL_PREFIX/lib
/${PROJECT_NAME} in your binaries which can be quite convenient, too.
Moreover, you can hardly prevent your project's users to use RPATH on
their own, see the CMAKE_INSTALL_RPATH/CMAKE_BUILD_WITH_INSTALL_RPATH
variables, e.g. In this regard, using the DESTDIR Makefile/environment
variable bears the risk of subtle failures and isn't worth the effort,
IMO. Thus, you should take Alex's warning absolutely seriously, or in
other words: Changing the installation prefix does invalidate your
already built targets, so you do need to reconfigure and rebuild.
Anyway, see [1] for a chance to add "DESTDIR=$MYDESTDIR" to the
generated Makefiles, provided that you are using GNU Make, but
even this won't work as expected since DESTDIR is hard-coded
in CMake, AFAIK, and due to other reasons.
Somewhat hackish (especially this \$\(firstword \$\(MAKEFILE_LIST\)\)
part). I've just come up with another solution (probably not less hackish,
but simpler and working):
set(CMAKE_INSTALL_PREFIX "\$ENV{MYDESTDIR}")
--
Regards,
Tomasz Grobelny
Michael Hertling
2011-04-14 03:57:34 UTC
Permalink
Post by Tyler
Post by Michael Hertling
Post by Tomasz Grobelny
Post by Alexander Neundorf
Post by Tomasz Grobelny
Post by Tyler
On Mon, Apr 11, 2011 at 8:54 AM, Tomasz Grobelny
Post by Tomasz Grobelny
Ok, but is there a way to achieve the same effect so that the user can
type just "make install" and not know anything about DESTDIR
environment
Post by Tyler
Post by Tomasz Grobelny
variable (provided he knows about MYDESTDIR)? Maybe it is possible
to
Post by Michael Hertling
Post by Tomasz Grobelny
Post by Alexander Neundorf
Post by Tomasz Grobelny
Post by Tyler
Post by Tomasz Grobelny
put this "DESTDIR=$MYDESTDIR" in the generated Makefiles somehow...
If I understand your use case right (which I might not as you
haven't
Post by Michael Hertling
Post by Tomasz Grobelny
Post by Alexander Neundorf
Post by Tomasz Grobelny
Post by Tyler
described what you're trying to do, just how you're trying to do
it),
Post by Michael Hertling
Post by Tomasz Grobelny
Post by Alexander Neundorf
Post by Tomasz Grobelny
Post by Tyler
maybe you can just override CMAKE_INSTALL_PREFIX.
If you go this route, check the archives because of the whole
_INITIALIZED_TO_DEFAULT aspect of that particular cache variable.
I already tried playing with CMAKE_INSTALL_PREFIX but the problem was
that value of MYDESTDIR was read (and saved to CMAKE_INSTALL_PREFIX)
only when configuring first time. That's why DESTDIR mechanism comes
closer to what I'm trying to achieve. My use case is something like
1. User has some default MYDESTDIR to non writable location.
2. User executes "cmake . && make install".
3. The installation fails because user has no rights to $MYDESTDIR.
4. User changes MYDESTDIR to another location (writable this time).
5. User executes "make install" once again and it should succeed.
Of course the user could set MYDESTDIR to correct location before
building but people often forget that. Now the tricky part is that users
are already used to this mechanism (for particular variable name, called
MYDESTDIR here). So taking different environment variable instead of
DESTDIR would allow me to minimize confusion among users. Otherwise I'll
just tell them to set yet another variable (DESTDIR). But I would
like
Post by Michael Hertling
Post by Tomasz Grobelny
Post by Alexander Neundorf
Post by Tomasz Grobelny
to avoid that if at all possible.
DESTDIR has a different purpose.
Installing to DESTDIR does not necessarily lead to a working and
correct
Post by Michael Hertling
Post by Tomasz Grobelny
Post by Alexander Neundorf
installation, mainly when paths are involved, like e.g. RPATH
settings.
Post by Michael Hertling
Post by Tomasz Grobelny
Post by Alexander Neundorf
Assuming that CMAKE_INSTALL_PREFIX would be /opt/foo, your executable might
get /opt/foo/lib as RPATH, also when installed to $DESTDIR/opt/foo.
So they will not have a correct RPATH.
You really should set CMAKE_INSTALL_PREFIX.
I'd like to. But CMAKE_INSTALL_PREFIX does not get recomputed when I change
MYDESTDIR and try to do "make install" again. Or at least I don't know how to
make it behave this way.
Besides, I don't use RPATH (at least not explicitely, hopefully cmake
is
Post by Michael Hertling
Post by Tomasz Grobelny
not
doing anything nasty behind the scenes).
But some day, you might want to use RPATH features as they are very
convenient in certain situations, or you might want to incorporate
the installation prefix or derivatives like CMAKE_INSTALL_PREFIX/lib
/${PROJECT_NAME} in your binaries which can be quite convenient, too.
Moreover, you can hardly prevent your project's users to use RPATH on
their own, see the CMAKE_INSTALL_RPATH/CMAKE_BUILD_WITH_INSTALL_RPATH
variables, e.g. In this regard, using the DESTDIR Makefile/environment
variable bears the risk of subtle failures and isn't worth the effort,
IMO. Thus, you should take Alex's warning absolutely seriously, or in
other words: Changing the installation prefix does invalidate your
already built targets, so you do need to reconfigure and rebuild.
Anyway, see [1] for a chance to add "DESTDIR=$MYDESTDIR" to the
generated Makefiles, provided that you are using GNU Make, but
even this won't work as expected since DESTDIR is hard-coded
in CMake, AFAIK, and due to other reasons.
Somewhat hackish (especially this \$\(firstword \$\(MAKEFILE_LIST\)\)
Hackish, ugly, non-portable and absolutely inadvisable. ;-)
Post by Tyler
part). I've just come up with another solution (probably not less hackish,
set(CMAKE_INSTALL_PREFIX "\$ENV{MYDESTDIR}")
That's not hackish, IMO, but even quite elegant, indeed. Nevertheless,
the limitations and risks mentioned earlier in this thread still hold.
A rather obvious example for the shortcomings of that approach is the
installation of a configuration file for the concerned package; see
the following CMakeLists.txt for a highly rudimentary realisation:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(MYDESTDIR C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
SET(CMAKE_INSTALL_PREFIX "\$ENV{MYDESTDIR}")
FILE(WRITE ${CMAKE_BINARY_DIR}/f.c "void f(void){}\n")
ADD_LIBRARY(f SHARED f.c)
FILE(WRITE ${CMAKE_BINARY_DIR}/f-config.cmake "FIND_LIBRARY(
F_LIBRARY f PATHS ${CMAKE_INSTALL_PREFIX}/lib NO_DEFAULT_PATH
)\n")
INSTALL(TARGETS f LIBRARY DESTINATION lib)
INSTALL(FILES ${CMAKE_BINARY_DIR}/f-config.cmake DESTINATION share)

Here, $ENV{MYDESTDIR} will end up as the installation prefix in the
config file, so another project that calls FIND_PACKAGE(f) to learn
about libf.so's location would need to have MYDESTDIR defined in its
environment. Thus, you extend the need for this environment variable
from your project to your project's users, i.e. you're about to shoot
yourself in the foot, and even worse, you're about to shoot in another
one's foot. OK, you might do some last-minute-modifications during the
installation with INSTALL(CODE/SCRIPT ...), or you might try to use the
CMAKE_CURRENT_LIST_FILE variable to find a way from the config file to
the library as it is done in the export files from INSTALL(EXPORT ...),
but I wonder if this can be set up in a bullet-proof way. To summarize,
delaying the expansion of CMAKE_INSTALL_PREFIX up to the installation
is most inconvenient for projects which install configuration files.

Regarding this and the already mentioned issues in this respect, for
what reason should one bank on an installation prefix evaluated at
installation time? Just because the users are accustomed to "make
install MYDESTDIR=..."? As I said before, I think that this is
worth neither the effort nor the limitations nor the risks.

Regards,

Michael
Tomasz Grobelny
2011-04-14 09:34:13 UTC
Permalink
Post by Michael Hertling
Post by Tomasz Grobelny
Somewhat hackish (especially this \$\(firstword \$\(MAKEFILE_LIST\)\)
Hackish, ugly, non-portable and absolutely inadvisable. ;-)
Post by Tomasz Grobelny
part). I've just come up with another solution (probably not less hackish,
set(CMAKE_INSTALL_PREFIX "\$ENV{MYDESTDIR}")
That's not hackish, IMO, but even quite elegant, indeed. Nevertheless,
What I'm concerned about is dependence on double evaluation. If one day
cmake developers decide that evaluation should be done differently and/or
different number of times this could break. But hopefully this will not
happen anytime soon.
Post by Michael Hertling
Here, $ENV{MYDESTDIR} will end up as the installation prefix in the
config file, so another project that calls FIND_PACKAGE(f) to learn
about libf.so's location would need to have MYDESTDIR defined in its
environment.
(...)
Regarding this and the already mentioned issues in this respect, for
what reason should one bank on an installation prefix evaluated at
installation time? Just because the users are accustomed to "make
install MYDESTDIR=..."? As I said before, I think that this is
worth neither the effort nor the limitations nor the risks.
Users are used to typing "make install" and currently MYDESTDIR is taken
from environment in Makefiles.
There are several factors that make this solution viable in my case:
- whole product is built internally in tightly controlled environment. I
mean: no one will try to build or even use the library outside our internal
servers. Before the build of the product environment is set up using a
shell script. On the other hand "tightly controlled" does not mean I (as
developer) can change anything in our build system. Even if I would like to
do it the correct way.
- currently we "suffer" consequences of installation time defined
installation directory. So moving to cmake will not change that in any way.
- currently we can have several builds and we switch between them using
environment variables. Both for build and for simple use.

I hope I understand the risks. And if I shoot myself in the foot, well...
that's called experience :-)
--
Regards,
Tomasz Grobelny
Loading...