1. Approach

Codeblocks is a simple but powerful compile and run IDE for MS-Windows and Linux. It can be used for first experience as well as to compare capabilities with other known and familiar IDEs such as VS-Code or Eclipse-CDT.

For test on PC it is recommended to use the GNU GCC compiler suite. This is done and described here. The description is only one focus: GCC with usual C language files, but using C++ compilation.

Codeblocks allows single stepping, set breakpoint etc. All what an IDE can do.

Alternatively also the GNU GCC suite with the same options is also used for Zmake script compilation.

VS Code should be described also here, it isn’t done yet.

2. Install tools

TODO on Debian 12,

2.3. Zmake script compilation

For installaton is needs only the standard vishiaBase.jar Java library, running under Java recommendet the traditional Java-8 version, also in higher versions.

On Windows MinGW should be available see https://vishia.org/emc/html/TestOrg/testStrategie_en.html#_infrastructure_on_the_pc_for_test_emc. On Linux just GCC should be installed.

3. Zmake, or simple command line compilation

This is an approach alternatively to common cmake command line usages with some advantages especially for generated code. It is developed by vishia.org from Dr. Hartmut Schorrig, step by step since mid of 1990th, and stable in the yet used form since ~2012. The difference in comparison with a GNU-cmake approach is:

  • General the Zmake process generates a shell script on demand depending from the source situation. This compileAndLink.sh script contains the compiler and linker invocations direct as command line invocation. That has the advantage, that the exact used cmd and options are obviously before, during and after compilation. The script for generation can be changed, for example for changing options or for calling additional special tools in an obviously form. The script is written and executed as https://vishia.org/JZtxtcmd/html/JZtxtcmd.html using Java as Runtime environment.

  • The files to compile are given in some so named file set in JzTxtCmd syntax: https://vishia.org/JZtxtcmd/html/JZtxtcmd.html#chapter_9.1.13

  • On generating the compileAndLink.sh script the source files are checked against changes to detect whether a source file is new. For that not the time stamp of the object is used, because especially for generated sources, it is possible that the source file is generated newly, but without changes. That’s why two strategies exists to detect whether a source is changed, and the compilation should be performed:

    • a) Compare with a mirror location, where the last used file for compilation is stored.

    • b) Build a list of files with time stamp, length and CRC code. Compare each file with its list entry. If the file has the same time stamp and the same length, it is expected unchanged. If this both is different, the CRC check is build, whereby maybe comment parts are excluded. Then the CRC is compared with the list entry. If it is not equal, then the source is expected to be changed.

    • If the source file is seen as 'changed', then an existing target (object) file is removed. Compiled object files from non-changed sources remains.

    • In the shell script for compilation, the compilation is conditionally done, only if the target (object) file does not exists. Same for linking or for any other translation approaches.

See details for example in explanation of the OFB https://vishia.org/fbg/html/Videos_OFB_VishiaDiagrams.html or in https://vishia.org/emc, see https://vishia.org/emc/html/TestOrg/testStrategie_en.html or on button [Github & Test]

Because it is not enough obviously in given descriptions what the zmake command in a JZTxtCmd script do, a short explanation:

  zmake <:>build/<&CMPN>/objZmake/<&testCase>/*.o<.> := ccCompile( CMPN=CMPN
  ,&c_src_emC_core
  , &srcSet
  , cc_def = cc_defh, makesh = makesh, depArgs = depArgs, testCase=testCase, ccSet=ccSet
  );

Above, it is a line calling zmake in the script OFB_Presentation/src/Organize_OFB/genScriptZmake_emC.jztc.

  • The destination of the zmake is left of :=, given as file path with wild card, the objects of compilation.

  • The source of zmake is right side given in the "zmake" operation as "file set " c_src_emC_core and srcSet. This file sets are defined in the kind (shortend here) from OFB_Presentation/src/ExmplBandpassFilter/makeScripts/filesets.jzTc:

Fileset c_src_emC_core =
( src/src_emC/cpp:emC/Base/Endianness_emC.c
, src/src_emC/cpp:emC/Base/StringBase_emC.c
, src/src_emC/cpp:emC/Base/Time_emC.c
, src/src_emC/cpp:emC/Ipc/SocketComm_Ipc_emC.c
, &src_Ctrl_emC
, &src_OSALgcc
);


Fileset src_ExmplBandpassFilter =
( build/ExmplBandpassFilter/genSrc:ArrayBandpassFilter.c
, build/ExmplBandpassFilter/genSrc:ArrayBandpassFilter_scope.c
, build/ExmplBandpassFilter/genSrc:OrthBandpassFilter.c
, build/ExmplBandpassFilter/genSrc:BandpassFilterModulDef.c
, build/ExmplBandpassFilter/genSrc:OrthBandpassFilter_scope.c
, build/ExmplBandpassFilter/genSrc:BandpassFilterModulDef_scope.c
, src/ExmplBandpassFilter/cpp/ExmplOrthi.c
);

The src_Ctrl_emC and src_OSALgcc is another file set also defined in this context, which is included in the file set c_src_emC_core.

The operation ccCompile(…​) decides how to use this file sets and output paths. For that it has an internal argument target as instance of the Java class:

In this instance the output file path is set to ZmakeTarget#output and the input file sets are set to ZmakeTarget#inputs.

If the JzTxtCmd operation ccCompile is executed, it calls for all input files of the input set in the for loop (shortened):

  for(c_src1: target.allInputFilesExpanded()) {
    <:>
    #echo ==== gcc <&c_src1.localfile()> 1>> <&target.output.localdir()>/gcc_err.txt
      <&ccSet.cc> <&cc_options> -Wa,-adhln <&cc_def> <&inclPath> -o <&target.output.localdir()>/<&c_src1.localname()>.o <&c_src1.file()> 1>> <&target.output.localdir()>/<&c_src1.localname()>.lst 2>> build/<&CMPN>/result/<&testCase>.cc_err
    <. >
  }

It means here,, it generates the output lines which calls the compiler in the created shell script.

It means, a zmake operation in JzTxtCmd has only the additional capability of target, as argument in this writing style. Elsewhere it is a normal operation in the JzTxtCmd context.

4. GCC

4.1. Why C++ compilation with GCC on PC, but with C sources

This is experience since the mid of 1990th for embedded control: Usual the C++ version of the compiler makes more checks especially with pointer types. So writing or thinking errors were better detected. The code generated with C-sources is near or real equal as the C compilation. In that kind, the sources compiled on PC are better checked, also used in test on PC. And then also C-compilation can be used for a target compiler, which does not support or should not support C++ due to rules of source development.

4.2. Why using C instead C++, but C object oriented.

Generally, a lightweight C++ is often ok, if a C++ compiler is possible to use for target development, But complex C++ constructs (templates, virtual operations) may not be desired in some development teams.

On the other hand, object oriented programming (which is anyway recommended) is possible without limitations also in C language. This is shown on many examples in the emC examples (https://vishia.org/emc) as well as also for OFB: https://vishia.org/fbg/html/Videos_OFB_VishiaDiagrams.html

4.3. Default settings for GCC

If gcc is installed, the standard include search path and libraries for standard C/++ are configured with any more options. It means path to libc.a, or to <stdio.h> etc. don’t need to be given. But then, which includes and libraries are used, it’s often not obviously. If no problems occur, then it can be seen as non relevant. But if any problem on compilation or linking is given, it is helpfully to know the configuration.

For that the gcc compiler can be checked and asked:

echo | gcc -xc++ -E -v -
echo | gcc -xc -E -v -
cpp -v /dev/null -o /dev/null
$ echo | gcc -Wp,-v -x c++ - -fsyntax-only

That are some commands showing settings for gcc, g++

example output:

$ $ echo | gcc -Wp,-v -x c++ - -fsyntax-only
bash: $: command not found
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/12"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/12/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/12
 /usr/include/x86_64-linux-gnu/c++/12
 /usr/include/c++/12/backward
 /usr/lib/gcc/x86_64-linux-gnu/12/include
 /usr/local/include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

Here maybe a better explanation

gcc -Q --help=target

produces list of options with enabled|disabled flag

4.4. Usual necessary project depending settings

4.4.1. Include paths

I recommend, use a well thought out file tree for your own headers, and include your own headers with slash in form

#include <mainSrc/headerY.h>

Then you see in the source code, it is a header from the project. Secondly name clashes are avoided.

Then you need only a include path relativ (recommended) from the working dir (it is the project folder on using an IDE, CodeBlocks) to your own sources:

-I../../../src/MyProject/cpp

presumed that the header file is found in

.../src/MyProject/cpp/mainSrc/headerY.h

or if you work more stronger, and you have a proper component oriented Working tree with component names really used in the sources (its similar Strong as package paths in Java):

-I../../../src

The include path only to your all sources,

#include <MyProject/cpp/mainSrc/headerY.h>

But this presumes, that exact this project tree structure is used, second level this project name, third level should be cpp, not other. It may be too strong.

emC headers

-I../../../src/src_emC/cpp
-I../../../src/src_emC/cpp/emC

The header inluce in emC starts usual with

#include <emC/Ctrl/PIDf_Ctrl_emC.h>
#include <emC/Base/Math_emC.h>
#include <math.h>
#include <string.h>

But sometimes the emC/ is missing. More consequently (strong) the own header include should be written as:

#include <src_emC/cpp/emC/Ctrl/PIDf_Ctrl_emC.h>
#include <src_emC/cpp/emC/Base/Math_emC.h>

But then, for all applications it is dedicated, that the src_emC/cpp directory tree need to be used. For common usage of emC, it is too strong.

include with <…​> or "…​"

The #include "header.h" allows including as relative paths from the current source. It is especially for header immediately beside the sources. But because in the past usage of this <…​> or "…​" are sometimes confused, …​ the 'official' docu ("K&R") says: "use <…​> for system headers", some compiler does not really differ between <…​> and "…​".

Specific headers in own sources, which presents own but components or other modules, should be handled also as "system header" in K&R words, hence written in <…​>. That is the consequent approach.

"K&R" is the synonym for the great book "The C Programming Language" from Brian W. Kerninghan and Dennis M. Ritchie from the 1980th of the foreigh century.

Specific headers:

But, be flexible. Some included files are not strong affiliated to one component. It should be taken as found in specified directories. For the file:///home/D/vishia/emc framework it is for example:

#include <compl_adaption.h>
#include <applstdef_emC.h>

The first include file should be found in a specific operation system and compiler depending directory. For this include:

-I../../../src/src_emC/cpp/emC_srcOSALspec/os_LinuxGcc

The second include file should be contain the project specfic settings, hence found in the project’s directory, but without path before. For that you must include:

-I../../../src/MyProject/cpp/projectSettings

if this file is really stored under

.../src/MyProject/cpp/projectSettings/applstdef_emC.h

Then also only a few files are found in this specialized directory, which avoids clashes.

4.4.2. Libraries

-lpthread -lm

Libraries are written very short in the option, lib and .a is omitted. The libraries included here are

  • libpthread.a for all thread operations using pthread

  • libm.a it is the math library.

4.6. 64 bit or 32 bit architecture

-m32

as flag for gcc switches to 32 bit compilation/linking.

But then:

Libraries are missing. Todo yet not clarified.

5. CodeBlocks

CodeBlocks is pre-tuned for GCC compilation, but some should be done or checked before first usage.

5.1. Setup GNU GCC

Menu "Settings-Comiler", select "GNU CCC Compiler (default)"

Let usual all fields empty, because they can be set as project specific options.

But select in tan "Toolchain executable":

  • Compller: gcc (here g++ may be possible, but it is experience use gcc)

  • C++ Compiler: g++

  • Linker for dynamic libs: g++ (this is pre-set)

  • Linker for static libs: g++ (instead of ar or gcc)

This last option is important to force the C++ compiled sources with C++ linkage. Elsewhere linker errors remain, because per default gcc is called as linker.

For compilation in the compiler flags -x c++ is given to force C++ compilation with gcc, see next:

5.2. Project build options

On a created or given project in Workspace, the right mouse context menu, and then "Build options…​" opens the same as "Properties…​" and then in the Properties dialog "Project/target options" selecting the button right bottom [Project’s build options] opens the same dialog.

Attention, select the correct Project (top) or possible targets which are usual "Debug" and Release". For test of sources on PC which are prepared to use on embedded control, usual "debug" is sufficient, but you can compile also for different debug opportunities. But let the target options unchanged (nothing set), and do concentrate on Project options for include etc, see next:

5.3. c files beside h file

First activate anyway the check box menu "Project - Project tree" and then

[x] Display folders as on disk

Deactivate the check box

[ ] Categorize by file types.

If this check box is activated, then it dispersed between c and h file, as it is known also from some other IDEs. But why this is bad?

Disperse between c and h files is then useful, if you haven’t a folder structure ("folders as on disk") in the project, and the h files are usual interfaces to libraries. This is a typical situation on PC application development in the 1980th of the foreign century. Using of libraries have the advantage, that compile time should be saved, the own application has only a few files, based of library functions.

For software development on PC for embedded control, libraries are often not helpful, and on the other hand, the compilation needs very less time as in the 1080th. Because of that header files and its affiliated c files comes together. More as that, todays modular design suggest one header to one implementation file. And that’s why they should be found side by side in the same tree folder.

5.4. Libraries for old compilation ??

Problem on my Linux instalation there are two different installations:

  • /usr/lib/x86_64-linux-gnu/ and /usr/include/

This seems to be oriented to traditional C language

  • /usr/include/x86_64-linux-gnu/c/12` and `/usr/include/c/12

The last one is used per default from gcc, and seems to be C++ oriented.

I don’t know which installation of gcc has produced the one and the other directory tree. But using the first one as compiler settings with the following libraries_

-static-libstdc++
-static-libgcc

also with option

-m32

for 32 bit (instead 64 bit) application has forced yet not solved linker problems, todo see in future.

6. compare and swap