mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.59k stars 1.63k forks source link

It's not obvious or documented that you can't "add" include directories #7487

Open detly opened 4 years ago

detly commented 4 years ago

Using Meson 0.55.0 under a Python 3.7.3 virtualenv on Ubuntu 20.04.

This style of meson.build works:

ui_includes = include_directories(...)
proto_includes = include_directories(...)
other_includes = include_directories(...)

all_includes = []
all_includes += ui_includes
all_includes += proto_includes
all_includes += other_includes

executable(
    'program',
    sources : ui_sources + proto_sources + other_sources,
    include_directories : all_includes,
)

This doesn't work:

ui_includes = include_directories(...)
proto_includes = include_directories(...)
other_includes = include_directories(...)

executable(
    'program',
    sources : ui_sources + proto_sources + other_sources,
    include_directories : ui_includes + proto_includes + other_includes,
)

It fails with ERROR: Invalid use of addition: unsupported operand type(s) for +: 'IncludeDirsHolder' and 'IncludeDirsHolder'.

(Real, runnable examples follow below.)

This is made more confusing by the facts that:

I had to Google a variety of terms ("meson includedirsholder" ... "concatenation"? "add"? "direct sum" aha!) before I came across a post providing the solution above.

Expected behaviour: if += with the type on an empty list works, I'd expect + to work between two objects of the same type.

Real example, working:

project('tmp', 'c')

ui_includes = include_directories()
proto_includes = include_directories()
other_includes = include_directories()

all_includes = []
all_includes += ui_includes
all_includes += proto_includes
all_includes += other_includes

executable(
    'program',
    sources : [],
    include_directories : all_includes,
)

Real example, not working:

project('tmp', 'c')

ui_includes = include_directories()
proto_includes = include_directories()
other_includes = include_directories()

executable(
    'program',
    sources : [],
    include_directories : ui_includes + proto_includes + other_includes,
)
p01arst0rm commented 4 years ago

this is just a weird way that the arrays work in meson. The following should work just fine for you.

project('tmp', 'c')

project_includes = [include_directories(...)]
ui_includes = [include_directories(...)]
proto_includes = [include_directories(...)]
other_includes = [include_directories(...)]

project_includes += ui_includes
project_includes += proto_includes
project_includes += other_includes

executable(
    'tmp',
    sources : [],
    include_directories : project_includes)
p01arst0rm commented 4 years ago

heres a working version of the second example too:

project('tmp', 'c')

ui_includes = include_directories(...)
proto_includes = include_directories(...)
other_includes = include_directories(...)

executable(
    'program',
    sources : [],
    include_directories : [
        ui_includes,
        proto_includes, 
        other_includes])
detly commented 4 years ago

this is just a weird way that the arrays work in meson.

Sure, but if it's not worth changing then it should probably be documented, because it's not easy to discover how you're supposed to do this. Specifically:

  1. a + b + c
  2. [a] + [b] + [c]
  3. [a, b, c]

All three of these work for the returned result from files() and dependency()/find_library() but only 2 and 3 work for include_directories(). Only 1 is shown in the docs (I think).