Pages

Showing posts with label C. Show all posts
Showing posts with label C. Show all posts

Thursday, February 11, 2021

Fedora 33 : Meson build system.

Meson is a build system that is designed to be as user-friendly as possible without sacrificing performance. The main tool for this is a custom language that the user uses to describe the structure of his build. The main design goals of this language has been simplicity, clarity and conciseness. Much inspiration was drawn from the Python programming language, which is considered very readable, even to people who have not programmed in Python before., see the official webpage.
Let's test with an simple example on Fedora 33 distro.
First step, install this tool with DNF tool.
[root@desk mythcat]# dnf search meson
Last metadata expiration check: 2:20:41 ago on Thu 11 Feb 2021 08:39:26 PM EET.
============================== Name Exactly Matched: meson ==============================
meson.noarch : High productivity build system
[root@desk mythcat]# dnf install meson.noarch 
...
Installed:
  meson-0.55.3-1.fc33.noarch               ninja-build-1.10.2-1.fc33.x86_64              

Complete!
The next step is to create a C file with a simple example and one with the build file:
[mythcat@desk ~]$ mkdir CProjects
[mythcat@desk ~]$ cd CProjects/
[mythcat@desk CProjects]$ vi main.c
[mythcat@desk CProjects]$ vi meson.build
The C example file named main.c has this source code:
#include 

//
// main is where all program execution starts
//
int main(int argc, char **argv) {
  printf("Hello there.\n");
  return 0;
} 
The build file named meson.build comes with this content:
project('tutorial', 'c')
executable('demo', 'main.c') 
Use the meson with setup builddir and compile to build executable and run it.
[mythcat@desk CProjects]$ meson setup builddir
The Meson build system
Version: 0.56.2
Source dir: /home/mythcat/CProjects
Build dir: /home/mythcat/CProjects/builddir
Build type: native build
Project name: tutorial
Project version: undefined
C compiler for the host machine: cc (gcc 10.2.1 "cc (GCC) 10.2.1 20201125 (Red Hat 10.2.1-9)")
C linker for the host machine: cc ld.bfd 2.35-18
Host machine cpu family: x86_64
Host machine cpu: x86_64
Build targets in project: 1

Found ninja-1.10.2 at /bin/ninja
[mythcat@desk CProjects]$ cd builddir/
[mythcat@desk builddir]$ ls
build.ninja  compile_commands.json  meson-info	meson-logs  meson-private
[mythcat@desk builddir]$ meson compile
Found runner: ['/bin/ninja']
ninja: Entering directory `.'
[2/2] Linking target demo
[mythcat@desk builddir]$ ls
build.ninja  compile_commands.json  demo  demo.p  meson-info  meson-logs  meson-private
[mythcat@desk builddir]$ ./demo
Hello there.
You can see this run well.

Tuesday, September 15, 2020

Fedora 32 : Can be better? part 009.

The Fedora distro will be better if the development team will come with useful, accurate, and up-to-date information. A very simple example is C and C ++ programming and more precisely how to build programs and packages. Let's take a simple example of creating interfaces with GTK. Let's take a simple example of creating interfaces with GTK that require knowledge of the GCC compiler. First I install gtk3-devel package:
dnf install gtk3-devel 
The Fedora team come with a group install with many feature.
#dnf -y groupinstall "Development Tools"
I test with these examples:
#include 

int main(int   argc,
     char *argv[])
{
  GtkWidget *window;
    
  gtk_init (&argc, &argv);
    
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Hello World");
  gtk_widget_show  (window);
    
  gtk_main ();
    
  return 0;
}
This create a simple window with Hello World title.
#include 

static void on_window_closed(GtkWidget * widget, gpointer data)
{
    gtk_main_quit();
}

int main(int argc, char * argv[])
{
    GtkWidget * window, * label;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    g_signal_connect( window, "destroy", G_CALLBACK(on_window_closed), NULL);

    label = gtk_label_new("Hello, World!");

    gtk_container_add(GTK_CONTAINER(window), label);

    gtk_widget_show(label);
    gtk_widget_show(window);

    gtk_main();

    return 0;
}
This is the same example but you will see a label with te text Hello, World!.
The last example is more complex and involves the use of signals attached to the close button and the OK button.
The main window contains three labels with my name and an editbox in which you have to enter my nickname mythcat or something else.
#include 

const char *password = "mythcat";

// close the window application 
void closeApp(GtkWidget *widget, gpointer data)
{
    gtk_main_quit();
}

// show text when you click on button 
void button_clicked(GtkWidget *button, gpointer data)
{
    const char *password_text = gtk_entry_get_text(GTK_ENTRY((GtkWidget *)data));

    if(strcmp(password_text, password) == 0)
        printf("Access granted for user: \"%s\"\n",password);
    else
        printf("Access denied!\n");
 
}

int main( int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *label1, *label2, *label3;
    GtkWidget *hbox;
    GtkWidget *vbox;
    GtkWidget *ok_button;
    GtkWidget *password_entry;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_window_set_title(GTK_WINDOW(window), "Labels, password with one button and layout");
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);

    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(closeApp), NULL);

    label1 = gtk_label_new("Catalin");
    label2 = gtk_label_new("George");
    label3 = gtk_label_new("Festila");

    password_entry = gtk_entry_new();
    gtk_entry_set_visibility(GTK_ENTRY(password_entry), FALSE);
    ok_button = gtk_button_new_with_label("OK");
    g_signal_connect(G_OBJECT(ok_button), "clicked", G_CALLBACK(button_clicked),password_entry);

    hbox = gtk_box_new(FALSE, 1);
    vbox = gtk_box_new(TRUE, 2);

    gtk_box_pack_start(GTK_BOX(vbox), label1, TRUE, FALSE, 5);
    gtk_box_pack_start(GTK_BOX(vbox), label2, TRUE, FALSE, 5);
    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, TRUE, 5);
    gtk_box_pack_start(GTK_BOX(hbox), label3, FALSE, FALSE, 5);
    gtk_box_pack_start(GTK_BOX(vbox), ok_button, FALSE, FALSE, 5);
    gtk_box_pack_start(GTK_BOX(hbox), password_entry, TRUE, FALSE, 5);
    gtk_container_add(GTK_CONTAINER(window), hbox);

    gtk_widget_show_all(window);

    gtk_main();

    return 0;
} 
The result can be seen in the following image:

I put the source code for the last example in a test.c file and compiled it like this:
[mythcat@desk ~]$ gcc test.c $(pkg-config --cflags --libs gtk+-3.0) -o test
[mythcat@desk ~]$ ./test

Friday, June 15, 2018

Fedora 28 : ARM programming and testing .

This is a simple tutorial about ARM programming and QEMU:
The test.c program is this :
volatile unsigned int * const UART0DR = (unsigned int *)0x101f1000;
 
void print_uart0(const char *s) {
 while(*s != '\0') { /* Loop until end of string */
 *UART0DR = (unsigned int)(*s); /* Transmit char */
 s++; /* Next char */
 }
}
 
void c_entry() {
 print_uart0("Hello world!\n");
}

Using volatile keyword is necessary to instruct the compiler that the memory pointed.
The unsigned int type enforces 32-bits read and write access.
The QEMU model like in a real system on chip the Transmit FIFO Full flag must be checked in the UARTFR register before writing on the UARTDR register.
Create the startup.s assembler file:
.global _Reset
_Reset:
 LDR sp, =stack_top
 BL c_entry
 B .
Create the script linker named test.ld:
ENTRY(_Reset)
SECTIONS
{
 . = 0x10000;
 .startup . : { startup.o(.text) }
 .text : { *(.text) }
 .data : { *(.data) }
 .bss : { *(.bss COMMON) }
 . = ALIGN(8);
 . = . + 0x1000; /* 4kB of stack memory */
 stack_top = .;
}
Next step is the install of arm-none-eabi x86_64 tools :
[root@desk arm-source]# dnf install arm-none-eabi-gcc-cs-c++.x86_64 
Last metadata expiration check: 1:54:04 ago on Fri 15 Jun 2018 06:55:54 PM EEST.
Package arm-none-eabi-gcc-cs-c++-1:7.1.0-5.fc27.x86_64 is already installed, skipping.
Dependencies resolved.
Nothing to do.
Complete!
[root@desk arm-source]# dnf install arm-none-eabi-gdb.x86_64 
Last metadata expiration check: 1:54:48 ago on Fri 15 Jun 2018 06:55:54 PM EEST.
Package arm-none-eabi-gdb-7.6.2-4.fc24.x86_64 is already installed, skipping.
Dependencies resolved.
Nothing to do.
Complete!
[mythcat@desk arm-source]$ ll
total 12
-rw-rw-r--. 1 mythcat mythcat  60 Jun 15 20:28 startup.s
-rw-rw-r--. 1 mythcat mythcat 288 Jun 15 20:26 test.c
-rw-rw-r--. 1 mythcat mythcat 223 Jun 15 20:29 test.ld
Let's test this with qemu virtual tool ( use Ctr+A and X keys to stop qemu) :
[mythcat@desk arm-source]$ qemu-system-arm -M versatilepb -m 64M -nographic -kernel test.bin
pulseaudio: set_sink_input_volume() failed
pulseaudio: Reason: Invalid argument
pulseaudio: set_sink_input_mute() failed
pulseaudio: Reason: Invalid argument
Hello world!
QEMU: Terminated

Wednesday, September 19, 2012

Make one simple kernel module using C programming language.

Today I will try to explain how to make a kernel module.
Basically, a kernel module it's one piece of code that can be loaded and unloaded into the kernel.
You can read about kernel modules from here.
Now, let's try to make a simple kernel module.
Writing your own module can be done if you know some basic rules.
First, about how to use modules.
Suppose you have a new module named kernelmoduletest.
How to load the module.
Just use this command in your module kernel folder:
#insmod kernelmoduletest.ko
Next, test the kernel module messages.
This can be done with:
#dmesg | tail
Also, you need to remove the kernel module.
$ rmmod kernelmoduletest 
ERROR: Removing 'kernelmoduletest': Operation not permitted
This means you need to have superuser rights. So use the sudo or su command.
Then use the rmmod command.
Know how to make the kernel module skeleton.
This is not very simple because you need to know many things about kernel and programming.
But you can try the test with some simple example like this example:
Create the c file named kernelmoduletest and add this source code:
#include <linux module.h="">
#include <linux kernel.h="">

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("kernelmoduletest");
MODULE_AUTHOR("Catalin George Festila/mythcat/catafest");

int init_module() {

    printk(KERN_INFO "Now I will initialize my  kernel module\n");

    printk(KERN_INFO "Test: Hello World !\n");

    return 0;
}

void cleanup_module() {

    printk(KERN_INFO "Bad!... kernel module unloaded.\n");
}</linux></linux>
Make a new file named Makefile.
Add this to tell how to compile the kernel module.
obj-m += kernelmoduletest.o
all:
 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Compile your kernel module
Just use make command.
# make
...
  Building modules, stage 2.
  MODPOST 1 modules
...
make[1]: Leaving directory `/usr/src/linux-headers-2.6.31-14-generic'
If you test your module using the commands from the top of this tutorial, you can see that:

[14694.779227] Now I will initialize my  kernel module
[14694.779233] Test: Hello World !
[15049.825605] Bad!... kernel module unloaded.
If you have already made kernel modules and the subject it's interesting for you, send me an email.
Thank you. Regards.