Re: [CMake] Correct handling of absolute/relative installation paths
Le 27/07/2017 à 13:08, Eric Noulard a écrit : 2017-07-27 12:28 GMT+02:00 David Demelier>: Hello, I'm still trying to find a correct solution to handle user specified installation paths. Let's consider two kind of paths: - WITH_BINDIR (default: bin/) where to install executables, - WITH_DATADIR (default: share/project_name/) where to install extra data. I want to let the user configuring those paths because not all distributions use the same paths (e.g. bin vs usr/bin). Then, I also like to build the whole CMake project by creating the hierarchy as it would be installed like: /WITH_BINDIR/myapp /WITH_DATADIR/somestuff.txt Do you mean here that you setup CMAKE__OUTPUT_DIRECTORY (variable or target property) to your favorite value or Both, I set the output directory for executable to WITH_BINDIR value and also install it as destination. My opinion is that you should never use absolute path (besides some very specific case on unix where you want to put something in /etc/...) You should ask your user for DATADIR BINDIR etc... This is what I have done in my CMakeLists.txt, the cmake invocation fails if BINDIR and/or DATADIR are absolute. But again, then with some package managers you get in troubles because they specify absolute path. See the RPM default macro: /usr/bin/cmake \ -DCMAKE_C_FLAGS_RELEASE:STRING="-DNDEBUG" \ -DCMAKE_CXX_FLAGS_RELEASE:STRING="-DNDEBUG" \ -DCMAKE_Fortran_FLAGS_RELEASE:STRING="-DNDEBUG" \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ -DCMAKE_INSTALL_PREFIX:PATH=/usr \ -DINCLUDE_INSTALL_DIR:PATH=/usr/include \ -DLIB_INSTALL_DIR:PATH=/usr/lib64 \ -DSYSCONF_INSTALL_DIR:PATH=/etc \ -DSHARE_INSTALL_PREFIX:PATH=/usr/share \ And if you add any new variable, you should prefix by %{prefix} which is also absolute... I wouldn't try to mimic install tree during the build (if it is what you are doing), The nice thing is that you can easily run/debug the application especially if that application needs to find some plugins/data while running by evaluating paths to them. I'll probably go for something like a pre-install target like you said instead of mimic'ing the build tree. And disable that target if any of the paths are absolute. Thanks for the answers! -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake
Re: [CMake] Correct handling of absolute/relative installation paths
It's also handy to get installation paths from GNUInstallDirs https://cmake.org/cmake/help/v3.4/module/GNUInstallDirs.html especially if you expect to install libs on linux which either go to lib or lib64. many things that install to windows just supply a standard base path (/program files/) and then still use bin, lib, share, etc in that path... It is an annoyance to have to override dll installation to bin instead of lib on windows include( GNUInstallDirs ) if( WIN32 ) set( BINARY_OUTPUT_DIR ${CMAKE_INSTALL_BINDIR} ) set( SHARED_LIBRARY_OUTPUT_DIR ${CMAKE_INSTALL_BINDIR} ) set( SHARED_LIBRARY_LINK_DIR ${CMAKE_INSTALL_LIBDIR} ) else( WIN32 ) set( BINARY_OUTPUT_DIR ${CMAKE_INSTALL_BINDIR} ) set( SHARED_LIBRARY_OUTPUT_DIR ${CMAKE_INSTALL_LIBDIR} ) set( SHARED_LIBRARY_LINK_DIR ${CMAKE_INSTALL_LIBDIR} ) endif( WIN32 ) and then use the aliased path instead macro( install_my_thing ) install( TARGETS ${ARGV} RUNTIME DESTINATION ${BINARY_OUTPUT_DIR} LIBRARY DESTINATION ${SHARED_LIBRARY_OUTPUT_DIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) endmacro( install_my_thing ) People will inevitably also respond and say 'but dlls install as runtime' which is probably true these days. All I can do is copy the cmake stuff I have that definitely works; which has been around since 2.6 or something... So it's probably simpler than what I've shared above. On Thu, Jul 27, 2017 at 4:08 AM, Eric Noulardwrote: > > > 2017-07-27 12:28 GMT+02:00 David Demelier : > >> Hello, >> >> I'm still trying to find a correct solution to handle user specified >> installation paths. >> >> Let's consider two kind of paths: >> >> - WITH_BINDIR (default: bin/) where to install executables, >> - WITH_DATADIR (default: share/project_name/) where to install extra >> data. >> >> I want to let the user configuring those paths because not all >> distributions use the same paths (e.g. bin vs usr/bin). >> >> Then, I also like to build the whole CMake project by creating the >> hierarchy as it would be installed like: >> >> /WITH_BINDIR/myapp >> /WITH_DATADIR/somestuff.txt >> > > Do you mean here that you setup CMAKE__OUTPUT_DIRECTORY (variable or > target property) to your favorite value > or > You build and then install with the / prefix? > > >> >> Using relative paths makes the application relocatable, if I keep >> WITH_BINDIR set as "bin" I can get the executable path at runtime, going >> through its parent (bin/../) and then I can go share/project_name. >> Obviously this is only valid for relative paths. >> >> However, a very high number of package managers build programs by >> specifying absolute paths, it is not an issue: instead of getting the >> directories at runtime, I use directly the absolute ones. >> >> On unix it can still work because it will just be translated as: >> >> /usr/local/bin/myapp >> /usr/local/share/project_name/somestuff.txt >> >> This is much bigger an issue on Windows if the user set WITH_BINDIR to >> something like D:/alt/bin >> >> The path would be translated to >> >> D:/alt/bin >> >> which is invalid on Windows. >> >> I like very much having this kind of `fakeroot' directory where you can >> have a preview on how the project looks like but I don't know what to do if >> paths are absolute, especially on Windows. >> > > My opinion is that you should never use absolute path (besides some very > specific case on unix where you want to put something in /etc/...) > You should ask your user for > >DATADIR >BINDIR >etc... > > all those var should be relative path. > > and an eventual >INSTALL_PREFIX > which could be absolute. > > In any case if you really want to tolerate absolute path given by the > user, but still want to mimic install location during the build > then you'll have to escape it. > > For each path you expect from the user: > > check the path with if(IS_ABSOLUTE path) and compute some relative path > a) if you are on Windows remove the drive letter, i.e. D:/alt/bin > becomes alt/bin > (or network drive share name //shairedisk/alt/bin becomes > alt/bin) > b) if you are on Unix > > >> >> What are your thoughts on that, recommandations? >> > > I wouldn't try to mimic install tree during the build (if it is what you > are doing), > If I have a need to "verify" install tree structure then **after the > build** I would do a fake install with a particular > local prefix (as CPack does before packaging). > > Note that for similar reason CPack has to track files installed with > absolute destination and > possibly error out when it cannot handle it, particularly on Windows > oriented generator: > see e.g.: > https://cmake.org/cmake/help/v3.7/variable/CPACK_ERROR_ON_ > ABSOLUTE_INSTALL_DESTINATION.html > > AFAIK, IFW and NSIS do not work with, absolute installed files. > > > -- > Eric > > -- > > Powered by www.kitware.com > > Please keep messages on-topic and check the CMake FAQ at: >
Re: [CMake] Correct handling of absolute/relative installation paths
2017-07-27 12:28 GMT+02:00 David Demelier: > Hello, > > I'm still trying to find a correct solution to handle user specified > installation paths. > > Let's consider two kind of paths: > > - WITH_BINDIR (default: bin/) where to install executables, > - WITH_DATADIR (default: share/project_name/) where to install extra > data. > > I want to let the user configuring those paths because not all > distributions use the same paths (e.g. bin vs usr/bin). > > Then, I also like to build the whole CMake project by creating the > hierarchy as it would be installed like: > > /WITH_BINDIR/myapp > /WITH_DATADIR/somestuff.txt > Do you mean here that you setup CMAKE__OUTPUT_DIRECTORY (variable or target property) to your favorite value or You build and then install with the / prefix? > > Using relative paths makes the application relocatable, if I keep > WITH_BINDIR set as "bin" I can get the executable path at runtime, going > through its parent (bin/../) and then I can go share/project_name. > Obviously this is only valid for relative paths. > > However, a very high number of package managers build programs by > specifying absolute paths, it is not an issue: instead of getting the > directories at runtime, I use directly the absolute ones. > > On unix it can still work because it will just be translated as: > > /usr/local/bin/myapp > /usr/local/share/project_name/somestuff.txt > > This is much bigger an issue on Windows if the user set WITH_BINDIR to > something like D:/alt/bin > > The path would be translated to > > D:/alt/bin > > which is invalid on Windows. > > I like very much having this kind of `fakeroot' directory where you can > have a preview on how the project looks like but I don't know what to do if > paths are absolute, especially on Windows. > My opinion is that you should never use absolute path (besides some very specific case on unix where you want to put something in /etc/...) You should ask your user for DATADIR BINDIR etc... all those var should be relative path. and an eventual INSTALL_PREFIX which could be absolute. In any case if you really want to tolerate absolute path given by the user, but still want to mimic install location during the build then you'll have to escape it. For each path you expect from the user: check the path with if(IS_ABSOLUTE path) and compute some relative path a) if you are on Windows remove the drive letter, i.e. D:/alt/bin becomes alt/bin (or network drive share name //shairedisk/alt/bin becomes alt/bin) b) if you are on Unix > > What are your thoughts on that, recommandations? > I wouldn't try to mimic install tree during the build (if it is what you are doing), If I have a need to "verify" install tree structure then **after the build** I would do a fake install with a particular local prefix (as CPack does before packaging). Note that for similar reason CPack has to track files installed with absolute destination and possibly error out when it cannot handle it, particularly on Windows oriented generator: see e.g.: https://cmake.org/cmake/help/v3.7/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.html AFAIK, IFW and NSIS do not work with, absolute installed files. -- Eric -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake
[CMake] Correct handling of absolute/relative installation paths
Hello, I'm still trying to find a correct solution to handle user specified installation paths. Let's consider two kind of paths: - WITH_BINDIR (default: bin/) where to install executables, - WITH_DATADIR (default: share/project_name/) where to install extra data. I want to let the user configuring those paths because not all distributions use the same paths (e.g. bin vs usr/bin). Then, I also like to build the whole CMake project by creating the hierarchy as it would be installed like: /WITH_BINDIR/myapp /WITH_DATADIR/somestuff.txt Using relative paths makes the application relocatable, if I keep WITH_BINDIR set as "bin" I can get the executable path at runtime, going through its parent (bin/../) and then I can go share/project_name. Obviously this is only valid for relative paths. However, a very high number of package managers build programs by specifying absolute paths, it is not an issue: instead of getting the directories at runtime, I use directly the absolute ones. On unix it can still work because it will just be translated as: /usr/local/bin/myapp /usr/local/share/project_name/somestuff.txt This is much bigger an issue on Windows if the user set WITH_BINDIR to something like D:/alt/bin The path would be translated to D:/alt/bin which is invalid on Windows. I like very much having this kind of `fakeroot' directory where you can have a preview on how the project looks like but I don't know what to do if paths are absolute, especially on Windows. What are your thoughts on that, recommandations? Regards, -- David Demelier -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake