-
Notifications
You must be signed in to change notification settings - Fork 43
Support for the meson build system #142
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
base: master
Are you sure you want to change the base?
Conversation
This pr does not contain building documentation, which will be included in a future pr. My reasoning for this is that I updated the documentation to build using the new gi-docgen instead of gtk-doc. This pr uses a 1.0 version of meson. I don't think I use anything later than 0.7 but I don't know what versions different systems ship with. coverage works but reports false atm since I don't know if there is a portable way to check for coverage packages / support. profiling support isn't included in this pr. |
meson.build
Outdated
|
||
add_global_arguments('-DHAVE_CONFIG_H=1', language : 'c') | ||
|
||
iconv = dependency('iconv', required : false, method: get_option('iconv')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a particular reason you need to expose an option for the method used? Usually people add options to select whether to enable the functionality at all...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, marking it as required: false
seems wrong. The configure.ac considers it mandatory, and the source code unconditionally tries to use it. All you're doing here is adding it to the list of deps -- you don't check whether it's available and set different preprocessor defines to e.g. avoid using it if it doesn't exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, required: false is wrong. It was something left over. Removed it.
The reason for the get_option is to be able to specify what version of iconv to use if you have multiple installed. This is something configure.ac included. Maybe it's considered bad practice or there is a better way to do it in now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea what the original intention was, but the general rule of thumb is that you can either get the standalone gnu one (always an external library) or rely on the platform one (which may be a builtin or an external library, and for glibc it's also the same underlying codebase as the gnu one).
Which one you use isn't much of an option, though, because they both require the same iconv.h
header and if you have both available then the gnu one overrides the header search path. It also overrides the symbol names, so if you don't perform a link verification test using the header (the dependency() provided by meson does this for you) you may end up compiling against the default header which is the gnu one, but linking to an incompatible BSD or musl one that is built into your libc.
The only choice you have really is to either:
- use the one picked up by auto
- return an error or simply disable iconv support if you didn't get the one you wanted
- modify CFLAGS and LDFLAGS before running meson, to prioritize a custom copy in the location you prefer
You're effectively offering an opt-in for option 2 (return a fatal error). But I traditionally wonder: does it actually matter which iconv you find?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea what the original intention was, but the general rule of thumb is that you can either get the standalone gnu one (always an external library) or rely on the platform one (which may be a builtin or an external library, and for glibc it's also the same underlying codebase as the gnu one).
This was the original intention, yes.
meson.build
Outdated
if cc.has_header('getopt.h') | ||
if cc.has_function('getopt_long') | ||
conf_data.set('HAVE_GETOPT_H', 1) | ||
endif | ||
endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why check both has_header and has_function? You could do both at the same time by checking either:
cc.has_function('getopt_long', prefix: '#include <getopt.h>')
or, to do a compile test but not a link test,
cc.has_header_symbol('getopt.h', 'getopt_long')
This saves on one fork+exec to the compiler, saving a bit of time and making the configure stage a bit more responsive, and is also more accurate as a side bonus.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. Fixed
meson.build
Outdated
if get_option('have_iconv_detect_h') | ||
conf_data.set('HAVE_ICONV_DETECT_H', 1) | ||
else | ||
# not cross-compiler secure | ||
root = include_directories('.') | ||
has_detect = cc.run(iconv_detect, name: 'iconv-detect', | ||
include_directories: root).returncode() == 0 | ||
if has_detect | ||
conf_data.set('HAVE_ICONV_DETECT_H', 1) | ||
endif | ||
endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meson can absolutely handle this with cross compilation, you just have to define an exe_wrapper (usually qemu-user). If you don't, meson errors out with "Can not run test applications in this cross environment." which... I suppose could be enhanced to mention exe_wrapper, hmm.
But this is a pretty awkward way to do things here. You're running a test program in the source directory and emitting unclean output into the source directory instead of the build directory -- this violates Meson's guarantee of out-of-source build directories, potentially messing up situations such as read-only mounted source directories or having multiple build directories, one native one cross compiled, which need different generated headers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. Adding an error if we can't run.
In the long run I think it might be better to not pollute the system. The reason for me to "port the awkwardness" over is to not disrupt the autotools build which can require this file to exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As someone who cross-compiles daily, remember to include a fallback for cross and can't run by checking for a property in the cross file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be fair, this code only runs in the else branch of a get_option()
...
meson.build
Outdated
foreach hd : [ | ||
{ 'm': 'HAVE_DLFCN_H', 'v': 'dlfcn.h', }, | ||
{ 'm': 'HAVE_INTTYPES_H', 'v': 'inttypes.h', }, | ||
{ 'm': 'HAVE_NETDB_H', 'v': 'netdb.h', }, | ||
{ 'm': 'HAVE_STDINT_H', 'v': 'stdint.h', }, | ||
{ 'm': 'HAVE_WINDOWS_H', 'v': 'windows.h'}, | ||
{ 'm': 'HAVE_SYS_MMAN_H', 'v': 'sys/mman.h', }, | ||
{ 'm': 'HAVE_SYS_PARAM_H', 'v': 'sys/param.h', }, | ||
] | ||
if cc.has_header(hd['v']) | ||
conf_data.set10(hd['m'], true) | ||
endif | ||
endforeach |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be a flat list of headers. e.g. if you use Meson's tools/ac_converter.h
, it suggests the following:
cc = meson.get_compiler('c')
cdata = configuration_data()
check_headers = [
'dlfcn.h',
'getopt.h',
'iconv/detect.h',
'inttypes.h',
'netdb.h',
'poll.h',
'stdint.h',
'stdio.h',
'stdlib.h',
'strings.h',
'string.h',
'sys/mman.h',
'sys/param.h',
'sys/stat.h',
'sys/types.h',
'time.h',
'unistd.h',
'winsock2.h',
]
foreach h : check_headers
if cc.has_header(h)
cdata.set('HAVE_' + h.underscorify().to_upper(), 1)
endif
endforeach
check_functions = [
['HAVE_FSYNC', 'fsync', '#include<unistd.h>'],
['HAVE_GETADDRINFO', 'getaddrinfo', '#include<netdb.h>'],
# check token ['HAVE_GETDOMAINNAME']
# check token ['HAVE_GETHOSTNAME']
['HAVE_GETPAGESIZE', 'getpagesize', '#include<unistd.h>'],
['HAVE_MMAP', 'mmap', '#include<sys/mman.h>'],
# check token ['HAVE_MSYNC']
# check token ['HAVE_MUNMAP']
['HAVE_POLL', 'poll', '#include<poll.h>'],
['HAVE_SELECT', 'select', '#include<sys/select.h>'],
# check token ['HAVE_UTSNAME_DOMAINNAME']
]
foreach f : check_functions
if cc.has_function(f.get(1), prefix : f.get(2))
cdata.set(f.get(0), 1)
endif
endforeach
cdata.set('SIZEOF_OFF_T', cc.sizeof('off t'))
cdata.set('SIZEOF_SIZE_T', cc.sizeof('size_t'))
cdata.set('SIZEOF_SSIZE_T', cc.sizeof('ssize_t'))
cdata.set('SIZEOF_TIME_T', cc.sizeof('time t'))
configure_file(input : 'config.h.meson',
output : 'config.h',
configuration : cdata)
Note the use of:
cdata.set('HAVE_' + h.underscorify().to_upper(), 1)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, never heard of that tool. Fixed
requires: LIBS, | ||
# libraries_private: EXTRA_LIBS, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LIBS is a list of strings. Consider using the returned dependency()
objects as those automatically do "the right thing" (including enforce the same version constraints you used when looking up the dependency to begin with).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
gmime/meson.build
Outdated
gen_table = executable('gen-table', 'gen-table.c') | ||
charset_map = executable('charset-map', 'charset-map.c', dependencies : deps, | ||
include_directories: inc_conf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since cross compilation came up... you can mark an executable as native: true
to make it be compiled with the build machine compiler instead of the cross-compiler, although if you need an exe_wrapper anyway that might not matter so much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
meson.build
Outdated
] | ||
|
||
gmime_prefix = get_option('prefix') | ||
gmime_datadir = join_paths(gmime_prefix, get_option('datadir')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't appear to ever be used, nor can I find anything in the source code or autotools that it would correspond to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah. Those are used for the docs, which are not included in this PR. Removing.
First, sorry for taking so long to get around to this, I'm just so busy these days and have multiple projects that I maintain in my limited free time. I also have no knowledge of the meson build system or what GNOME is doing these days. That said, I just had the most awful experience trying to build gmime on macOS (the closest thing I have to a suitable for gmime development environment) which is what made me think of this PR that I'd been meaning to get around to. I just installed meson from How do I test this? |
tl;dr # replaces ./configure
meson setup builddir/
# replaces /configure --enable-foo
meson setup builddir/ -Dfoo=enabled
# replaces ./configure --help
meson configure
# replaces make
ninja |
|
Looks like the meson setup logic assumes gmime-version.h exists from the onset, but it is/was autogenerated by the old Presumably meson needs to auto-generate it as well. |
Hmmm, looks like it should be doing that...
|
Okay, I'm guessing that it's because libgmime_headers contains gmime-version.h I wonder if maybe inc_conf needs to include the meson build directory so that gmime-version.h can be picked up from there? |
This add support for the meson build system which supports multiple operating systems among things out of the box. This requires jstedfast#141 to be merged, because gnome.generate_gir() treats warnings as errors.
This allows meson setup to work (because it auto-generates gmime-version.h, meaning it doesn't exist when meson is setting up the build).
Rebased this on top of the latest gmime to fix the gir errors that I was getting when trying to |
Logs:
|
Okay, fixed that. TODO:
|
Releases can be done with |
This add support for the meson build system which supports multiple operating systems among things out of the box. This requires #141 to be merged, because gnome.generate_gir() treats warnings as errors.