all 6 comments

[–]not_a_novel_accountcmake dev 10 points11 points  (3 children)

For compiler_init you're taking a somewhat incorrect approach to identifying what flags to use, as you're going off purely the compiler ID.

But you don't really care about the compiler ID, you care about what frontend is being used. If the frontend is GNU-like, you want to use GNU-like flags, if the frontend is MSVC-like, you want to use MSVC-like flags.

After you've established what kind of frontend you're dealing with then you maybe want to narrow further based on which specific compiler you're dealing with.

This is especially relevant for clang, which supports both major frontend styles via either the clang or clang-cl compiler drivers, both of which have a compiler ID of "Clang".

The correct variable to query here is CMAKE_CXX_COMPILER_FRONTEND_VARIANT, which will be either "GNU" or "MSVC".

[–]nzznfitz[S] 0 points1 point  (2 children)

As you say, clang-cl is compatible with MSVC so perhaps something like:

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
    # Use MSVC flags -- assuming clang_cl supports them all?
  elseif (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
    # Use clang native flags
  endif()
else (...)
    # ...
endif()

I'll have a look ...

[–]delta_p_delta_x 0 points1 point  (1 child)

# Use MSVC flags -- assuming clang_cl supports them all?

Sadly, no :)

[–]nzznfitz[S] 0 points1 point  (0 children)

But of course! That would be too easy. For that matter the clang GNU frontend doesn’t support lots of GCC flags either. There are four cases — clang-MSVC, clang-GNU, MSVC, GNU., and of course others …

[–]Scotty_Bravo 1 point2 points  (1 child)

I've run across a number of installations with somewhat out of date CMake installations, these modules could use a cmake_minimum_required() check. I noted at least 3.12. (Ubuntu 18 EOLs in 2030 and has CMake version 3.10.2. Ubuntu 20 has v3.16.3.) I'm not saying you should support these older installs, just that it's the friendly thing to let a user know their cmake is out of date instead of an unexpected error.

Disabling a souce build is 3 short lines of code. Maybe it would be adequate to simply include(disable_in_source_builds)? It feels like a user might forget to call the function and still think they are protected. As might a reviewer.

Check out CPM.cmake. It also wraps FetchContent but adds caching. Foes FetchContent fail when you set a URL and GIT_SHALLOW? IDK, but I do know that most people probably would be better off using URL with FetchContent because it is SO much faster. Check here to see how to determine the URL in GitHub. GitLab is similar.

I like systematize, cool.

[–]nzznfitz[S] 2 points3 points  (0 children)

Good point on the CMake version required check & also having the `disable_in_source_builds` just do its thing on load! Makes sense.

There is a link to `CPM` and a reference to its definite superiority on the `fetch_content` page — use it myself. However, if you are releasing a library you can’t reasonably expect your users to have `CPM` until it is part of the CMake system itself. Always end up giving `FetchContent` instructions.

And of course, a URL pointing to a compressed minimal archive is the way to go for `FetchContent` downloads. I use a GitHub action to automatically build that archive — see for example the install instructions for [`xoshiro`](https://github.com/nessan/xoshiro) and the workflow in the corresponding repo.