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

Add ability to build minmea with meson #28

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

ssloboda
Copy link
Contributor

Hi, is this something that you would consider merging? I'm currently writing a library that pulls in minmea as a dependency and I needed to build it with meson to do so. I thought the work done here might be useful for others who are also using the meson build system.

This function is useful when writing libraries that use minmea and support NMEA
as well as other sentence types.
@mtp401
Copy link

mtp401 commented Mar 6, 2018

@kosma can you take a peek when you get a chance? thanks!

@kosma
Copy link
Owner

kosma commented Mar 8, 2018

I'm gonna need some rationale behind making a minmea directory. This is a somewhat breaking change for the users. Why does Meson require a subdirectory?

@kosma
Copy link
Owner

kosma commented Mar 13, 2018

@ssloboda @mtp401

@ssloboda
Copy link
Contributor Author

When setting up a Meson project to be usable as a subproject, you have to specify its include directories. A minmea directory was added so that client code could #include "minmea/minmea.h".

The reason why one would want to #include "minmea/minmea.h" rather than #include "minmea.h" is to avoid potential name conflicts (somewhat similar reasoning to prefixing all the functions with minmea_). While in this case, it is only one header with an uncommon name that needs to be included, not using subdirectories for your includes, to my knowledge, is generally seen as bad practice. Keeping project header files in their own directory is especially important when building and installing libraries. Just imagine how many problems would come up if the headers for every library you installed got dumped, without subdirectories, into /usr/local/include/. Adding the minmea subdirectory helps prevent this sort of include directory pollution and file name conflict. Also, this helps future-proof minmea because if at some point a new header file with a common name needs to be added, e.g., utils.h, doing so will not cause any of the problems described above.

If adding the minmea directory is a no-go, I'd still like to incorporate the build with meson changes (I've got another commit to add for library installation in a different branch) because that will be useful for developers using Meson and is a non-breaking feature addition.

@ssloboda
Copy link
Contributor Author

Also, it's been a while since I've read through the Meson docs, but I don't think it's possible to optionally fake a minmea directory for subproject includes. It's easy to optionally add a prefix when installing as a library to the system.

@cmorganBE
Copy link
Collaborator

@ssloboda any reason you can't place minmea in a subdirectory on your own end to avoid having to move the files within this repository? I can't imagine everyone integrating libraries with meson is looking to move their location in upstream repos.

@mtp401
Copy link

mtp401 commented May 20, 2022

@ssloboda any reason you can't place minmea in a subdirectory on your own end to avoid having to move the files within this repository? I can't imagine everyone integrating libraries with meson is looking to move their location in upstream repos.

This can be closed if the maintainers of minmea are not interested in first class meson support. We'll contribute a wrap to Meson's wrapdb instead.

@eli-schwartz
Copy link

eli-schwartz commented May 20, 2022

The reason why one would want to #include "minmea/minmea.h" rather than #include "minmea.h" is to avoid potential name conflicts (somewhat similar reasoning to prefixing all the functions with minmea_). While in this case, it is only one header with an uncommon name that needs to be included, not using subdirectories for your includes, to my knowledge, is generally seen as bad practice. Keeping project header files in their own directory is especially important when building and installing libraries. Just imagine how many problems would come up if the headers for every library you installed got dumped, without subdirectories, into /usr/local/include/. Adding the minmea subdirectory helps prevent this sort of include directory pollution and file name conflict. Also, this helps future-proof minmea because if at some point a new header file with a common name needs to be added, e.g., utils.h, doing so will not cause any of the problems described above.

Actually, many libraries install headers directly to /usr/local/include/ and expect users to use #include <foolib.h> -- the difference is that these libraries carefully maintain a public header API in a single file with a distinctive name.

Or sometimes they do it in multiple files with distinctive names. <foolib.h> and <foolib_utils.h>.

Many projects also install everything to a subdir #include <foolib/foolib.h>.

A third choice, yes that's right there's three of them, is that the files get installed to /usr/local/include/foolib/ but that gets added as the includedir on the compiler command line, and users still use #include <foolib.h>.

These are valid decisions, but it should in fact be a decision of the project. In general, the subdir approach tends to be taken by projects that expect to have a bunch of header files, and the no-subdir approach tends to be taken by projects that expect to have one or two header files.

Is there a serious concern that this project will grow to include many publicly installed header files? Keep in mind, if there comes to be a utils.h which is used internally for building the library, but isn't needed for third-party projects to build against the library API, then for the purposes of this discussion it's quite irrelevant and doesn't need to be factored in here.

...

Either way, with my Meson core dev hat on...

Meson does not care which approach is taken, it supports and is used for both.

What Meson does care about, is that in order for use via the wrap subprojects system, whatever include name the project expects downstream consumers to use in their source code, i.e. #include <foolib.h> or #include <foolib/foolib.h>, needs to be an on-disk file structure in the repository so that the in-tree version can be passed as a compiler include directory. This is an actual good practice.

Failure to do this means that Meson will still support building and installing the project, but will not support adding the project as a git submodule to another project and building it as a vendored copy as described in https://mesonbuild.com/Wrap-dependency-system-manual.html#provide-section

...

If the project expects people to do #include <minmea.h> then no changes need be made to the file structure here.

This conversation should NOT focus on implementing moving files around the source tree, but rather focus on convincing the project maintainers of the relative merits of different styles of includes, and then work backwards from there to implement the desired approach.

*.exe
build

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary:

  • it may be named anything and a popular convention is builddir/, or builddir-release/ and builddir-debug/, so this gitignore entry likely won't take effect

  • Meson knows at the time of creating builddir/ that it is a build directory, and that no files in there should be added to git, so it creates builddir/.gitignore which ignores *, so that you don't have to. This just magically works.

    Admittedly, this was implemented in December 2020 via mesonbuild/meson@7437d98 and released in Meson 0.57.0, so back when you originally submitted this PR that was not the case, but still... it is long past December 2020, so you can remove this now. :)

)

add_project_arguments(
'-Wall', '-Wextra', '-Werror',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meson will warn you not to do this, and suggest instead that you set default_options to include ['warning_level=2', 'werror=true'].

This will guarantee that it works cross-platform and on any compiler, and it also means that when GCC adds new warnings to -Wextra, which it often does, users can still build the project by passing -Dwerror=false as a manual override.

)

if host_machine.system() == 'windows'
add_project_arguments('DMINMEA_INCLUDE_COMPAT')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is missing a leading -

c_args = []

if get_option('buildtype') == 'debug'
c_args += '-ggdb'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The debug buildtype already sets -g, why do you need to enforce -ggdb (which the Makefile doesn't do anyway)?

minmea_lib = library(
'minmea',
minmea_sources,
include_directories: minmea_includes,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current directory is an implicit include, you still need to use it for declare_dependency, but you don't need it for defining the library. Minus one line.

'minmea',
minmea_sources,
include_directories: minmea_includes,
dependencies: minmea_dependencies,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an empty array, is it just future proofing? The project should confirm whether it's worth the additional lines for something that may have a definite development policy to never utilize.

In fact this seems likely to be the case, the project goals state that it is lightweight/minimal, and mention the bullet point:

  • One source file and one header - can't get any simpler.

So it sounds like they would not be willing to add dependencies in the future, which means you don't need to plan ahead for dependencies.

link_with: minmea_lib,
)

if get_option('example')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not bother with this option, just always define the example to be built. It's a single compile rule with no dependencies, it doesn't add any complexity to building, so there's no cost to always building it.

If you just don't want to run an extraneous build rule when using this as a wrap, set this executable to build_by_default: false.

endif

if get_option('tests')
check = dependency('check')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use a feature option for this these days, you can do check = dependency('check', required: get_option('tests')) and it will be a tristate lookup. If enabled, the dependency is required. If disabled, the dependency is skipped and forced to not-found. If auto, it will try to find the dependency, but allow not finding it.

Then, you can check whether the dependency was found and only when it is found, define the tests.

@chmorgan
Copy link
Collaborator

@eli-schwartz @ssloboda is it ok if only the header file is moved into a minmea/ subdirectory? As the library (.a file) would remain in the parent folder during install but the header would go into the subdir?

Would that let you use the meson build in your repo without pulling it in here? If we pulled it in here we'd have to maintain it etc... and there are a lot of build systems.

@eli-schwartz
Copy link

@chmorgan,

if someone uses minmea in their own project, what would you recommend they use as a header #include?

@cmorganBE
Copy link
Collaborator

@eli-schwartz it would depend where they put the header files. If you put minmea into a 'minmea' folder you could add the containing folder to your search path and #include "minmea/minmea.h", or add minmea to your include path and #include minmea.h".

It feels like I'm misunderstanding the question though.

@eli-schwartz
Copy link

The question is what should be the canonical way, not what is technologically possible. :)

@kosma
Copy link
Owner

kosma commented Aug 5, 2022

The include for minmea is #include <minmea.h>. It's a single-file library by design, so subfolders are not needed, not necessary, and not wanted. This is a design decision.

Copy link
Owner

@kosma kosma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

062714d merged into master as it's not directly related to Meson and it's a good commit.

Copy link
Owner

@kosma kosma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

77e2579 will not be merged as the current file layout is not a problem.

@eli-schwartz
Copy link

Then my comment above still applies, in which I predicted that that would be the case.

Nothing, not even Meson, needs the folder structure of this repository changed.

Changing the folder structure would be a statement that you expect people to use that folder structure via #include <minmea/minmea.h>, and that's massively out of scope for "support building via Meson" because it requires source code and documentation changes to all external users.

@kosma
Copy link
Owner

kosma commented Aug 5, 2022

@eli-schwartz You are an absolute blessing. ❤️

@kosma
Copy link
Owner

kosma commented Aug 5, 2022

Okay. I think I am ready to proceed with this... but I need the following:

  1. Clean, minimal build.meson. If we can have no options, just single build.meson, that would be perfect.
  2. Instructions how to use it - preferably in the form of a shell script, as this will need to be integrated into our CI setup.

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

Successfully merging this pull request may close these issues.

6 participants