Skip to content

Cygwin: Enable build of SITL jMAVsim and ARM NuttX under Windows#8407

Merged
dagar merged 6 commits intomasterfrom
cygwin
Jan 5, 2018
Merged

Cygwin: Enable build of SITL jMAVsim and ARM NuttX under Windows#8407
dagar merged 6 commits intomasterfrom
cygwin

Conversation

@MaEtUgR
Copy link
Copy Markdown
Member

@MaEtUgR MaEtUgR commented Dec 4, 2017

Most of the incompatitbilities are luckily similar to the darwin build.

  • New target OS __PX4_CYGWIN added because in other build environments on Windows defines will very likely be completely different
  • added all necessary exeptions to the defines
  • disabled priorities completely because on Windows they are defined as values 1-32 and with all the arbitrary +40 -40 priority settings for the modules there were a lot of problems
    not only did some threads/"virtual tasks" not start because of out of bound priorities but also the resulting scheduling was totally random and inadequate
    with default priorities it ran toally fine during my first tests, should be rethought when windows is used onboard in the future

What I'm really wondering is what the define __CUSTOM_FILE_IO__ is for... I couldn't find any documentation. Any explanation appreciated.

Here is an archive of the portable toolchain setup I tested with: https://drive.google.com/file/d/1y0SvGT6kPxJaB0T-qY2m0ONeR5ppzLGv/view?usp=sharing
If anyone wants to have a try just:

  • unzip
  • open the console (click script in the root folder)
cd Firmware
make posix jmavsim

I will:

  • add more documentation in the dev guide as soon as it's merged (including how to build the entire toolchain manually)
  • appreciate any hosting platform/system for the one click toolchain
  • maybe create a small PX4 binary package without toolchain for demonstration purposes
  • try to enable ARM build as well EDIT: done
  • (look into what is possible for Windows CI)

bkueng
bkueng previously approved these changes Dec 4, 2017
Copy link
Copy Markdown
Member

@bkueng bkueng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I'm really wondering is what the define CUSTOM_FILE_IO is for... I couldn't find any documentation

Seems to be used to customize file IO in libc: https://chromium.googlesource.com/native_client/nacl-newlib/+/a9ae3c60b36dea3d8a10e18b1b6db952d21268c2/newlib/libc/include/sys/reent.h#228. But I don't know why we have it in our build.

Comment thread cmake/posix/px4_impl_posix.cmake Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need this and if so why?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Itz is needed because:

/* Non posix calls */

#if __GNU_VISIBLE
int pthread_getattr_np (pthread_t, pthread_attr_t *);
int pthread_getname_np (pthread_t, char *, size_t) __attribute__((__nonnull__(2)));
int pthread_setname_np (pthread_t, const char *) __attribute__((__nonnull__(2)));
int pthread_sigqueue (pthread_t *, int, const union sigval);
int pthread_yield (void);
#endif
#if __MISC_VISIBLE /* HP-UX, others? */
int pthread_suspend (pthread_t);
int pthread_continue (pthread_t);
#endif

If you have any better solution please feel free to correct. Honestly I don't understand all the interna about these libraries and in my opinion it's so hard to find any documentation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting and thanks for looking it up. I'm wondering why we don't need to define it then (or do I see that wrong)?
In any case I would try to reduce the scope to only the files where pthread_{g,s}etname_np is used. The define can lead to subtle changes in behavior.
Something like:

#define _GNU_SOURCE // for pthread_getname_np
#include <pthread.h>
#undef _GNU_SOURCE

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that _GNU_SOURCE is actually defined in our build, probably because we add -std=gnu++11.
So you can ignore my comment and it's ok to add the define globally (would be good to make this more explicit though for the other builds).

Copy link
Copy Markdown
Member Author

@MaEtUgR MaEtUgR Dec 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking stuff up.

I see that _GNU_SOURCE is actually defined in our build

Why do I have to redefine it then? Is it dependent on the compiler? Does -std=gnu++11 just not get handeled in cygwin? That would explain it. In any case I don't see a risk for this define.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: it's implemented on NuttX too.

Copy link
Copy Markdown
Member Author

@MaEtUgR MaEtUgR Dec 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, obviously you're right. I was thinking in the posix box but the message might be misleading.
EDIT: I corrected

@dagar
Copy link
Copy Markdown
Member

dagar commented Dec 4, 2017

Looking good. You effectively have 2 options for CI.
Appveyor - https://www.appveyor.com/docs/build-environment/
Jenkins + AWS EC2 - Custom windows build slave on Jenkins

For NuttX have you considered using the Windows version of the GCC ARM Embedded Toolchain natively? You could even use Visual Studio (project generated by cmake).

@hamishwillee
Copy link
Copy Markdown
Contributor

@MaEtUgR I tried this - pretty cool. A few notes (that you already probably know)

  • Trouble loading sky textures - sky shown in black
  • doing shutdown fails - pkill command not found
  • FPS up around 62/63 and rock solid. This is much better than in my VM, which varies between 25 and 42.

Getting an ARM build working would be excellent. Getting an arm build + Gazebo would be the dogs bollocks.

@MaEtUgR
Copy link
Copy Markdown
Member Author

MaEtUgR commented Dec 5, 2017

@hamishwillee Thanks for testing!

  1. I know about the sky, I just did some test yesterday night and found out it's the same issue as Sky Does not display in jMAVSim #8229 which means enabling the VMWare case uses the old textures and rendering settings but works fine.
  2. Sry I don't understand. Are you closing the simulator window and expect it to also shut down px4? I always do Ctrl-C in the console which closes everything.
  3. Same here, if the delay of the QGC forwarded joystick information wasn't there I could practise my flying skills on my laptop and the 4K screen with this. In the VM performance was very limited especially with higher resolution output.

Totally agree. I will keep working on it 😉
I think ARM build is feasible as I had it workin in MinGW before using official native "GCC ARM Embedded" compiler which I will use again. Gazebo seems to be not exactly impossible but will probably require a lot of development time.

@dagar

  • see last paragraph
  • Or a local CI to start out with?
  • Visual Studio will not be my first goto option which doesn't eliminate it for the future.

@hamishwillee
Copy link
Copy Markdown
Contributor

Sry I don't understand. Are you closing the simulator window and expect it to also shut down px4? I always do Ctrl-C in the console which closes everything.

In PX4 console I normally type shutdown. That "nicely" shuts down PX4 and returns me to the command prompt. Ctrl+C probably works too, but I'm not sure it does as clean a kill.

Personally having jMAVSim working is fine for me - because mostly in docs I'm working in playing with parameters, and DroneCore. I know that ROS users and lots of our "future platform" work will find it essential.

@hamishwillee
Copy link
Copy Markdown
Contributor

PS. Sander / Deltaquad also have a VM based simulator that is rather nice. It just does their vehicle, just does jMAVSim. What I like about it is that it has a nice GUI for starting/stopping refreshing, and presumably you could abstract this to easily do different vehicles. As a pure simulator on Windows it is "user friendly". Suffers from same stability problems as other VM based solutions and no UI of course.

@AbhishekGS
Copy link
Copy Markdown

@MaEtUgR , I tried steps mentioned above and I ended up with the below error. Could you please guide me if I have missed anything?

asheshad@BGL-ASHESHADX ~/Firmware
$ make posix jmavsim VERBOSE=1
Re-run cmake no build system arguments
-- Build Type: RelWithDebInfo
/usr/bin/python: /usr/bin/python: cannot execute binary file
-- PX4 VERSION: v1.7.0-rc3-38-gb7c6bb8b6
-- CONFIG: posix_sitl_default
-- Build Type: RelWithDebInfo
-- The CXX compiler identification is GNU 6.4.0
-- The C compiler identification is unknown
-- The ASM compiler identification is unknown
-- Found assembler: /usr/bin/cc
-- Check for working CXX compiler: /usr/bin/c++.exe
-- Check for working CXX compiler: /usr/bin/c++.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- broken
CMake Error at /usr/share/cmake-3.6.2/Modules/CMakeTestCCompiler.cmake:61 (message):
The C compiler "/usr/bin/cc" is not able to compile a simple test program.

It fails with the following output:

Change Dir: /cygdrive/c/Work/Embedded_Targets/Work/Windows_PX4_cygwin_Matthias_grob/home/Firmware/build/posix_sitl_default/CMakeFiles/CMakeTmp

Run Build Command:"/usr/bin/ninja.exe" "cmTC_457ec"

[1/2] Building C object CMakeFiles/cmTC_457ec.dir/testCCompiler.c.o

FAILED: CMakeFiles/cmTC_457ec.dir/testCCompiler.c.o

/usr/bin/cc -o CMakeFiles/cmTC_457ec.dir/testCCompiler.c.o -c
testCCompiler.c

/bin/sh: /usr/bin/cc: cannot execute binary file: Exec format error

ninja: build stopped: subcommand failed.

CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:200 (project)

-- Configuring incomplete, errors occurred!
See also "/cygdrive/c/Work/Embedded_Targets/Work/Windows_PX4_cygwin_Matthias_grob/home/Firmware/build/posix_sitl_default/CMakeFiles/CMakeOutput.log".
See also "/cygdrive/c/Work/Embedded_Targets/Work/Windows_PX4_cygwin_Matthias_grob/home/Firmware/build/posix_sitl_default/CMakeFiles/CMakeError.log".
/bin/sh: line 0: cd: /cygdrive/c/Work/Embedded_Targets/Work/Windows_PX4_cygwin_Matthias_grob/home/Firmware/build/posix_sitl_default: No such file or directory
make: *** [Makefile:147: posix_sitl_default] Error 1

@MaEtUgR
Copy link
Copy Markdown
Member Author

MaEtUgR commented Dec 6, 2017

@AbhishekGS Looks to me like the toolcahin fails to execute ninja and the compiler...

  1. Could it be permissions? You generally don't need Administrator rights to compile this but there could be some problem with folder permissions.
  2. Did you change folder? I have it under C:\PX4\ . It should not make a difference but maybe it does or maybe your folder structure names just result in a path that's too long. (Just to rule that one out)
  3. Also try doing make distclean...

I'm guessing here sorry, I don't really see the likely cause.

@hamishwillee
Copy link
Copy Markdown
Contributor

Did you change folder? I have it under C:\PX4\ . It should not make a difference but maybe it does or maybe your folder structure names just result in a path that's too long. (Just to rule that one out)

I ran this under a differently named subfolder and it ran fine. So that is not the problem. I just did make posix jmavsim

@MaEtUgR MaEtUgR changed the title Cygwin: Enable build of SITL jMAVsim under Windows using the Cygwin Unix-like environment Cygwin: Enable build of SITL jMAVsim and ARM NuttX under Windows Dec 10, 2017
@MaEtUgR
Copy link
Copy Markdown
Member Author

MaEtUgR commented Dec 10, 2017

I rebased on master and added the ARM NuttX on Cygwin support.

  • First commit didn't change anything (not even rebase conflict)
  • Second commit is new and solves the two necessary cases where the cygwin path is converted the wrong way because there are custom commands that don't get handeled by the cmake ninja path magic or the cygwin handling already built into the NuttX Windows/Cygwin build.

Comment thread src/drivers/px4io/CMakeLists.txt Outdated
add_custom_command(OUTPUT ${fw_io_bin}
COMMAND mkdir -p ${PX4_BINARY_DIR}/ROMFS/${config_romfs_root}/extras/
COMMAND ${OBJCOPY} -O binary ${fw_io_exe} ${fw_io_bin}
COMMAND ${OBJCOPY} -O binary ${fw_io_exe_cyg} ${fw_io_bin_cyg}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kind of nitpicky, but instead of having special cygwin handling all over the place can we sidestep the issue by using relative paths?

https://github.com/PX4/Firmware/blob/master/platforms/nuttx/NuttX/CMakeLists.txt#L56-L57

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea, I'll try

Comment thread src/platforms/px4_time.h Outdated
__END_DECLS

#elif defined(__PX4_LINUX) || defined(__PX4_NUTTX) || defined(__PX4_DARWIN)
#elif defined(__PX4_LINUX) || defined(__PX4_NUTTX) || defined(__PX4_DARWIN) || defined(__PX4_CYGWIN)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this to a single #else after QURT?

Comment thread src/lib/rc/dsm.cpp Outdated
#include <drivers/drv_hrt.h>

#if defined (__PX4_LINUX) || defined (__PX4_DARWIN) || defined(__PX4_QURT)
#if defined (__PX4_LINUX) || defined (__PX4_DARWIN) || defined(__PX4_CYGWIN) || defined(__PX4_QURT)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flip this around to handle the special nuttx case first, otherwise use usleep.

@davids5 do you know why nuttx uses a delay instead of sleep here?

Ideally rc could be kept as a standalone lib without PX4 specifics.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably because it's used from IRQ context. Then it also makes sense to have the ifdef's in the current way: if we were to add support for another RTOS, we would stumble upon this, and realize that usleep cannot be used.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, then it's more readable and the chances for a new platform which might be added is higher to succeed without error.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right, the bind is done in the px4io serial dma callback.

Comment thread cmake/posix/px4_impl_posix.cmake Outdated
else()
elseif(CYGWIN)
set(added_definitions
-D__PX4_POSIX
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can move -D__PX4_POSIX to the top of this file so that it's applied to all configs.

-Dnoreturn_function=__attribute__\(\(noreturn\)\) is also added for all posix configs.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, let me see if there's an easy way.

@MaEtUgR
Copy link
Copy Markdown
Member Author

MaEtUgR commented Dec 11, 2017

@dagar In the latest commit I worked out a solution for all your comments except the first one.
I agree it would be nice to have relative paths in general but as you likely know most paths in the current build system are absolute and generated from camke variables like ${PX4_SOURCE_DIR} which then contain the OS specific drive identifier.

I'm pretty sure I break something if I do something like this: cygwin...cygwin-relative-paths-demo
especially when using a lot of ../.. it is prone to break when the structure changes right?

I didn't find a solution. But I'm also not completely sure why the conversion with the extra cygwin path is needed only in these places...

julianoes
julianoes previously approved these changes Dec 11, 2017
Copy link
Copy Markdown
Contributor

@julianoes julianoes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed, didn't see anything wrong.

@MaEtUgR have you built and tested Snapdragon with this branch to make sure it doesn't break anything?

@dagar
Copy link
Copy Markdown
Member

dagar commented Dec 12, 2017

Relative path usage update. cygwin...cygwin-relative-paths-demo

@MaEtUgR
Copy link
Copy Markdown
Member Author

MaEtUgR commented Dec 14, 2017

@julianoes Thanks, I never built snapdragon until now otherwise I would have tried. I'm pretty sure it is not be affected.

@dagar Your relative path solution is nice and works perfectly fine under cygwin. Thanks a lot for looking into it! I didn't know cmake has this feature. Now the paths in the build.ninja file are always correctly generated e.g. ../../..//nuttx_px4fmu-v4_default.elf px4fmu-v4.bin.

By the way, here's the newest version of the toolchain which builds all this:
https://drive.google.com/file/d/1fZk9tL2sq1whK47DyBGy63YOfnnFMYJ9/view?usp=sharing
Size basically only grew by the size of the arm gcc compiler (~400MB) which is obviously necessary. As soon as this pr is merged I will think of a way to create an official release for the toolchain.

@dagar
Copy link
Copy Markdown
Member

dagar commented Dec 16, 2017

OSX failure (circleci) is real. I'll look into it.

image

Update - the issue seems to be a difference in where Make vs Ninja perform the linking.

@dagar
Copy link
Copy Markdown
Member

dagar commented Dec 16, 2017

@MaEtUgR I fixed the OSX makefile issue. Please test it under cygwin.

@MaEtUgR
Copy link
Copy Markdown
Member Author

MaEtUgR commented Dec 18, 2017

Sadly the cygwin build is broken with these changes. Let me have a look.

@MaEtUgR
Copy link
Copy Markdown
Member Author

MaEtUgR commented Dec 18, 2017

If I run it without the last commit I get the path NuttX/nuttx/configs/px4io-v2/scripts/ld.script for the linker script in the build.ninja file which is the correct one from the view of the build path.

With the last commit cmake writes the relative path ../../..//NuttX/nuttx/configs/px4io-v2/scripts/ld.script which is incorrect...

EDIT:
${CMAKE_CURRENT_BINARY_DIR} is /cygdrive/c/PX4/home/Firmware/build/px4fmu-v2_default/src/firmware/nuttx and somehow the linker is executed in the PX4 binary path...

@MaEtUgR
Copy link
Copy Markdown
Member Author

MaEtUgR commented Dec 19, 2017

@dagar What do you think about the last commit?

@MaEtUgR
Copy link
Copy Markdown
Member Author

MaEtUgR commented Jan 4, 2018

I rebased on master again and as discussed with @dagar reverted to using converted absolute paths to the linker script again because the ARM GCC linker seems to interprets relative paths differently on linux, mac and windows...

Just for reference:
--script=NuttX/nuttx/configs/${BOARD}/scripts/${LD_SCRIPT} works on windows and linux
--script=../../..//NuttX/nuttx/configs/px4io-v2/scripts/ld.script works on mac and linux
I didn't find out why...

@MaEtUgR MaEtUgR added this to the Release v1.8.0 milestone Jan 4, 2018
dagar
dagar previously approved these changes Jan 4, 2018
@dagar
Copy link
Copy Markdown
Member

dagar commented Jan 4, 2018

Looks good. I strongly suggest having CI in place if you don't want this to break on a semi regular basis.
In fact I think that should be the bar before documenting and claiming to support this.

PX4 Firmware CI

  • cygwin build
  • basic jmavsim test?

Toolchain update should be automated and compiler version needs to be kept in sync with Ubuntu (docker) and OSX.

MaEtUgR and others added 6 commits January 5, 2018 14:25
…nix-like environment

Most of the incompatitbilities are luckily similar to the darwin build.
- New target OS __PX4_CYGWIN added because in other build environments on Windows defines will very likely be completely different
- added all necessary exeptions to the defines
- disabled priorities completely because on Windows they are defined 1-32 and with all the arbitrary +40 -40 priority settings there were a lot of problems
  not only did some threads/"virtual tasks" not start because of out of bound priorities but also the resulting scheduling was totally random and inadequate
  with default priorities it ran toally fine during my first tests, should be rethought when windows is used onboard in the future
…t again

because the relative path is interpreted differently on linux, mac and windows
@dagar
Copy link
Copy Markdown
Member

dagar commented Jan 5, 2018

Rebased to resolve merge conflicts. Let's get this in and continue iterating.

@dagar dagar merged commit c0c0666 into master Jan 5, 2018
Copy link
Copy Markdown
Member

@LorenzMeier LorenzMeier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

@LorenzMeier LorenzMeier deleted the cygwin branch January 5, 2018 19:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants