Skip to content
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

Wish: Recognize commands for Qt projects #48

Open
winterz opened this issue Dec 16, 2024 · 4 comments
Open

Wish: Recognize commands for Qt projects #48

winterz opened this issue Dec 16, 2024 · 4 comments

Comments

@winterz
Copy link

winterz commented Dec 16, 2024

We write a lot of Qt-based projects.
In order to have a nicely working gersemi we need to add "stubs" (like qt_commands.cmake.txt) for the Qt CMake commands to every single project.

iow: we copy the attachment (remove the '.txt' extension) into ./cmake/stubs for every project and have definitions=[./cmake/stubs] in our .gersemirc

it would be really nice if gersemi could somehow recognize Qt commands automatically.

The complete list of CMake commands provided by Qt is at https://doc.qt.io/qt-6/cmake-command-reference.html
It is a long list; and probably a list that will change with new Qt releases.

@BlankSpruce
Copy link
Owner

I would like to avoid bringing other commands as supported out of the box for two reasons:

  • The process of adding these commands in "native" form is only semi-automatic for official CMake commands. While I have some helper scripts to do that at the end of the day I need to make verification manually because there are things like add_custom_target where arguments after ALL but before COMMAND require special handling. It's a little bit cumbersome process, I haven't found better one at the moment and I don't want to have extra thing to carefully maintain.
  • I don't know how backward compatible are signatures of commands offered by Qt within major version and, what's more important, do they diverge between major versions like Qt5 vs Qt6? That would be a bummer if there was such case because on source code level I have no way to guess what Qt version I'm dealing with. In contrast, CMake's commands offer, fortunately, good backward compatibility and I can safely add support for new keywords without worrying that they might mean substantially different things in different versions.

Perhaps there's alternative approach available. First thing that came to my mind would be supporting some kind of plugin system and I could even advertise such plugins in README, prepare an example plugin etc. I guess that would be the closest to out of the box experience.

Another approach, although it might suffer from version problem alluded earlier, would be supporting some kind of community driven repository of such commands. I'm guessing there's some room for Boost, Qt, SDL and other popular libraries which might provide their own custom commands. This is somewhat weaker variant of plugin approach.

I need to think a little bit more to find a satisfactory solution for myself and the users.

@BlankSpruce
Copy link
Owner

@winterz
What are your thoughts on the topic? What would be the second best thing other than supporting officially Qt commands for you or your organization? I'm open to any idea since it might inspire me somewhat.

@winterz
Copy link
Author

winterz commented Dec 18, 2024

on linux anyway there is /usr/lib64/cmake (or /usr/lib/cmake).

it's a bit slower (not by much and there are lots of "ignoring" messages), but what if we added an option for searching built-in system directories.

you can already do this yourself with definitions: [/usr/lib64/cmake] but that's not portable to Mac for instance. and also the system directory option wouldn't print any "ignoring" or some other diagnostics (like conflicting definitions)

also this doesn't help if you hand-built Qt/boost/etc or installed yourself in non-standard locations.

@BlankSpruce
Copy link
Owner

Although tempting how easy it would be here's a caveat why it won't work in general (you might have already noticed the pattern of difficult to achieve generality):

Taking for instance qt_add_bigresources and looking at the source code current gersemi won't be able to detect the keywords because this definition doesn't uphold its end of the deal (it doesn't matter how simple this definition is) :
https://github.com/qt/qtbase/blob/bbcf47a07d3ec138016d4f997c9b4849598c2f10/src/corelib/Qt6CoreMacros.cmake#L587

if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
    function(qt_add_big_resources outfiles)
        if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
            qt5_add_big_resources(${outfiles} ${ARGN})
        elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
            qt6_add_big_resources(${outfiles} ${ARGN})
        endif()
        set("${outfiles}" "${${outfiles}}" PARENT_SCOPE)
    endfunction()
endif()

if statement isn't problematic but the fact that call is delegated to specialized alternatives qt5_add_big_resources and qt6_add_big_resources. If you were to use that exact alternative for Qt6 then it would work:
https://github.com/qt/qtbase/blob/bbcf47a07d3ec138016d4f997c9b4849598c2f10/src/corelib/Qt6CoreMacros.cmake#L474

function(qt6_add_big_resources outfiles )
    # ...

    set(options)
    set(oneValueArgs)
    set(multiValueArgs OPTIONS)

    cmake_parse_arguments(_RCC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
    
    # ...
endfunction()

I'm slowly converging to conclusion that plugin based approach might be the best in general because you could then simply install gersemi-qt6 plugin that'd deal with these things and gersemi would somehow take that extra source of truth into the account. I need to:

  • try it out a little bit before going further with that,
  • figure out how pre-commit hook can be augmented by such plugins (especially important if some organizations want to develop their own plugins but don't want to or can't expose them to open source community),
  • what capabilities can be exposed,
  • what contract should be in place between plugins and gersemi to make it just work.

I hope to find some time for these activities after New Year's Day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants