Sunday, January 30, 2022

Installing C++17 on CentOS 7 and using it with Eclipse

By default, CentOS 7 supports C++ up to 2011 (C++11). For C++17 (2017) support with Eclipse IDE:
  1. Login to CentoOS 7 as root.
  2. Open terminal.
  3. Install Developer Toolset 8yum install dev-toolset-8
  4. cd into Eclipse folder.
  5. Enable toolset 8 for Eclipse and open it: scl enable devtoolset-8 ./eclipse
  6. After Eclipse opens, open/create a C++ project, use this filesystem example.
  7. Go to project properties - C/C++ Build - Settings - Tool Settings - GCC C++ Compiler -  Dialect - Other dialect flags and enter -std=c++17:
  8. Now you can build your project using C++ 2017 features. If you print __cplusplus, you get 201703. Note that project include folders point to devtoolset-8:

Rebuild index. Now you can compile but still get linker error.

Add linker flag -lstdc++fs and reorder linker flags so that -lstdc++fs is at the end: ${COMMAND} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS} ${FLAGS}

Now you can successfully run the example.

Tuesday, January 25, 2022

Development phases of aerospace flight software

When developing embedded software for a complex system, it is not advisable to do the development primarily on target hardware because a test that might take a single developer 5 minutes on a PC might take 4 people half a day on target hardware. We are talking about 100x of efficiency difference. To minimize time spent on target hardware, the following six phases of aerospace flight software development might help:

This approach converts the typical time - effort curve A to a more manageable B:
Phase 1: Test application logic of each software configuration item separately on non real time commercial PCs  (communication is only via ethernet). To do this you have to have abstraction layers for hardware, OS, time synchronization and non-ethernet interfaces. Examples of application logic: Checking flight envelope, reading DTED files, calculating checksum, converting IMU mathematical model outputs to specific IMU brand interface, estimating position. Tests should be automated and run every night. Automated tests immensely reduce the stress of refactoring and experimentation because if you have "good enough" test coverage, any problem will be discovered at most a day later.

Phase 2: Use commercial PCs with real time OS, integrate software components with each other (still only ethernet communication) and verify that software interfaces and state transitions that depend on timing work as expected. Again, use automated nightly tests.

Phase 3: Now that you have high confidence in software due to thousands of tests having passed during the previous phases, begin deploying software on electronics hardware and test. At this stage, you should mainly focus on verifying that software is working in the constrained environment of target hardware (small heap, stack, disk, RAM, processing power etc.) and that non-ethernet interfaces are ok. If there are problems in application logic, go back to Phase 1/2 development environment for debugging.

Phase 4: Deploy all software to hardware and test.

Phase 5: Add other electro-mechanical systems (sensors, actuators) and test on the ground.

Phase 6: Do full system flight test.

Saturday, January 15, 2022

C++: const_cast use case

A third party function that I have to use has an input of type char* which the function does not modify. Normally the type should be const char* but the function writer was a novice it seems. I cannot change it to const char* because it is used in other code that such a change would break. I have a variable that needs to be string so that I can use the flexibility of string. In order to send that string variable into the third party function, I cannot just use  string.c_str() because the compiler would complain that you cannot send a const char* to a function that expects char*. To remove the "constness", I have to use const_cast<char*> (string.c_str()). Example implementation:

Note that the third party function does not modify the input char*. If it did, I could not use const_cast (even tough it would compile) because it would result in undefined behaviour.

Friday, January 14, 2022

File search in Eclipse and Visual Studio

 To search for files in

  • Eclipse: ctrl + shift + r
  • Visual Studio: ctrl + , (comma)
    • It also searches for methods and classes

Monday, January 10, 2022

Eclipse working folder

To change Eclipse working folder so that file paths are the same when running project from IDE and when running the binary from terminal, you have to set the working directory (similar to Visual Studio) using the Run Configurations - Arguments - Working Directory: ${workspace_loc:MyProject/Debug}

Note that Eclipse run configurations are saved in <eclipse-workspace>.metadata/.plugins/org.eclipse.debug.core/.launches

To copy files on Linux Eclipse in post-build step:

  1. Select Project - Properties - C/C++ Build - Settings - Build Steps
  2. In Post-build steps, enter cp source destination
If you have changed the working folder as explained above, then source will be relative to that working folder. If, for example, you want to copy a folder to working folder, you could use cp -f -R ../src/config .
You can enter more than one cp command by separating them with a semicolon (;)

Sunday, January 9, 2022

xcopy and Eclipse build path variables

When working with Eclipse on Windows, some of the system build path variables will have "/" while others have "\" as path separator:


When using xcopy in Post-build steps, there cannot be "/" in path because xcopy treats anything with a "/" as a parameter. For example if you use ${ProjDirPath} with xcopy, you will get "invalid number of parameters" error. To solve it, edit ProjDirPath and replace "/" with "\". Don't forget to do it for both Debug and Release configurations.

Wednesday, January 5, 2022

Checking C++ version in code

If your code has to behave differently for different C++ versions, you can check the value of __cplusplus directive. It will return the year and month of C++ standard used in your current environment. Examples:

  • 199711L stands for Year=1997, Month = 11
  • 201103L stands for Year=2011, Month = 03
If you want to run code only if C++ version is less than C++11, you write:
#if __cplusplus < 201100L
When you use Visual Studio 2019 and print the value of __cplusplus to console, you will see 199711, although in the project properties - C/C++ - Language page it is set to C++14:
For Visual Studio to output the correct value, you have to go to Configuration Properties > C/C++ > Command Line and add /Zc:__cplusplus. Now you get the correct value of 201402.

Tuesday, January 4, 2022

Visual Studio Setup

The default Visual Studio setup is impractical. Here is my setup for C++:

  • Output Directory: $(SolutionDir)bin\$(Platform)\$(Configuration)\
  • Intermediate Directory: $(SolutionDir)bin\intermediate\$(Platform)\$(Configuration)\
  • To read files from exe folder instead of solution folder when running from IDE, Working Directory: $(SolutionDir)bin\$(Platform)\$(Configuration)\

  • I put a sample VS2022 project template to github.
  • To copy an input file (file.txt) to exe folder after a build: xcopy $(SolutionDir)file.txt $(SolutionDir)bin\$(Platform)\$(Configuration)\ /Y

Note: If you use the same intermediate folder for all configurations, you might get "fatal error C1041: cannot open program database ...vc120.pdb". The solution is to set /FS command line flag.