-
-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reconsider install location #222
Comments
So if I understand correctly, assuming somebody installs fplus like the following on a normal Ubuntu git clone https://github.com/Dobiasd/FunctionalPlus
cd FunctionalPlus
mkdir build
cd build
cmake ..
make
sudo make install it would not land in I don't know about the percentage of fplus users not using CMake, but writing Is the kind of trouble, that having it in Asking, because glancing at the readme files from some other libraries (using JSON libs as a random example), they all seem to use the way we currently also have:
Or maybe I'm missing something here? |
The If there was another folder that uniquely identified this library, then including an unrelated dependency would not cause this issue. Of course, a conscious user can just pass the necessary flag to define the location ahead of time: cmake -S . -B build -D CMAKE_INSTALL_INCLUDEDIR=include/FunctionalPlus
cmake --build build
sudo cmake --install build but of course this requires prior knowledge about the issue and how it can be solved. This is the kind of (arcane) knowledge that comes with dealing with distros and managing packages for them. |
Oh yes, I did. 😬
Thanks for the good explanation and example. So having fplus installed at multiple locations alone suffices to create problems, if one is not careful about the priority of the different include paths given to the compiler. Makes sense, however
I'm worried about the clients not using CMake. I know you say "why would anyone want to do that???". 🙂 But even if we might not agree with the reason for doing that, I'd like to avoid breaking their workflow nonetheless. Is there some way we could estimate the percentage of such users? I'm especially worried about the people using FunctionalPlus only because of frugally-deep. They often come from a data-science/Python background and might not be used to building C++ projects using CMake. |
Since I'm not aware of fplus being distributed in distro package managers based on the INSTALL.md, this might not be such a huge problem right now, but I wanted to let you know that there is a possibility of such interaction resulting in unintended includes of libraries, where the behaviour depends on the order of the include flags (you can't really control these from CMake). Unfortunately, I do not know of a way to gauge non-CMake usage of the library, so I'm not going to push you to change things. It's enough if you know the problem exists and how it can be solved. |
Thanks. ❤️ |
"then you get the whole of /include added to your include paths"... There are two world views with regard to include paths and install prefixes:
When the install prefix stays as is, both audiences are served well: it does 'just works' out of the box, and can be tweaked to 'do the right thing' by specifying the prefix at build and install time. Aside... Actually, the "I'm sure you can guess what kind of trouble that could cause." problem is only a consequence of the way compilers (and linkers, for that matter) expect the user to set up their environment correctly:
The preprocessor will not complain about having two matches when looking on I think this problem is not up to library/package maintainers to solve, but to the C++ committee. |
This isn't really something the committee can change, people writing libraries should excercise some level of discipline and have knowledge about packages. I admit the resources to acquire this kind of knowledge is scarce and not of great quality. I myself plan to work on something like a modern CMake tutorial that would ideally cover topics like this, as I believe the current availability of documentation surrounding such topics is in a dire situation. Unless you trip into the problems you'd have never known about them. Regarding your example of having different versions of the same library, you can still separate things into libraries from the CMake side and link to the appropriate target. Again, this requires some level of discipline. |
You're right; I first thought 'compiler vendors' should solve, but why would they if the compilation model leaves this issue in the open? So I aimed a little higher and wrote 'committee' :). But then again, I'm not sure the standard doesn't mention this.
So if the header is not uniquely identified, can we say the implementation is in contradiction with the standard? |
It is true that the CMake install process is not widely understood, but one must be very careful with the implementation of this feature so that a package maintainer can still set include(GNUInstallDirs)
set(CMAKE_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/FunctionalPlus") To be correct, you need to check that if (NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
set(override_includes YES)
else ()
set(override_includes NO)
endif ()
include(GNUInstallDirs)
# CMAKE_INSTALL_INCLUDEDIR is defined as a cache variable now
if (override_includes)
# Force override. Only happens when the user wasn't trying to override it the first time.
# Won't be executed multiple times because override_includes is always false after first run.
set(CMAKE_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/FunctionalPlus"
CACHE PATH "C header files (include)" FORCE)
endif () But wouldn't it be simpler to just teach people CMake better? I'm not sure this sort of thing belongs anywhere besides CMake's documentation & supporting blog posts. |
That's a lot of code to replicate what cache variables do already: set(CMAKE_INSTALL_INCLUDEDIR "include/FunctionalPlus" CACHE PATH "")
include(GNUInstallDirs)
And that is actually a really elegant way to solve this problem. Thanks for the idea! |
I didn't bother to dig through the CMake source code. I suppose they wouldn't be able to change it without a policy so given that it has always been
Happy to be of service, even if it isn't my preferred approach🙂. Generally speaking, the argument to |
This came up in the C++ Slack earlier and reminded me that this library could cause the same issue as well.
Consider that
include/fplus
gets installed as the<prefix>/include/fplus
directory and adds<prefix>/include
to the include paths of the installed target. If you link against the installedFunctionalPlus::fplus
target, then you get the whole of<prefix>/include
added to your include paths. I'm sure you can guess what kind of trouble that could cause.My preferred install path where I have control is
<prefix>/include/<project-name>-<project-version>
, so when linking against the CMake package target, you don't get the whole world in your include paths implicitly, just the library you linked against and possibly dependencies.I propose that this be changed and instead of
<prefix>/include
FunctionalPlus be installed to<prefix>/include/FunctionalPlus
. Anyone not using CMake (why would anyone want to do that???) can still reach the library with#include <FunctionalPlus/fplus/fplus.hpp>
via the implicit system include paths, but anyone using the CMake package will get the correct include path that makes only FunctionalPlus available, so#include <fplus/fplus.hpp>
can be used like usual.The text was updated successfully, but these errors were encountered: