Using Meson to Cross-Compile applications for Embedded systems without Operating system

2,361 views
Skip to first unread message

Paweł Wiśniewski

unread,
Nov 19, 2014, 2:58:30 PM11/19/14
to meson...@googlegroups.com
Hi,

I'm searching for build system for my new project.
Application will run on microcontroller without Operating system and will be build with commercial cross-compiler (IAR).
In this project I will have Code and Unit tests. I would like to compile both as native as well as cross-compile (one source, two platforms).

I saw Cross compilation option in Meson, can it be used in this case, or only targets with Gcc-compatible compiler are supported?

Best Regards,
Paweł

Jussi Pakkanen

unread,
Nov 19, 2014, 3:16:40 PM11/19/14
to Paweł Wiśniewski, meson...@googlegroups.com
Meson supports cross-compilation and all compilers we can (we already support MSVC). Just be aware that Meson's cross-compilation bits have not been used as much as native build so there may be surprises. In this particular case you need to do two things.

The first is that you need to write a toolchain file that describes your platform. The simplest way is to look in the cross subdirectory of your Meson checkout, and adapt one of the files there.

The second thing is that you need to write a definition for your compiler inside Meson. This tells it what compiler flags to use. This is inside environment.py and the easiest thing is again to take one of the existing compiler definitions and modify it. Then you need to modify the detect_XXX_compiler methods and have it detect and instantiate your compiler object.

Once this is done, just do:

meson --cross-file your_cross_file.txt sourcedir builddir

Feel free to submit a patch for the compiler definition.

Thanks,

Paweł Wiśniewski

unread,
Dec 22, 2014, 10:12:02 AM12/22/14
to meson...@googlegroups.com, pavel.wi...@gmail.com

Hi,

I have found some time to look further in meson.
I have some questions regarding CCompiler class and meson architecture.

Why do you have get_always_args and get_buildtype_args separately?
theoretically you can use only get_buildtype_args and return self.always_args + buildtype_args[buildtype]

What is the difference between get_debug_args() and get_buildtype_args("debug")? I see there are different flags returned but I don't know context for both methods.

Why did you put all compiler classes into compilers.py? From readability point of view it will be better to have separate file for each compiler and it will be easier to add new compilers.

Best Regards,

Jussi Pakkanen

unread,
Dec 22, 2014, 11:03:49 AM12/22/14
to Paweł Wiśniewski, meson...@googlegroups.com
On Mon, Dec 22, 2014 at 5:12 PM, Paweł Wiśniewski <pavel.wi...@gmail.com> wrote:
 
I have found some time to look further in meson.
I have some questions regarding CCompiler class and meson architecture.

Why do you have get_always_args and get_buildtype_args separately?
theoretically you can use only get_buildtype_args and return self.always_args + buildtype_args[buildtype]

This follows the basic rule of Python: explicit is better than implicit. Combining always flags with buildtype flags would mix to unrelated concepts.
 
What is the difference between get_debug_args() and get_buildtype_args("debug")? I see there are different flags returned but I don't know context for both methods.

These were remnants of the old way Meson used to do it. All get_debug_args methods are now removed in trunk. 
 
Why did you put all compiler classes into compilers.py? From readability point of view it will be better to have separate file for each compiler and it will be easier to add new compilers.

No particular reason but having one file for each compiler would make the number of files grow too large. There are no hard and fast rules here.  

Paweł Wiśniewski

unread,
Jan 5, 2015, 5:31:43 AM1/5/15
to meson...@googlegroups.com, pavel.wi...@gmail.com


W dniu poniedziałek, 22 grudnia 2014 17:03:49 UTC+1 użytkownik Jussi Pakkanen napisał:
On Mon, Dec 22, 2014 at 5:12 PM, Paweł Wiśniewski <pavel.wi...@gmail.com> wrote:
 
I have found some time to look further in meson.
I have some questions regarding CCompiler class and meson architecture.

Why do you have get_always_args and get_buildtype_args separately?
theoretically you can use only get_buildtype_args and return self.always_args + buildtype_args[buildtype]

This follows the basic rule of Python: explicit is better than implicit. Combining always flags with buildtype flags would mix to unrelated concepts.

Thanks for clarification I will keep it in mind.

 
What is the difference between get_debug_args() and get_buildtype_args("debug")? I see there are different flags returned but I don't know context for both methods.

These were remnants of the old way Meson used to do it. All get_debug_args methods are now removed in trunk. 
 
Why did you put all compiler classes into compilers.py? From readability point of view it will be better to have separate file for each compiler and it will be easier to add new compilers.

No particular reason but having one file for each compiler would make the number of files grow too large. There are no hard and fast rules here.  
 
From my experience sometimes it's better to have more files but smaller files.
In case of compilers I think it would be better to have more smaller files that contain only compiler specific code. It will be easier to add new compiler without risk of breaking existing one.
I will try to add my cross-compiler as separate module.

I'm not sure whether separating compiler from linker is a good idea. I think it's not good idea to use gcc as compiler and VS as linker, it should be somehow connected.
Maybe some concept of toolchain that contain compiler and linker definition. Did you considered such a solution?

I'm thinking about moving some things from environment.py to compilers.py. For example part of __init__ that is creating compiler for target platform (default_c, default_cpp, etc).
I think platform information is part of compiler definition not environment. What do you think about it?


Jussi Pakkanen

unread,
Jan 5, 2015, 3:58:07 PM1/5/15
to Paweł Wiśniewski, meson...@googlegroups.com
On Mon, Jan 5, 2015 at 12:31 PM, Paweł Wiśniewski <pavel.wi...@gmail.com> wrote:
 
From my experience sometimes it's better to have more files but smaller files.
In case of compilers I think it would be better to have more smaller files that contain only compiler specific code. It will be easier to add new compiler without risk of breaking existing one.
I will try to add my cross-compiler as separate module.

Please try to do your submissions in small batches. That is, first just add the compiler in the current file and only after that start thinking about how to change the module structure. The former is simple and noncontroversial whereas module refactorings need a lot more work and have a greater chance of being rejected for one reason or another.
 
I'm not sure whether separating compiler from linker is a good idea. I think it's not good idea to use gcc as compiler and VS as linker, it should be somehow connected.
Maybe some concept of toolchain that contain compiler and linker definition. Did you considered such a solution?

This is what Meson already does. If you select gcc, it will always select gcc's linker, for MSVC it will always select Microsoft's linker and so on. The separate classes are just a way of keeping linker information separate from compilers (because that is what they are after all).
 
I'm thinking about moving some things from environment.py to compilers.py. For example part of __init__ that is creating compiler for target platform (default_c, default_cpp, etc).
I think platform information is part of compiler definition not environment. What do you think about it?

I have thought about this but unfortunately it is not as simple. The same compiler can run on a multitude of different platforms, as an example gcc runs on Linux, FreeBSD, OSX, Aix and so on and so on. You need to separate those two and putting all that platform stuff inside the compiler class would probably make it explode.

If you have specific ideas on how to change this (the autodetection bit especially feels a bit wonky) please post your ideas on this list first. There are probably hidden potholes that you might hit if you just start coding.

Thanks for looking into this,

Paweł Wiśniewski

unread,
Jan 6, 2015, 10:55:11 AM1/6/15
to meson...@googlegroups.com, pavel.wi...@gmail.com

On Monday, January 5, 2015 9:58:07 PM UTC+1, Jussi Pakkanen wrote:
On Mon, Jan 5, 2015 at 12:31 PM, Paweł Wiśniewski <pavel.wi...@gmail.com> wrote:
 
From my experience sometimes it's better to have more files but smaller files.
In case of compilers I think it would be better to have more smaller files that contain only compiler specific code. It will be easier to add new compiler without risk of breaking existing one.
I will try to add my cross-compiler as separate module.

Please try to do your submissions in small batches. That is, first just add the compiler in the current file and only after that start thinking about how to change the module structure. The former is simple and noncontroversial whereas module refactorings need a lot more work and have a greater chance of being rejected for one reason or another.

I'm trying to implement it in small steps, first I'm trying to get it working than making in look good.
 
 
I'm not sure whether separating compiler from linker is a good idea. I think it's not good idea to use gcc as compiler and VS as linker, it should be somehow connected.
Maybe some concept of toolchain that contain compiler and linker definition. Did you considered such a solution?

This is what Meson already does. If you select gcc, it will always select gcc's linker, for MSVC it will always select Microsoft's linker and so on. The separate classes are just a way of keeping linker information separate from compilers (because that is what they are after all).

I have seen this, but I was thinking about some abstraction between environment and compiler/linker. At this moment you are making decision based on compiler class type inside environment. When I want to add new compiler and linker I have to add one more If isinstance.
I have some suggestion, read below.
 
I'm thinking about moving some things from environment.py to compilers.py. For example part of __init__ that is creating compiler for target platform (default_c, default_cpp, etc).
I think platform information is part of compiler definition not environment. What do you think about it?

I have thought about this but unfortunately it is not as simple. The same compiler can run on a multitude of different platforms, as an example gcc runs on Linux, FreeBSD, OSX, Aix and so on and so on. You need to separate those two and putting all that platform stuff inside the compiler class would probably make it explode.

If you have specific ideas on how to change this (the autodetection bit especially feels a bit wonky) please post your ideas on this list first. There are probably hidden potholes that you might hit if you just start coding.


I'm thinking about adding toolchain layer between compiler and environment. Environment could ask toolchain whether it can run on current operating system or ask for list with supported operating systems. other thing could be asking for supported cross compile platforms.
I've made some UML with how it could look like, you can find it here: http://goo.gl/hvNgzD
With such implementation compiler will be separated from platform information. Environment only have to ask toolchain whether it can run on host platform or build for target.

What do you think about this idea?

Jussi Pakkanen

unread,
Jan 6, 2015, 6:09:13 PM1/6/15
to Paweł Wiśniewski, meson...@googlegroups.com
On Tue, Jan 6, 2015 at 5:55 PM, Paweł Wiśniewski <pavel.wi...@gmail.com> wrote:
 
I have seen this, but I was thinking about some abstraction between environment and compiler/linker. At this moment you are making decision based on compiler class type inside environment. When I want to add new compiler and linker I have to add one more If isinstance.

Note that the linkers mentioned in the code are static linkers. That is only used to generate static libraries. All other link types (executables, shared libraries) are generated with the compiler binary. Or at least sometimes they are does and sometimes not, which bring us to ...
 
I'm thinking about adding toolchain layer between compiler and environment. Environment could ask toolchain whether it can run on current operating system or ask for list with supported operating systems. other thing could be asking for supported cross compile platforms.
I've made some UML with how it could look like, you can find it here: http://goo.gl/hvNgzD

... here where your diagram is very much hardcoded to C and C++. The problem is that Meson needs to support a whole lot of other languages, some of which have a completely different way of working. I thought about this problem and have not been able to come up with a single class interface that could cover all of those and at the same time not be vague enough to be meaningless.

It is unfortunate that the current code is an amalgamation of different kinds of bits. But it follows directly from the problem it is trying to solve. It just isn't clean, composable or nicely unifiable behind a single interface. I'm not saying it can't be done but it will be hard. Hard problems usually beget complex solutions, and anything more complex than the current solution will not be considered (the current approach is in fact a bit too complex already for my taste but I can live with it).
Reply all
Reply to author
Forward
0 new messages