propgcc: Issue with libpropeller's serial.PutFormatted
trancefreak
Posts: 186
I just started to use some of the cool objects of libpropeller. I'm not really a C/C++ Expert so maybe someone could help me with the following error message I get when compiling the project:
If I use the serial.PutFormatted function of the serial object, compilation fails. If I just use serial.Put it works. The serial object includes the "Numbers.h" file, so I don't have a clue, why compilation fails.
I appreciate any help :-)
Thanks,
Christian
propeller-elf-c++.exe -L..\lib -o bin\Release\AddamsFamilyPinballMaster.elf obj\Release\lib\Domain\AutonomousKicker.o obj\Release\lib\Domain\ModelBase.o obj\Release\lib\Domain\OneTimeHitCounter.o obj\Release\lib\Domain\OutputActivator.o obj\Release\lib\Domain\Scheduler.o obj\Release\lib\Domain\SchedulerRegistry.o obj\Release\lib\Game\EventMessage.o obj\Release\lib\Game\InOperationState.o obj\Release\lib\Game\PinballHSM.o obj\Release\lib\Game\StateBase.o obj\Release\lib\Lamps\LampShow.o obj\Release\lib\Lamps\LampShowWorker.o obj\Release\lib\Lamps\MultiballLampShowWorker.o obj\Release\lib\libpropeller\serial\serial.o obj\Release\lib\Timer\CounterSpan.o obj\Release\lib\Timer\PauseTimer.o obj\Release\lib\Util\c++-alloc.o obj\Release\Master\main.o -Os -Wall -mcmm -m32bit-doubles -fno-exceptions -fno-rtti -s -ffunction-sections -fdata-sections -Wl,--gc-sections CogC_Drivers\IODriver\bin\Release\IODriver.cog obj\Release\Master\main.o: In function `libpropeller::Numbers::Dec(int, char*)': (.text._ZN12libpropeller7Numbers3DecEiPc+0x3): undefined reference to `libpropeller::Numbers::internalBuffer' obj\Release\Master\main.o: In function `libpropeller::PrintStream<libpropeller::Serial>::Format(char const*, void*)': (.text._ZN12libpropeller11PrintStreamINS_6SerialEE6FormatEPKcPv+0x2e0): undefined reference to `libpropeller::Numbers::internalBuffer' obj\Release\Master\main.o: In function `libpropeller::PrintStream<libpropeller::Serial>::Format(char const*, void*)': (.text._ZN12libpropeller11PrintStreamINS_6SerialEE6FormatEPKcPv+0x2e7): undefined reference to `libpropeller::Numbers::internalBuffer' obj\Release\Master\main.o: In function `libpropeller::PrintStream<libpropeller::Serial>::Format(char const*, void*)': (.text._ZN12libpropeller11PrintStreamINS_6SerialEE6FormatEPKcPv+0x2fb): undefined reference to `libpropeller::Numbers::internalBuffer'
If I use the serial.PutFormatted function of the serial object, compilation fails. If I just use serial.Put it works. The serial object includes the "Numbers.h" file, so I don't have a clue, why compilation fails.
I appreciate any help :-)
Thanks,
Christian
Comments
The numbers module also contains a source file, `numbers.cpp`. Simply copy that file into your project and you'll be good-to-go.
(Completely unrelated to your problem, I'm just curious)
Doing everything using inline classes is great for maximum compilation efficiency, but it makes it a pain when you need to use class variables. Then you have to toss it into a .cpp file and pull that in, which is pretty ridiculous. I haven't figured out a better way to do it, though.
I played around with the idea of a preprocessor macro named "WHOLE_PROGRAM". At the bottom of my header, I had the following:
I had a CMake option named WHOLE_PROGRAM, which would define the "WHOLE_PROGRAM" macro and add the -fwhole-program flag. I was really happy with this idea!!! Until... I tried using with a program that had an assembly driver
Thanks very much for the quick help!! I added the numbers.cpp file to the project and it compiles and works, now.
Hmm... Shouldn't the compiler find the numbers.cpp because the numbers.h is included in the serial.h file and I thought the compiler will look in the same directory for the matching .cpp file.
<snip>
That compilation line is interesting. You certainly didn't write that by hand. Are you using Eclipse?
(Completely unrelated to your problem, I'm just curious)
</snip>
No, I didn't write that by hand ;-)
I'm using Code::Blocks to compile the main code and the cogc drivers.
Thanks again!
Christian
Wishful thinking. The short story: no. No C/C++ compiler works that way. Think about the case where you have a static library and header files... what *.cpp file are you going to look for?
If that's the case, PropWare was made for you. You and I are two of a handful of folks on these forums that prefer a full-blown IDE over SimpleIDE or vim/emacs. PropWare uses CMake for its build system, and CMake fully supports Code::Blocks. You might also like CLion - it supports CMake natively. And since I like libpropeller as much as you do, it's already included in PropWare and is automatically built and linked into your program (aka, no need to include numbers.cpp in your project).
http://david.zemon.name/PropWare/
Yes, I used SimpleIDE in the beginning but the lack of having a structured project view and really "simple" IDE features I started looking for another IDE where I struggled over Code::Blocks. You have to configure so much by hand when using cogc files, i.e. add a post-build step so that objcopy can rename the text section and so on.
When using CMake with Code::Blocks, do I have to edit the Makefile by hand or does this Code::Blocks? I'm not very familiar with Makefiles, so I tried to not use Propware because I don't have a clue how to set it up with my IDE ;-)
Do you have a document describing the necessary steps for propware?
I really would like to try it out :-)
You have to write your own CMakeLists.txt files, but they're extremely simple. For instance, yours will probably look like this:
Hmm... That was the reason why I used an IDE where I don't have to manage Makefiles. In Code::Blocks I just click on Add file, select the appropirate .cpp or .h file and that's it. The IDE includes the file into the command line build call and handles the linking of the generated object and so on.
When using CMake, do I have to add each file I use in the IDE additionally to the CMakeLists.txt file?
Many, many years ago I used Eclipse to program in JAVA. We used Maven back then. I remember, we could create an Eclipse project with Maven. And if the initial project was set up, I just had to add the new reference packages and files in Eclipse and that updated the Makefiles automatically so it was possible again to create a new Eclipse project with Maven.
Or maybe I'm completely wrong. This was 10 years ago :-)
numbers.cpp does have that `#ifdef` business (under "SINGLE_TRANSLATION_UNIT").
And I agree: CLion and CMake are the way to go.
I think I'll start using it this weekend. It's half past twelve now, so I'm going to get some sleep, but the combo CLion and CMake look really cool especially because CLion completely includes/supports CMake and can update the Makefile automatically :-)
Thanks for pointing that out!
Oh yea... that's where I got the idea lol. Did you find a way to make that work when including assembly or cog modules? Or do you just have a mental note not to use that option sometimes?
When I first heard that JetBrains was announcing their own C++ idea, these were the exact same thoughts that went through my head.
I assume you have this all figured out, now that you've watched the video?
I use maven every day at my job. It is, by far, the best build system I've ever seen. When I first started, I was sickened by how painfully slow it was (and still is). Then I learned what it does.... :O Every time I ran into a problem with CMake in PropWare, I'd say to myself "why can't I just use Maven!?!?!"
I fear, that when the EAP is over a single user license is so expensive, that I can't afford one just for a hobby project.
How do you guys handle that? Are you working with the EAP builds for 30 days or have you bought a license? If so, how much is one? I was not able to find a price on the JetBrains page.
I don't want to start CLion and get used to it and 30 days later I can't work on the project anymore because I don't wanna spend 3000$ on a single user license ;-)
re CLion: you can just keep renewing. I've done it three or four times so far. And when it's eventually a product I anticipate it won't be too much. I paid $49 for Webstorm. PhpStorm, PyCharm, and RubyMine are $99, and renewals are less. For me it's worth it. And tax deductible, so that's like cutting off 25% right there.
Definitely I'll give it a try.
Do you know if within the libpropeller project or PropWare there is an example how cogc files are handled with CMake (with regards to use objcopy to be able to use the _load_start... stuff in the main program)?
I'm afraid that's been a thorn in my side for a while. If you're writing your own cogc file, yes it can be done. I am not yet able to include cogc files from the Learn folder. I've created an issue for it here which links to this thread.
If you're willing, you can copy/paste the cogc file out of the Learn folder, into your project, and make the necessary change as described in the above linked thread. Then it would be functional.
I'm also working on creating an example cogc project, but it ended up getting shoved pretty far down the priority list. If it's something you need, let me know and I could bump it back up.
Can anyone give me some pointers.
Thanks
Alex
But, anyway, once you've installed PropWare and created your CMakeLists.txt file, simply start a terminal in the folder of your project and run the following:
That command will create a Code::Blocks project file in the same directory as your project, at which point you can use Code::Blocks to "Open existing project" and start programming. I tested the build, rebuild and run buttons in Code::Blocks. Build and rebuild worked great, run was a bad idea and I had to exit Code::Blocks and kill propeller-load in top (linux version of Task Manager). This is mostly expected, and you'll see similar results in other IDEs. Running/debugging PropWare applications is best done through the command line - I haven't found a good way to hook propeller-load into any IDE yet.
Today I had time to try to install propware but the installer didn't succeed. I have added the errors below.
Currently I'm downloading CLion and will play with it a bit :-)
After that I will go over the thread you linked with regards to cogc file with CMake.
Regards,
Christian
Thanks,
Christian
Ok, I think I'm one step further. After adding the path to the make utility the installer did some more steps than before, but now it hangs while scanning for dependencies of target Simple_lmm.
What I also notice is, that COGC, COGCXX, ... compiler identification is unknown. But the cogc compiler is also propeller-elf-gcc.exe. Why does the installer doesn't recognize the cogc compiler identification?
Here is the full output:
Christian
Because I didn't bother with all the CMake crud required for it to understand that it is using GCC. It doesn't matter though - it's superfluous.
That is not so normal . I don't know what could be causing it. My only guess is something very weird happened in the build directory and CMake has confused itself. Try deleting C:\Users\Christian\PropWare\bin and rerunning the installer.
As a side note, the above issue is why it's important to use "out-of-source" builds with CMake. CMake creates lots of extra files (metadata, Makefiles, caches, etc) when you run "cmake .." and sometimes it gets broken. When it's broken, you want CMake to start over from scratch, and that is by far most easily done when you can just delete an entire directory instead of picking through your source code and trying to remember what is auto-generated by CMake and what actually matters for your project.
Now it hangs here:
Hmmm... Do you have any idea what I could do or try?
Is there some parameter where I can switch on a more verbose mode to provide you more input?
Christian
Could there be an issue with python?