mesonbuild / meson

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

How to compile AIDL files using meson? #2539

Open rom1v opened 6 years ago

rom1v commented 6 years ago

Here are 2 aidl files.

src/com/rom1v/example/Service.aidl:

package com.rom1v.example;
interface Service {
    void doSomething();
}

src/another/package/Other.aidl:

package another.package;
interface Other {
    int get();
}

I would like to compile them using meson (and compile these generated java files along with my sources), so I started a build.meson:

project('example', 'java')

aidl = [
    'src/com/rom1v/example/Service.aidl',
    'src/another/package/Other.aidl',
]

From these sources, I want to generate:

To generate them manually, I use these commands:

aidl -ogen src/com/rom1v/example/Service.aidl
aidl -ogen src/another/package/Other.aidl

How to do the same using Meson?

I guess generator is what I want, but I can't figure out what output value to use (it does not accept pathes, and only supports @PLAINNAME@ and @BASENAME@ as substitutions).

aidl_compiler = find_program('aidl')
gen = generator(aidl_compiler, output: ???, arguments: ['-ogen', '@INPUT@'])

ref: https://stackoverflow.com/questions/46729488/how-to-compile-aidl-files-using-meson

It seems to me that Meson assumes that all outputs may be generated in a flat directory, assumption that is false in the Java world.

NickeZ commented 6 years ago

I think you have to use either configure_file or custom_target. But using both of these means that you will have to repeat yourself a lot in the build file.. I think this is a missing feature of meson currently. I also have projects where I have to produce custom targets from pretty obscure source types and I haven't found out a clean way to do it. Especially when you have extra dependencies on your targets..

Using the generator would have been a nice abstraction if it actually was meant to be used like this.

rom1v commented 6 years ago

I think you have to use either configure_file or custom_target.

I think that even in configure_file or custom_target, it is not possible to specify an output file which is in a subdirectory, is it?

NickeZ commented 6 years ago

Put the meson files in the same directory as the aidl files and use subdir.

rom1v commented 6 years ago

@NickeZ I can't get it work (and my meson skills are limited). Could you create a working sample to show how it is possible to build a java program that includes the files generated from AIDL, please?

NickeZ commented 6 years ago

Below is a simple example. The meson.build files in the subdirectories are the same. See configure_file for more details on how to generate files from input files instead of capturing the stdout.

niklas @ niklas-tp : /tmp/testprj
$ tree .
.
├── build
│   ├── build.ninja
│   ├── compile_commands.json
│   ├── meson-logs
│   │   └── meson-log.txt
│   ├── meson-private
│   │   ├── build.dat
│   │   ├── coredata.dat
│   │   ├── install.dat
│   │   ├── meson_benchmark_setup.dat
│   │   └── meson_test_setup.dat
│   └── src
│       ├── another
│       │   └── package
│       │       └── file1
│       └── com
│           └── package1
│               └── file1
├── meson.build
└── src
    ├── another
    │   └── package
    │       └── meson.build
    └── com
        └── package1
            └── meson.build
13 directories, 13 files
niklas @ niklas-tp : /tmp/testprj
$ cat meson.build
project('test')
subdir('src/com/package1')
subdir('src/another/package')
niklas @ niklas-tp : /tmp/testprj
$ cat src/com/package1/meson.build
configure_file(capture:true, command: ['echo', 'test'], output: 'file1')
rom1v commented 6 years ago

Thank you for the skeleton. I still have many thing to figure out to make it build.

But I think there is a flaw in using configure_file (which seems to be a workaround here for compiling AIDL, this is not its purpose): it's executed on "configure" (when we execute meson mybuilddir), while AIDL should be generated – and regenerated – on build only (on ninja).

What do you think?

NickeZ commented 6 years ago

Then custom_target is probably better. You use it in a similar way but the files will be created at build time.

rom1v commented 6 years ago

If I create src/com/rom1v/example/meson.build with this content:

custom_target('sample', input: 'Service.aidl', command: [find_program('aidl'), '-o@OUTDIR@', '@INPUT@'], output: 'Service.java')

Then it generates mybuilddir/src/com/rom1v/example/com/rom1v/example/Service.java.

The problem is that aidl generates the file according to the Java package, that meson is not aware of.

So I moved the file to src/meson.build:

custom_target('sample', input: 'com/rom1v/example/Service.aidl', command: [find_program('aidl'), '-o@OUTDIR@', '@INPUT@'], output: 'Service.java')

Here, it generates in mybuilddir/src/com/rom1v/example/Service.java, but meson is not aware of the fullpath, it thinks that the output is mybuilddir/src/Service.java, so it won't correctly manage the dependencies. Cf the relevant lines in the generated build.ninja:

build src/Service.java: CUSTOM_COMMAND ../src/com/rom1v/example/Service.aidl
 COMMAND = '/home/rom/android/sdk/build-tools/26.0.2/aidl' '-osrc' '../src/com/rom1v/example/Service.aidl'

My last attempt was to set the full path of the output:

custom_target('sample', input: 'com/rom1v/example/Service.aidl', command: [find_program('aidl'), '-o@OUTDIR@', '@INPUT@'], output: 'com/rom1v/example/Service.java')

But unfortunately:

Output must not contain a path segment.

So I think meson currently cannot handle this simple case.

IMO, it would require support of hierarchy for outputs.

NickeZ commented 6 years ago

What if you don't set @OUTDIR@ in the first example? Set -o to dot (.) Instead maybe?

rom1v commented 6 years ago

No, that will only change the directory into which the hierarchy associated to the package will be created.

NickeZ commented 6 years ago

Alright, I agree what you need probaly can't be done today. For completeness I link to the other related issue as well: #2320

jasonszang commented 6 years ago

This is quite like my protobuf problem in #2320. Protubuf also has its own way of handling directory structures and meson's way of placing meson.build in sub directories and subdir also won't help. We are on exactly the same boat. I think these problems can only be solved by removing meson's assumption of flat generated source directory.