Hello,
I'm using Conan 1.0.4
Lately I've been trying to use the ycm generator for one of my projects, but the generated .ycm_extra_conf.py is not usable as-is, as one has to add the consumer project flags to it:
# .ycm_extra_conf.py
flags = [...]
flags.extend(['-I/path/to/project/include', '-std=c++14', '-D_NDEBUG', ...])
Should the generator only create a file containing the list of flags, which would then be included by .ycm_extra_conf.py?
In my case I want the .ycm_extra_conf.py to be at my project root, and the flags file in my build directory, refreshed each time I run conan install.
Maybe generating both files in the build directory would solve the issue without breaking current usage:
# on first run
$ cd build && conan install .. -g ycm
$ cp .ycm_extra_conf.py ..
# next runs
$ cd build && conan install .. -g ycm
To help us debug your issue please explain:
Honestly, I have no idea about this generator, it was mainly a contribution, the generator's code is quite easy. If you think it can be improved maybe you are the best person to know how to do it ;)
If I have some time this week-end I'll try to look into it.
This was a change that was necessary to clean some debt before 1.0: generators only have access and manage information about dependencies, but they don't have access to the current package. The original work by @skizzay implemented this, but we had to remove it.
So yes, I agree the best solution would be to have:
@theodelrieu I've actually had this "complaint" about this myself. Generators do not have the current build information because cpp_info doesn't become available until package_info is called. I haven't found a good way around this limitation. We cannot call package_info ourselves because the expectation in that method is that package_folder will be used when configuring directories. We'd need to distinguish calling package_info for development and package_info for packaging.
The best solution that I've found (which is actually superior to having conan itself trying to figure out all of the flags) is to use CMake's ability to export the compilation flags. If you look at the generated file, then you'll notice that it'll read in compilation flags database and use those flags instead of the default. This is more accurate since CMake actually generating the command that builds a particular file.
In your top level CMakeLists.txt file, add this somewhere set(CMAKE_EXPORT_COMIPLE_COMMANDS ON) Combined with the ycm generator, this should give you the correct set of compilation flags.
Actually, there is another use case, that is installing from conaninfo.txt, so a package_info() won't be there.
So it seems there should also be a way in which users can define their own input to ycm and include the info from the dependencies installed by conan. It seems that getting that info from cmake is a good approach, just to define how that "combination" with the generator could be automatically done.
@skizzay I tried to use YCM with compilation databse once, but relaunching CMake each time I added a file was a no-go for me.
Anyway I don't think the Conan generator can be of any help for the consumer project, as @memsharded mentioned in his previous comment.
I think that generating two files is the best we got:
# generated .ycm_extra_conf.py
flags = read_flags_from_file("conan_deps_flags_for_ycm.txt")
Then users have to copy (one time only) the .ycm_extra_conf.py from the build folder to wherever they want, and create a symlink to point to the build folder's conan_deps_flags_for_ycm.txt file.
That's a rough idea for now, if there is a better way I'll gladly take it :)
The way that I've been using this generator is that when I run conan install, I specify the generator for myself locally (conan install -g ycm ...) in my build directory since it's not needed by any client libraries. I manually tweak the default flags since most of the libraries that I'm working on at the moment are header only (which makes the CMake compilation database useless). I start my editor (good ol' vim) in my build directory, but load up its file explorer (NERDTree) in the source directory.
All of the external dependencies are resolved by the generator, which is really a good starting point. The internal flags just need a quick tweak in order to get right. I usually have multiple build directories, one for each configuration that I build. This method has been pretty good to me so far because I don't have to run conan install that often. Plus, I don't have to worry about my previous settings being overwritten with a fresh run of conan install because .ycm_extra_conf.py only gets written when I run it manually.
Both @memsharded and @theodelrieu made comments that made me think of something... We should probably have a way to pass in data to the generators. In this example, something like:
generators = "ycm", "cmake"
generator_config = {
"extra_compilation_flags": "-I%s/include" % os.path.dirname(__file__),
"some_other_flag": True
}
The Generator base class could then have a property
class Generator(...):
@property
def extra_config(self):
return self.conanfile.generator_config
The generator_config attribute would be an accumulated map, using dict.update of each config declared in a ConanFile.
Or I'm just getting too deep into something that can be solved in a much easier fashion or doesn't need to be solved at all???
This has been improved by recent work by @AlexandreBossard in #2519, so I think it might be considered solved (it will be released in 1.2), but please comment if otherwise. Thanks!
Most helpful comment
If I have some time this week-end I'll try to look into it.