Universal C++ Project - C++ programming for Linux, and more

While WindRiver provides an excellent programming environment, it is not suitable for everyone. The Universal C++ Project (UCPP) aims to provide development tools that allow programmers in different environments, such as Linux, Mac OSX, Eclipse, command line, and others. At the same time, we intend to remain compatible with WindRiver projects, allowing WindRiver and UCPP users to collaborate on projects.

Project Pages and Downloads:
FIRST Forge project: http://firstforge.wpi.edu/sf/projects/ucpp
Releases (zip files): 0.1+git20110208
Source code via git: https://github.com/nikitakit/ucpp

Instructions for installing and using UCPP are in the readme file accompanying the source code.

Platforms currently supported:

Linux with WindRiver files
– Compile C++ code on Linux with a WindRiver installation (ideal for dual-boot systems with WindRiver installed on the Windows drive). There is a command line interface for generating Linux makefiles for a C++ project and runs WindRiver gcc under wine in order to compile the project.

Linux without WindRiver files
– Same as above, except that the compiler, VxWorks, and WPIlib are automatically downloaded from the Internet

Windows using the MSYSgit command line
– Still requires WindRiver to be installed, but if you prefer to use another IDE or text editor you can now compile and deploy code from the command line.

Platforms coming soon…

Windows/Cygwin command-line interface (this should be possible with just a minor bit of tweaking)
MacOS X port of the Linux environment
Cross-platform Eclipse IDE plugin (about half done)
Explorer/Nautilus(/Finder?) right click build and deploy options

Project Members:

Special thanks to:

Interesting, I’ll be looking forward to this next year when we program in C++. (That is if we do)

I’ll definitely try this out tomorrow–cool stuff.

Is there support for reading the target console output without NetConsole?

socat UDP4-RECV:6666 STDOUT

While playing around with it, the compiling appears to be working great. However, I am having a small problem with the Makefile in the root directory of the project. Using the default configuration, I get the following error when attempting to run make (I get the same output when running make deploy):

cd PPC603gnu && exec make -f Makefile_linux "Makefile" 
make[1]: Entering directory `/home/wiredcats/code/Wiredcats2011/PPC603gnu'
make[1]: *** No rule to make target `Makefile'.  Stop.
make[1]: Leaving directory `/home/wiredcats/code/Wiredcats2011/PPC603gnu'
make: *** [Makefile] Error 2

My quick hack replaced the Makefile with this:

#UCPP makefile

# For the default target, use the WindRiver makefile
all: force
        cd PPC603gnu && exec $(MAKE) -f Makefile_linux

# TODO: insert targets that download gcc and WPIlib

# For all other targets, use the WindRiver makefile
deploy: force
        cd PPC603gnu && exec $(MAKE) -f Makefile_linux deploy 

force: ;

Everything works as expected in terms of building/deploying (or at least, it appears it does. I haven’t tested it on a cRIO yet). But of course, it isn’t ideal as it only lets me use the “deploy” target. I’m not too proficient in make, so I’m not positive as to how to fix it myself.

I’m running Ubuntu 10.04 with GNU Make 3.81 if it helps. I’m about to head to the shop, so I’ll keep you posted on whether or not it successfully deploys and runs.

My best guess at what is happening is that “Makefile” is a default target of sorts, and it gets matched by the wildcards. For some reason, I don’t have any problems on my machine. Maybe it’s because I have a WindRiver makefile so the “Makefile” target is skipped instead of giving an error.

I think I’ve finally figured out how to fix it:

#UCPP makefile

# Default target
all: force
    cd PPC603gnu && exec $(MAKE) -f Makefile_linux

# Don't do anything for the "Makefile" target
Makefile: ;

%: force
    cd PPC603gnu && exec $(MAKE) -f Makefile_linux "$*"

force: ;

That fix worked great (once I redid the tab spaces)! I have successfully loaded code from Ubuntu to the cRIO. Thanks for the great tool, I’ll be using it here on out :slight_smile:

Great! I’m going to commit those changes and maybe make a quick patch-up release.

[strike]Ah, just one more problem…

I keep all of my tasks in a separate folder in my root directory named Tasks. It looks like by default, UCPP is only looking for files in the root directory to add to the Makefile. Is there a way to add those files in the folder?[/strike]

I solved my own problem. I created a file named .ucppdirs in my root directory of the code, then edited ucpp_gen_makefile.py as such:

# Find all the C++ files in the current directory

file_names = ]

d = file(".ucppdirs", "r")
dirs = d.read()

for direc in dirs.split():
    for filename in os.listdir(direc):
        if filename-4:]==".cpp":
	    file_names.append(direc + filename:-4])

I managed to try this out today, and it worked flawlessly. Thanks guys!

I found myself in need of the latest version of WPILib, and didn’t want to go through the process of installing the update. So, I came up with a workaround. Here’s some shell code that will get the latest version of WPILib. I present it here in the hopes that you will find it useful.


wget -q http://firstforge.wpi.edu/sf/frs/do/viewSummary/projects.wpilib/frs -O - | grep 'WPILib C++ update' | sed "s/.*<a href=\"\(^\"]*\)\">.*/http:\/\/firstforge.wpi.edu\1/" | uniq | sed "s/;.*//" > wpilib_page1.url
wget `cat wpilib_page1.url` -q -O - | grep "rel[0-9][0-9]*" | grep href | sed "s/.*\(rel[0-9]*\)/\1/" | sort -r | head -n 1 | sed "s/.*<a href=\"\(^\"]*\).*/http:\/\/firstforge.wpi.edu\1/" | sed "s/;.*//" > wpilib_page2.url
wget `cat wpilib_page2.url` -q -O - | grep "\.exe\s*<\/a>" | sed "s/.*<a href=\"\(^\"]*\)\".*/http:\/\/firstforge.wpi.edu\1/" | sed "s/;.*//" > wpilib_page3.url
wget `cat wpilib_page3.url` -q -O wpilibupdate.exe

mkdir wpilibinstaller

cd wpilibinstaller
unzip ../wpilibupdate.exe | tee unziplog.txt

cat unziplog.txt | grep "inflating: WPILib/.*\.zip" | sed "s/.*\(WPILib\/.*\.zip\).*/\1/" | xargs -I '{}' cp '{}' ../
cat unziplog.txt | grep "inflating: WPILib/.*\.zip" | sed "s/.*WPILib\/\(.*\.zip\).*/\1/" | xargs -I '{}' ln -s '{}' ../WPILib.zip

cd ../
rm -r wpilibinstaller

rm -f wpilib_page1.url wpilib_page2.url wpilib_page3.url

Thank you everyone for your comments!

A quick update on the status of things:
I only made a few minor changes in the past few weeks, hopefully I’ll get around to making a new release by Monday.

Major items on my to-do list:

  • Make the C+±file-finder recurse into subdirectories
  • Fix the problem with non-recent WPILib versions

AustinSchuh, thank you for all of your comments. I still haven’t gotten around to testing your version of gcc, but I’m definitely going to do that this weekend.

Also, if anyone reading this thread uses Cygwin and feels like taking on a challenge: the Cygwin version of ucpp runs into some pretty nasty problems. If you can come up with some kind of fix I’d be very grateful.

Version 0.2 is now available for download

Key changes:

  • Cleaner commands: many arguments now have auto-detected default values, so there’s less to type and remember
  • The default environment for linux is now gccdist. No manual WindRiver installation is required: just run “ucpp setup” and wait for it to download everything on its own.
  • On Linux, the latest WPILib is automatically downloaded using AustinSchuh’s script. It doesn’t have to be compiled manually because the WPILib update already comes with the compiled version
  • C++ files are searched for recursively

Ok, sounds like a stupid question, but does the debuggers and watches and breakpoints and ect work? Those are some very, very important tools that most people seem to overlook here.

On Linux?

If you have a couple days to burn, it’s possible to get all the breakpoints working on Linux. I’ve done it. If you are willing to document it for others, I can lead you through the process (from memory). It’s not trivial though.

I’ve also yet to use a breakpoint with FRC for the last couple years, and it hasn’t slowed me down much.

This summer (after the season and when my schedule calms down), I’d like to try to tackle porting the debugger. Should involve porting gdb_server over to the cRIO. Shouldn’t be that hard, but having not tried it, I don’t know.

Ooh, I’m excited, I can’t wait to use this (I can hear my mentor groaning about me wanting to use nonstandard tools in my head). I can already imagine the insane way I’ll use this when I need some quick drive code, its going to involve a VPN, ssh, and a phone with a qwerty keyboard.
Seriously though I’m excited about this because I like linux (and mac).

The first (somewhat) usable Eclipse plugin is here!
Start by installing the main Universal C++ scripts, git (if on windows), Eclipse CDT, and putting ucpp in your path. Then open the install new plugin dialog and enter http://ucpp.thecatattack.org/ as the url, and install it all.
create a new C++ project, and right click and go to Universal C++> initialize ucpp and fill in what you want (if you have not already done so from the command line)
go to window>prefs>FIRST downloader prefs (ucpp) and set team number and out file (can be changed later)

Then you can create other projects and code
(for each project)right click, and go to Universal C++> mark as Ucpp project
it should autobuild, if not, click the hammer icon

right click project>ucpp>download
…OR …

Just tested this out on Ubuntu 10.10, and everything compiled!

However, I had to do a bit of hacking because it turned out that the “HOME” variable was unset inside the shell scripts. Do you have any idea why this happened? (If not, I can just add “set HOME variable if unset” to the shell scripts).

Also, I think you can simplify the “Initialize ucpp” dialog. On Linux, the two drop-down options would be:

  • Automatically install the compiler and latest version of WPILib
  • I already have the WindRiver compiler installed (and ask for the path to the C drive in this case)
    If you re-use the team number inputted in the preferences dialog, that means that you can remove the long help-text off to the side.

Other than these suggestions, I think we’re ready for the next release.

Unless I’m missing something (entirely possible), there’s an even cleaner way. Check to see if the compiler is there on build, and if it isn’t, then put up a prompt asking if the user wants you to install it. This sets things up so you can literally just hit compile and it’ll work out the details. Almost dummy proof. :stuck_out_tongue: