-
Notifications
You must be signed in to change notification settings - Fork 474
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
Directory-specific configuration file #1393
Comments
For the
differ from
Using process substitution you can (on unix like systems) handle the simple filename case as well with a simple |
One difference is that Also, it's possible to specify a CMake compiler launcher with e.g. |
Hi @jrosdahl, Thanks for opening the issue. This is a feature that I would really like to see in ccache and I think it would make ccache a lot easier to configure, if implemented right. Here are my thoughts:
I don't know anything about autofs or its performance. However, if its that slow, how probable is it that someone would try to compile from an autofs mount in the first place? The idea is that the ccache.conf would be in the same directory as the source code, after all? Assuming that it is probable and hence undesirable: Maybe we can learn from other tools who offer project-specific configuration options, e.g. git?
For my specific use case (using ccache with cmake), passing command line options to ccache is difficult. In fact, it would require a hack similar to the one mentioned in #747. The same goes for the second proposal, introducing a new environment variable. I am afraid the "default search" (option 1) is the only one that would actually make ccache easier to configure when using cmake. Since I am not the only one using ccache, I would really like to hear other peoples' opinion on this. @srohmen already worked on something similar. Maybe he has something to add? |
The issue is not that building on a network filesystem is slow (well, it is, but with OK latency) – it is that queries to automount a file system can be much slower. Let's say that the current working directory is To clarify, the problem is not if
Git does not have the same problem since there is always a
How do you specify the location of the cache directory and its maximum size? |
Hi @jrosdahl, thanks for the clarification! I trust your experience with autofs and the likes and agree that this could turn into a problem. Nevertheless, I am confident it can be solved.
Not technically true. /home/ben $mkdir test
/home/ben $cd test
/home/ben/test $git init
Initialized empty Git repository in /home/ben/test/.git
/home/ben/test $mkdir subdir
/home/ben/test $cd subdir
/home/ben/test/subdir $git status
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track) Git does look for
In the user options under |
Just found this in the git documentation:
So another environment variable that would be hard to set when using cmake... Another thing I was wondering about: Would this "config searching" be triggered on every invokation of ccache, i.e. on every object that is built? Or is there some sort of "config caching" or similar going on? |
I agree that it would be great if things just work! Unfortunately I don't see a good way in this case.
Yes, I didn't mean to imply otherwise. With "there is always a .git directory to look for" I meant that there is always a No, Git doesn't deal with the problem and it doesn't have to. Even if Git would try to access, say,
Yes, on every invocation.
OK. How do you configure CMake to use ccache? |
Okay, I see the problem now.
With an ugly hack:
More details on the hack here. The problem boils down to this: Environmental Variables that are set in cmake are used during the setup stage but do not persist during the build stage. Hence, setting up ccache with environment variables is hacky. Adding command line options for ccache would be similarly hacky. Instead, it would be nice to have a way to say to ccache: "For all the work you do in this folder and the directories below, use this config". Furthermore, we want to prevent ccache from looking for the config on each invocation, as this process can be very slow. Instead, it would be beneficial to setup ccache once and have it apply the same configuration throughout the build process. The challenge is to make sure that ccache does not apply set configuration to other projects. Perhaps this could be prevented by checking the path of the passed source code file? In that case, one could say to ccache "Hey, if the file path starts with /home/ben/myproject1, use config 1. If it starts with /home/ben/myotherproject, use config 2". What do you think @jrosdahl ? |
Yes, I agree that the set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) With my proposal, it would look like this: set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM} @ccache.conf) Do you mean that you think that this is too hacky? I don't think that anybody has suggested setting environment variables inside CMake scripts. Setting
Sorry, I don't understand your idea. I think you'll need to describe it in more detail to get comments. |
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM} @ccache.conf) This is not bad. What about the overhead for searching the config file in this case? In a project like this: my_project/
│
├── CMakeLists.txt
├── ccache.conf
│
├── src_a/
│ └── main_a.cpp
│
├── src_b/
│ └── main_b.cpp
│ We would descend into
My suggestion is to have a mapping of source-file paths to config paths in the user-specific config file, e.g. like this:
I know that this is also not ideal. I'm just brainstorming here. |
If
No, because if there is no Note that you would also have the option to specify exactly the file you want inside the CMake script, thus not relying on searching for the file: set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM} @${CMAKE_SOURCE_DIR}/ccache.conf)
Thanks for the clarification and providing ideas. Although it would not be possible to add syntax similar to your example since it would be backward incompatible, it could indeed be valuable to be able to have project-specific settings in the main configuration file. It would be possible with another syntax, though. That said, I think that such a feature would be a complement rather than an alternative to the |
Hello @jrosdahl, Thanks for your detailed explanation, as always. I now see that your solution avoids the performance issues of my initial solution. I also agree that set(CMAKE_C_COMPILER_LAUNCHER ${CMAKE_COMMAND} ${CCACHE_PROGRAM} @ccache.conf) is much more elegant than set(ccacheEnv
CCACHE_BASEDIR="${PARENT_DIR}"
CCACHE_NOHASHDIR=true
...
)
set(CMAKE_C_COMPILER_LAUNCHER ${CMAKE_COMMAND} -E env ${ccacheEnv} ${CCACHE_PROGRAM}) I think this solution is really good. The only thing that still bothers me is that it requires the user to adapt the CMake configuration file. If you have any patience left (I hope), here is another idea: How about a strongly limited search for project-specific config files? It could work like this: Ccache looks for a ccache.conf in the CWD. If it doesn't find one, it stops there and uses the user- and system-specific confs by default. However, the user has the option to adapt the search depth by setting an environment variable, e.g. |
Hi,
If we continue using CMake as the example build system (generator) which you want to configure to use ccache, you create a temporary build directory and start the build there. For ccache to find a configuration file in CWD the file must be located in the temporary build directory, so a configuration file bundled with the project won't be found. So the user must do something for ccache to find project-specific configuration, either:
The first one does not seem easier than setting The last one would indeed be possible with your suggestion. Is that what you had in mind? It doesn't feel more ergonomic to me than the other options. To sum it up, I'm afraid I don't understand which actual problem this would solve. There is also a security aspect to this that I haven't mentioned before: the ccache configuration includes several settings that can modify which compilation command is invoked. Let's assume that ccache by default would look for configuration in CWD. If the user has set up ccache to masquerade as the compiler, then it would suddenly be potentially dangerous run e.g. |
Unfortunately, I could not solve my use-case by using CMAKE_CXX_COMPILER_LAUNCHER, as this variable is completely disregarded for the CMake Visual Studio generator. msbuild (or whatever executes the build) will per default execute a compiler named cl.exe (aka MSVC). Every attempt to overwrite the compiler executable and command line in that environment failed (sometimes just strange race conditions in the build system, long painful story...). Thus, my solution is to use the compiler impersonation feature provided by ccache. So I create a symlink to ccache.exe into the build folder, named cl.exe. Now, I have project specific settings (e.g. the base_dir configuration) and my modified ccache version picks up a ccache-extra.conf file from the current working directory implicitly. So far this work quite well, but I understand that there might be a better solution. I am afraid that it is not possible to use the I thought it would be possible to tell ccache in the impersonation mode, still to "consume the following parameter as ccache parameter" and not pass it down to the real compiler. But I cannot find it in the documentation anymore. Maybe I just dreamed it or I am blind. However, the EDIT: |
Well, CMake doesn't really enforce out-of-source builds but you are right, it is the standard to do so. So a more reasonable default for the search depth would be 1 (instead of 0). This would still be manageable performance-wise, I assume?
The main difference is that this config will complement the other configs, right? Also, I would argue that my idea is still simpler, because CCACHE_DIRCONFIG would have to be adapted for each project, whereas the default search depth can be set once in the user config.
This is indeed a problem. But then again: If a code repository contains malicious code, it is a bad idea to compile it in any case? |
@srohmen wrote:
Right, the The masquerading mode has never been able to parse compiler parameters as ccache parameters. Do I understand correctly that you have not been able to make the output from the CMake Visual Studio generator run |
@BenPortner wrote:
I agree that 1 would be a better default.
I guess we're talking about two separate things at once now:
Regarding the first: I don't understand why Regarding the second: I think that skipping the ordinary configuration files does not sound like a good idea. For example, it would mean that cache-specific configuration like maximum cache size suddenly wouldn't be applied if there is a directory config in some project.
If a user executes a build script (or any script or bundled program for that matter) found in an unknown repository then that script could be malicious, and it's easy to realize that this could be a problem and take appropriate actions. What would not be easy to realize is that merely running a system command inside an unknown repository could execute arbitrary code from that repository. That's why I gave |
Yes, as long |
Hi, I'd like to add my use-case here, which is much simpler (although I tried the suggested config-file route as well). I only need to pass the base_dir or hash_dir option to ccache in order to facilitate caching across different source trees (typically when you pull different tags/branches and you like to work/test on them quickly. When dealing with large codebases this "quickly" becomes "painfully slow"). I successfully integrated ccache into cmake/Visual Studio (using ninja as the build system) using the suggested way here: https://github.com/ccache/ccache/wiki/MS-Visual-Studio#usage-with-cmake. However I never could get the two options to pass through to the cl.exe (ccache)... -regards, |
There are currently four ways to specify ccache configuration:
CCACHE_CONFIGPATH
)CCACHE_CONFIGPATH
is not set)What's missing is an easy way to set configuration for a directory (project), either in a static file or in a generated file that can be read in addition to the other configuration files. See also discussion in #747.
One solution would be for ccache to search in the current working directory and its parents for a file with a known name, e.g.
.ccache.conf
. It would however not be a good idea to enable such a search by default. This is because ccache then (if no directory-specific configuration file is found) will search in all parent directories, including e.g./home/.ccache.conf
on Unix systems, and suchstat
calls can be very slow if the directory is an autofs mount point or similar.Here is my currently best ideas:
@file
at the command line before the compiler, extending theccache [KEY=VALUE …] compiler [compiler options]
form toccache [@file ...] [KEY=VALUE …] compiler [compiler options]
. Example:@file
syntax understood by many compilers.file
could be an absolute path or a simple filename in which case parent directories are searched.CCACHE_DIRCONFIG
/dir_config
configuration option to get a similar effect to@file
.The text was updated successfully, but these errors were encountered: