Force CMake to use release/debug build of a package



  • Either my Google-fu is failing, or what I'm trying to do is too weird...

    The short version:

    I'm adding a package to my CMake configuration with find_package() and I would like to be able to somehow make it so that both the Release and Debug configurations of my project (in VS, but this is inherited from what CMake defines) use the files from the Release build of the package (the package does contain both and the paths switch automatically and accordingly when I change my project build type).

    Basically, bar depends on foo, which comes from find_package(foo), and for some reason I need bar to always link with the Release build of foo, even when building bar in Debug.

    So I'm thinking either tweaking find_package() to tell it to always use the Release build, or do something after find_package() to similarly force it to always use the Release build. But I can't find any details on how to do that.

    I have access to source of the package itself, so I could also edit that in some way, but... it sounds even yuckier than the alternative. Besides, the package still needs to work in the "normal" way for other use-cases (so I can't just gut out the Debug build and replace it by the Release one!).

    The long version:

    No, no long version, I'm not gonna justify why I want to do that.

    Mostly because I'm actually almost 100% sure that I'm :doing_it_wrong: and the whole thing is really just a hack. Besides, it doesn't really matter that it doesn't work as the consequences are ultra-minor. So I'm just curious as to whether there is a way to do what I described, more than a real solution to my full problem.



  • @dkf :well_you're_not_wrong: / :he's_out_of_line_but_he's_right: but also the thread for unhelpful help is :arrows:.

    Not that I really mind that my thread gets derailed so quickly, but I had a glimmer of hope that a reply in that thread itself would be somewhat useful... 😿


  • Considered Harmful

    @remi any way to tweak it before, and get it to believe the Debug artifact for package x is satisfied by the Release artifact?



  • @Gribnit I guess that would fall into the "gut out the Debug build [of the package] and replace it by the Release one" and no, I can't really do that. Well, I can, but I don't want to as the package still needs to be usable (in Debug) when used in other projects.

    Or do you have something in mind that I would do right at the time of the find_package(), not when building that package? If so, yes, this would be a great idea but... how do I do that??


  • Considered Harmful

    @remi said in Force CMake to use release/debug build of a package:

    Or do you have something in mind that I would do right at the time of the find_package(), not when building that package?

    This, sadly with no mechanism on offer. In Gradle we'd use a qualifierclassifier or resolution rule for this sort of thing - let the dependency tree get generated then screw with it before assembling.



  • @Gribnit said in Force CMake to use release/debug build of a package:

    This, sadly with no mechanism on offer.

    What's annoying is that somehow find_package(), or the code that uses the result of find_package(), knows how to do that. Looking into the .cmake file of that package, there's a lot of stuff like:

    set_property(TARGET foo APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
    set_target_properties(foo PROPERTIES IMPORTED_LOCATION_RELEASE "${SOME_PREFIX}/release/foo.lib")
    

    And of course the same thing in DEBUG somewhere else.

    So something inside CMake knows to use IMPORTED_LOCATION_RELEASE or IMPORTED_LOCATION_DEBUG. But the problem is that I don't know how to override that, and neither the doc for IMPORTED_LOCATION or IMPORTED_LOCATION_<CONFIG> are much help.

    I could of course manually override these properties after the find_package() but the issue here is that there isn't a single foo target in the package, there are several libraries, each with their target, so I would have to manually override several of them (and of course since some are just internal dependencies, it's not like I know in advance that I'm going to need them, as they are just indirectly added when I link with another one).

    I'm guessing I could have some code that finds all targets added by the find_package() call and for each of them, replace the IMPORTED_LOCATION_DEBUG by the IMPORTED_LOCATION_RELEASE, but apart from being a lot of work (:kneeling_warthog:) and an horrible hack (🤮), it might not be enough if I need more than just changing the lib I'm linking with (i.e. if other properties of the imported target are relevant).


  • Considered Harmful

    @remi can you jank with the environment, maybe symlinks or redirects/aliases?



  • @Gribnit It's on Windows, so symlinks don't really work. Though there are ways to, but... yuck. Anyway, that would mean tweaking the package itself, or at least the copy I'm using. Which might be a way to at least solve the issue on my computer, which is the only place where it actually happens, so that might not be that big of an issue in the end, but then again, not really what I'm looking for.



  • Possibility...

    1. Create a project you control, have it always reference the release versions of the libraries...
    2. Have all your other projects reference project just created above

  • Discourse touched me in a no-no place

    @remi said in Force CMake to use release/debug build of a package:

    It's on Windows, so symlinks don't really work.

    Symlinks work fine (assuming you're on NTFS, which is probably true) but the tools for working with them are uncommon.



  • @TheCPUWizard said in Force CMake to use release/debug build of a package:

    Possibility...

    1. Create a project you control, have it always reference the release versions of the libraries...
    2. Have all your other projects reference project just created above

    That means duplicating all the library definitions of the original project, I think. And there are, I don't know how many but several tens of libraries in that project, so the :kneeling_warthog: is raising its head here... Though I guess that would be a relatively clean way to work around the problem here, so I appreciate the idea.



  • @remi said in Force CMake to use release/debug build of a package:

    @TheCPUWizard said in Force CMake to use release/debug build of a package:

    Possibility...

    1. Create a project you control, have it always reference the release versions of the libraries...
    2. Have all your other projects reference project just created above

    That means duplicating all the library definitions of the original project, I think. And there are, I don't know how many but several tens of libraries in that project, so the :kneeling_warthog: is raising its head here... Though I guess that would be a relatively clean way to work around the problem here, so I appreciate the idea.

    Thanks 😁

    To clarify, I was not really talking about wrapping all of the definitions... More along the line of:

    1. Have a project that references the dynamic location of the libraries with "copy local true"
    2. Set this projects output to always be the saqme regardless of configuration
    3. Have other projects reference the original dlls but in the output folder of this project.
    4. Additional details....

  • Notification Spam Recipient

    @dkf said in Force CMake to use release/debug build of a package:

    the tools for working with them are uncommonbuilt-in but really want you to be Admin to use them.


Log in to reply