Git Product home page Git Product logo

Comments (13)

krasin avatar krasin commented on May 27, 2024

I had been looking into the Makefile through the week. I find it surprisingly complicated for the small project. My understanding is that it's due to the following features:

  1. Out of tree build. Makefiles don't really support that, all implicit rules had to be rewritten.
  2. Recursive Makefiles, passing state between them (TinyG2/Makefile, TinyG2/platform/{atmel_sam.mk,atmel_sam/atmel_sam_series.mk,make_utilities.mk})
  3. Configurability for a specific board/platform without ./configure script.

While it's theoretically possible to fix the existing Makefile (right now, I suspect incorrectly propagates C_SOURCES from atmel_sam Makefile), it will likely continue to be a very brittle and complex thing, that will cause an ongoing maintenance efforts.

Generally, there's two options, which feel right:

  • Implement configure.ac, use autoconf to generate ./configure, which will generate Makefile for the specific board/platform. I will refer to this as the Autotools way
  • Write CMakeFiles and generate Makefiles, XCode projects, Visual studio projects, etc from them.

The Autotools way will address #2 and #3. Building out of tree will still be a pain. The CMake way will address all three. Also, it will reduce the amount of code that has to be manually updates, such as XCode project.

The disadvantage of CMake approach is the additional prerequisite, which will likely require some dance on Windows. Alternatively, we could generate a Makefile for Atmel studio ahead of time and check into the repo.

On the bright side, the CMakefiles.txt will be short (< 200 LOC).

Any thoughts? If there's no strong objections, I can write CMakefiles.txt and we'll explore this approach with more specifics.

from g2.

giseburt avatar giseburt commented on May 27, 2024

Hi Ivan,

I'm somewhat divided here. I agree that the makefile is very complex, and
can be simplified somewhat. It is doing a lot, herever. I'll come back to
that.

I personally despise it when autoconf is used when it's unnecessary, and
for any bare metal project like this it is certainly unnecessary.

I'm not familiar with CMake enough to have a strong opinion, but as far as
maintaining the Xcode and AS projects go, they're really just window
dressing for the makefile. (They are both doing bonus stuff, like XCode has
the "index" pseudo target that runs clang static analysis on the code as
you type.) I think CMake is probably overkill as well.

About the makefile: I am currently restructuring Motate (over in the Motate
repo, I'll post a link after I push). That includes rewriting the makefiles
somewhat.

The makefile now supports building for multiple memory deployment types
(in-RAM or in flash), and it supports building for multiple architectures
at the same time. The memory deployment types part is unnecessary since we
won't be using the ram deployment on these small chips and the simultaneous
multiple architectures isn't being used either. Those will be removed
shortly.

Other than for Tools, there are no recursive calls to make — it's all
handled in the same invocation.

The file structure is currently (not counting the .../Tools/):

Makefile (in the project build root)
platform/make_utilities.mk (contains routines to simplify adding a platform
to the build)
platform/${platform}.mk
platform/${platform}/ (any included make files from the platform.mk live
here)

There is also platform/per-board code and possibly linker scripts that live
in that last one as well.

The CREATE_DEVICE_LIBRARY routine will currently do as it says and make an
archive of all device/platform objects and add that as a single object in
the final linking stage. I suspect that that is what's messing up the -jX,
since it's not waiting for that to complete before linking. It is
also unnecessary, since it could just add the resulting object files to the
main object list and be done.

I will be restructuring Motate and it's makefiles to belts modular and thus
more maintainable. The layout will be like this (ignore the caps):

Project_root/
Makefile
Motate/
Motate.mk
Motate_Make_Utilities.mk
Platform/
Platforms.mk
$(platform).mk
$(platform)/
Support.mk
Cmsis/
$(Vendor)/
Board/
$(board).mk
$(board)/

In this structure, most files will only have a few lines, with 90% of the
makefile code being inside the Motate/ hierarchy.

In the main Makefile you would simply have project-specific setup, along
with setting up a list of supported board files, then it would include
Motate.mk. Ideally this main makefile would be <20 lines long, not counting
comments, license, etc.

Motate.mk would setup the build to include the necessary board file (based
on command line options or a default), and whatever platform files are
necessary based on the platform set by the board file. This is also where
the tools would be verified and fetched (using the external Tools
makefile) if necessary, based on the tool chain set in the platform file.

The platform files would ideally be ~10-20 lines long, and that would be
all adding defines and setup of include and source paths.

The board mk files would configure the platform settings and add any
compile options that are board specific (like defines.) (Ideally these
would be between 1 and 5 lines long.)

There's a lot going on here, but the point is reusablilty, maintainability,
and project independence.

Btw, this is all planning, and I welcome and and all feedback. For example,
I'm mulling on changing "platform" to "architecture". Thoughts?

-Rob

On Saturday, June 21, 2014, Ivan Krasin [email protected] wrote:

I had been looking into the Makefile through the week. I find it
surprisingly complicated for the small project. My understanding is that
it's due to the following features:

  1. Out of tree build. Makefiles don't really support that, all
    implicit rules had to be rewritten.
  2. Recursive Makefiles, passing state between them (g2, motate, cmsis)
  3. Configurability for a specific board/platform without ./configure
    script.

While it's theoretically possible to fix the existing Makefile (right now,
I suspect incorrectly propagates C_SOURCES from CMSIS Makefile), it will
likely continue to be a very brittle and complex thing, that will cause an
ongoing maintenance efforts.

Generally, there's two options, which feel right:

  • Implement configure.ac, use autoconf to generate ./configure, which
    will generate Makefile for the specific board/platform. I will refer to
    this as the Autotools way
  • Write CMakeFiles and generate Makefiles, XCode projects, Visual
    studio projects, etc from them.

The Autotools way will address #2
#2 and #3
#3. Building out of tree will
still be a pain. The CMake way will address all three. Also, it will reduce
the amount of code that has to be manually updates, such as XCode project.

The disadvantage of CMake approach is the additional prerequisite, which
will likely require some dance on Windows. Alternatively, we could generate
a Makefile for Atmel studio ahead of time and check into the repo.

On the bright side, the CMakefiles.txt will be short (< 200 LOC).

Any thoughts? If there's no strong objections, I can write CMakefiles.txt
and we'll explore this approach with more specifics.


Reply to this email directly or view it on GitHub
#14 (comment).

from g2.

krasin avatar krasin commented on May 27, 2024

Hi Rob,

I would recommend to use the Chromium OS terms for arch/board/platform.
http://www.chromium.org/chromium-os/how-tos-and-troubleshooting/chromiumos-board-porting-guide

  • Architecture is something like AVR/ARM/x86
  • Platform would be Atmel SAM3, or may be something like NXP LPC1700.
  • Board is gShield, v9_3x8c, v8, etc.

Architecture defines a compiler, Platform defines low-level stuff, like setting up timers or configuring pins, and Board adds details about the actual pin assignment.

Certainly, Board implies Platform and Architecture, Platform implies Architecture, so there's only one top-level configuration switch is required: Board.

from g2.

krasin avatar krasin commented on May 27, 2024

About autotools. I agree that they are often (actually, almost always) an overkill, because they add too much overhead. Almost no new projects use them.

from g2.

krasin avatar krasin commented on May 27, 2024

CMake: ultra-simple thing. I would go ahead and write a prototype CMakeLists.txt for G2, integrate it with Travis and will send all related links.

After that, you will have more information about the proposed solution, and it would be easier to discuss benefits and drawbacks Makefile vs CMake.

from g2.

krasin avatar krasin commented on May 27, 2024

Hi Rob,

I have the first version of CMakeLists.txt working. gShield.bin can be built, flashed and it boots on the device.

Here is it: https://github.com/krasin/g2/blob/cmake/TinyG2/CMakeLists.txt

And Travis: https://travis-ci.org/krasin/g2/builds/28202822

It still has a few minor omissions (like, I have not yet tested G2v9g build, may be some flags are missing), and I didn't implement flash/memory thing (as you said, it's about to be retired), but it works. It's a single file with 164 lines of code and it supports:

  • Out of tree build
  • Parallel build
  • Configuration for different platforms (gShield, G2v9g)
  • Toolchain download (right now, Linux only, can easily add other oses)
  • Colors
  • It's possible to generate XCode project, Visual studio project, regular makefile, ninja build, etc.

I can make it a bit cleaner by separating the target into motate, atmel_sam and core, but it's all minor.

Does CMakeLists.txt look better than an average configure.ac? Is it simpler than the current Makefile? Should I continue to work in this direction? Note: I don't expect a final "yes"; but if you have a final "no", it would save me some time.

from g2.

krasin avatar krasin commented on May 27, 2024

To demonstrate the point, I have started to address minor issues:

  • Toolchain setup script now lives under ./Tools/ARMToolchain.cmake (52 LOC). It's directly comparable to ./Tools/Makefile (53 LOC), but CMake also implements MD5 sum checking. It means that the chance to download a corrupted toolchain is much smaller.
  • Toolchain script supports all target operating systems: Linux, MacOS, Windows.

https://github.com/krasin/g2/blob/cmake/TinyG2/CMakeLists.txt
https://github.com/krasin/g2/blob/cmake/Tools/ARMToolchain.cmake
https://travis-ci.org/krasin/g2/builds/28295325

from g2.

krasin avatar krasin commented on May 27, 2024

Fixing more small issues: CMake downloads toolchain to the same directory; I have added G2v9g build to Travis CI:

https://travis-ci.org/krasin/g2/builds/28381873

Now, Travis can check the compilation both gShield and G2v9g on each commit.

I will focus on the simulator demo. It should be relatively straightforward to add changes to the same CMakeLists.txt. In TinyG repo, I had to create a separate Makefile for that (not that it was impossible to update the primary Makefile, but a lot of dirt was expected if doing so).

from g2.

krasin avatar krasin commented on May 27, 2024

This thread is getting irrelevant to the title, but anyway.

Today, I have investigated why qemu semihosting works with Sourcery GNU toolchain, but does not work with the toolchain used by G2. Basically, two things:

  • a proper linker script (easily importable to the G2 repo)
  • newlib built with semihosting support (not easily detachable)

So, I have defined the new PLATFORM=qemu, and download a different toolchain for it (I have no idea, if we can use the Sourcery toolchain for everything).

Right now, the process of getting G2 started inside QEMU is not complete, but I should have something like this small demo "soon":

https://github.com/krasin/qemu-counter-hello
https://travis-ci.org/krasin/qemu-counter-hello

Sorry for the half-assed update. I need to sleep.

from g2.

giseburt avatar giseburt commented on May 27, 2024

I still haven't had the ability to look into the CMakefiles. I feel bad
about that.

The gcc build we are using does support semihosting, but our code doesn't
necessarily right now. Look at
https://launchpadlibrarian.net/177524521/readme.txt — --specs=rdimon.specs.
Should turn it on.

What do you mean by a "proper" linker script? We are using one, and I'm
switching to the "stock" ones from the vendors' cmsis soon. See in the
Motate repo: https://github.com/giseburt/motate (specifically, the linker
script that'll get called for the Due:
https://github.com/giseburt/Motate/blob/master/MotateProject/motate/cmsis/TARGET_Atmel/sam3xa/source/as_gcc/sam3x8e_flash.ld)
Would that do?

Thank you,
-Rob

On Thursday, June 26, 2014, Ivan Krasin [email protected] wrote:

This thread is getting irrelevant to the header, but anyway.

Today, I have investigated why qemu semihosting works with Sourcery GNU
toolchain, but does not work with the toolchain used by G2. Basically, two
things:

  • a proper linker script (easily importable to the G2 repo)
  • newlib built with semihosting support (not easily detachable)

So, I have defined the new PLATFORM=qemu, and download a different
toolchain for it (I have no idea, if we can use the Sourcery toolchain for
everything).

Right now, the process of getting G2 started inside QEMU is not complete,
but I should have something like this small demo "soon":

https://github.com/krasin/qemu-counter-hello
https://travis-ci.org/krasin/qemu-counter-hello

Sorry for the half-assed update. I need to sleep.


Reply to this email directly or view it on GitHub
#14 (comment).

from g2.

krasin avatar krasin commented on May 27, 2024

Hi Rob,

thanks for the link to the readme! I will try rdimon.specs tonight.

re: "proper linker scripts". I meant that for semihosting, a linker script should be different from the one we use to flash a real device. I didn't mean that there's any issues with the current linker script. Sorry for being unclear!

from g2.

krasin avatar krasin commented on May 27, 2024

Thanks, Rob.

A simple example is rebased to the toolchain from launchpad. I hope to have something interesting by the end of the weekend.

from g2.

krasin avatar krasin commented on May 27, 2024

A non-update: I am basically stuck. The approach I used for TinyG "simulator" didn't work for G2. The code base is more complex, and there's much more nits to fix. It would be too long to fix them properly, and the alternative to put lots of hacks (and significantly reduce the quality of simulation) does not appeal to me.

I will try to explore the hard way: emulate the chip with enough peripherals on the qemu side. I am not sure about a success...

from g2.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.