Author Topic: hello world for linux in C++  (Read 4554 times)

0 Members and 1 Guest are viewing this topic.

Online IanB

  • Super Contributor
  • ***
  • Posts: 12368
  • Country: us
Re: hello world for linux in C++
« Reply #125 on: September 16, 2024, 06:31:58 pm »
Your language needs to have access to the low level instructions. This is hardware dependent. On x86 syscalls are called though the interrupt 0x80, on x64 there is a special instruction called "syscall". The arguments to the called function are passed in the registers. There are many sources for the syscall table, here is one https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

All low level library functions like read() or write() are just simple interfaces for those syscalls. You can do it all manually if you want to or if your language does not already have this list translated into a native to the language form.

In the very old days, this is what the BIOS provided (Basic Input Output System). These days what the BIOS used to provide is all abstracted away through device drivers, but operating systems still have to provide basic hardware access facilities for user programs to use.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 27919
  • Country: nl
    • NCT Developments
Re: hello world for linux in C++
« Reply #126 on: September 16, 2024, 06:34:26 pm »
that this is why the culture of the copy and paste programmer has arisen. I don't like just doing something because a web page tells me. We have an entire product that a now departed colleague designed in this way.

it is this product that I am now in a way trying to gain the skills to replace. I realize that programming takes years to learn properly despite a book on amazon claiming that you can learn python in a week and unlock huge salaries. but I seem to spend a lot of time just trying to make a start with the fundamentals.
IMHO the truth is somewhere in the middle. Personally I like to start with an example and improve / change it to my liking while looking up the language constructs being used. Along the way you figure out what is good and what is bad about the example and which language constructs would be a better fit. And if the example turns out to be utterly useless, find another example. That way you don't have to start from scratch understanding everything but gradually gaining more knowledge about a programming language while getting results.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 
The following users thanked this post: ralphrmartin

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11727
  • Country: us
    • Personal site
Re: hello world for linux in C++
« Reply #127 on: September 16, 2024, 06:38:06 pm »
Device drivers are still accessed though the same syscalls. That syscall list is all that Linux can do, there is no way to get more out of it. This includes all the hardware and driver access.
« Last Edit: September 16, 2024, 07:03:21 pm by ataradov »
Alex
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11727
  • Country: us
    • Personal site
Re: hello world for linux in C++
« Reply #128 on: September 16, 2024, 06:40:46 pm »
Personally I like to start with an example and improve / change it to my liking
This.

People like to shit on StackOverflow, yet it is extremely valuable resource. Sure, it includes a lot of garbage, but that garbage is also called out in the comments. So, as long as you are actually reading the discussion, you can extract a lot of value from SO.
Alex
 
The following users thanked this post: nctnico

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18031
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: hello world for linux in C++
« Reply #129 on: September 16, 2024, 06:54:00 pm »
... You can do it all manually ....
Why assembler, write everything in processor codes. I wrote a floppy disk driver in x86 codes. I keep this paper notebook and can take a photo if anyone doesn't believe me. So give me the Biggest Fool Award.

We will give you the award without the need for proof.
 

Offline Postal2

  • Frequent Contributor
  • **
  • Posts: 506
  • Country: ru
Re: hello world for linux in C++
« Reply #130 on: September 16, 2024, 07:05:14 pm »
If ataradov does write a program in machine code (as I did), he will have to additionally learn to knock on his head with the same empty sound as I can.
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11727
  • Country: us
    • Personal site
Re: hello world for linux in C++
« Reply #131 on: September 16, 2024, 07:08:15 pm »
I'm not into dick measuring contests, and the joke about writing things in machine code or scratching them with a needle on a surface of a hard drive ran their course 20+ year ago.

The assembly code I linked is not just to show how "cool" you are. This is something you have to do when porting a new language to Linux.
Alex
 

Offline Postal2

  • Frequent Contributor
  • **
  • Posts: 506
  • Country: ru
Re: hello world for linux in C++
« Reply #132 on: September 16, 2024, 07:30:11 pm »
... joke about writing things in machine code ...
I didn't have an assembler, so I entered the bytecode into the "hiew" program.
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11727
  • Country: us
    • Personal site
Re: hello world for linux in C++
« Reply #133 on: September 16, 2024, 08:09:44 pm »
Nobody cares. This is a waste of time.
Alex
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18031
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: hello world for linux in C++
« Reply #134 on: September 16, 2024, 08:23:09 pm »
... joke about writing things in machine code ...
I didn't have an assembler, so I entered the bytecode into the "hiew" program.

Why don't you create your own sad little thread all by yourself about how great you are, you can even troll yourself in it to your hearts content and leave us to get on with our business!
 

Offline Postal2

  • Frequent Contributor
  • **
  • Posts: 506
  • Country: ru
Re: hello world for linux in C++
« Reply #135 on: September 16, 2024, 08:37:34 pm »
... and leave us to get on with our business!
OK.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18031
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: hello world for linux in C++
« Reply #136 on: September 16, 2024, 08:41:48 pm »
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6863
  • Country: fi
    • My home page and email address
Re: hello world for linux in C++
« Reply #137 on: September 17, 2024, 05:58:35 am »
Simon, what you are experiencing is the exact situation I have mention I've observed: that it is more difficult for a Windows power user to learn Linux (or Mac, or any other OS) than it is for a complete newbie.  One has to first "unlearn", or learn to understand that some of their built-in assumptions are not universal and are instead specific to Windows only, before they can "learn the new stuff".

I've never said or intended it in any kind of derogatory way, it is just how it is.  If Linux was the popular one, it would be the exact other way around.  It is the same thing when learning a language when an adult: the first foreign language (not related to your native language) is the hardest, because you have to both learn how to learn a new language, and then learn the new language first.  The following ones, even if not related to the languages you already know, are comparably much easier, because you've already learned how to learn a new language.

(This does not apply to learning languages as a kid, because kids' brains have a specific language acquisition "mode" that adults don't tend to have; but looking at some language prodigies, their acquisition skills do seem awfully like what kids have, augmented with adult reasoning, logical capabilities, and memory management skills.)

I've never heard of a syscall interface.
Others have already talked about this above, so I should shut up.

However, I think I can describe the situation well starting back in the 8086 MS-DOS era, with references to connect to other stuff.  Apologies for repeating what has already been said; I just find this era, and how it affected what we have now in Linux, fascinating.

Syscall interface is another name for the Application Binary Interface between applications ("userspace") and the OS (kernel part, specifically).  We do use the term Application Binary Interface, or ABI for any interface between binary/machine code things, but for the specific one between an operating system and its applications, "syscall interface" is the most commonly used name.

Intel 8086 and compatibles have a dedicated instruction, int n, for software to trigger an interrupt.  n is an 8-bit value, with the smallest 8 or 16 reserved for specific interrupts, and with a couple of related instructions for breakpoints and such.  The interrupt table has 256 entries, so most of these were utterly unused – and were perfect for programs to call standardized routines in BIOS.  In fact, these interrupts, and the parameters they took in registers, were the DOS syscall interface.

My own introduction to these was via Ralf Brown's Interrupt List in 1988 or 1989.  It described all the interrupts available on MS-DOS and IBM compatible 8086/80186/80286/80386 BIOSes, plus many extensions like VESA VBE (which you could use in DOS to get SuperVGA graphics modes).

At the same time, in the Unix world, efforts for interoperability standards were heavily underway.  POSIX started in 1988.  Intel created iBCS so that the same 80386 binaries could run on different Unix variants.  RMS started the GNU project in 1983, founded Free Software Foundation in 1985, and the first release of GCC was in 1987.

The late 1980s and early 1990s were the era of the Unix Wars.  While BSD was much more popular at universities, many considered System V to be the "proper Unix"; but the USL-vs-BSD lawsuit meant BSD was still replacing the proprietary AT&T parts of it with its own during these times.  In the end, System V, especially System V Release 4.0 became the basis for interoperability among Unix variants.

Thus, when Linus developed Linux, he used the System V ABI for calling conventions, because it had just become the standard among Unix variants by 1991, and the GNU toolchain he used already supported that.

I believe the OSDev Wiki System V ABI page is the easiest collection point for various hardware details of that ABI.  On x86-64 aka AMD64 (PDF at gitlab.com), for example, it specifies that pointer and up to 64-bit integer arguments are passed (in order of left to right) in rdi, rsi, rdx, rcx, r8, and r9 registers, and any left over on the stack, and that r11 is a scratch register whose value is not saved or retained over a function call (or a syscall).  On AMD64, instead if int n, a dedicated syscall instruction is used for "calling" OS/kernel "functions". (These functions are also called "syscalls".  So, it means both the act of calling a function provided by the OS/kernel, and such functions themselves.)  Return values are passed in rax and optionally in rdx; that is, two separate integer or pointer values can be returned trivially from any function or syscall when using the System V ABI on AMD64.  (In comparison, on the original 8086/80386 System V ABI, all parameters were passed on stack, which was definitely not optimal.)

In Linux, the userspace-kernel ABI, the syscall interface, is very stable.  It is the internal kernel structures and function interfaces that they refuse to set in stone, because the kernel is much more flexible for development this way.  For out-of-tree driver developers and e.g. kernel Rust developers, this is a huge cause of annoyance.  Hell, even the excellent Linux Device Drivers, 3rd Edition book about Linux device driver development by Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman is out a bit wrt. in-kernel interfaces, as it refers to the state of the art for 2.6.10, and right now we're at 6.11.

When incompatible changes are done to the syscall interface – for example, a new parameter is added –, the existing versions are kept as-is, and a new syscall allocated for the new purpose.  I recommend looking at man 2 syscalls for a list with links to the C interface description, and the kernel version each syscall was introduced in.

It is quite possible to create applications using the syscall interfaces only and not use the standard C library at all.  As with embedded development, this then relies on the freestanding environment part of the C standards.  For the syscalls, I've written some very trivial syscall wrappers in extended inline assembly for GCC and Clang; the only downside is that they're both OS and architecture-specific.  There is much that I personally dislike about the standard C library, but like about the C language, so one of my long-term hobbies is examining what kind of a library replacement for the standard/POSIX C library would work better in practice.  With C23 and parameter array/length notation, it might even help programmers avoid buffer overrun bugs.

Because of Linux being developed using GNU toolchain and developers preferring the open standards like X/Open and Single Unix Specification (at the Open Group) and POSIX (also 2024 edition at the Open Group), it is very natural –– but possibly confusing! –– that many of the syscalls the Linux kernel provides match the POSIX System Interface functions (but see Introduction and General Information first).

And this finally ties into the Linux man pages project at man7.org by Michael Kerrisk.  He maintains these pages actively participating in the Linux kernel mailing lists, plus collects them from other sources (like the GNU C library).  Section 2 contains system calls and C functions that are simple wrappers around them, like open(), read(), write(), and close()Section 3 contains the rest of the standard C library calls, like fopen(), fread(), fwrite(), and fclose().  (The former are the low-level I/O functions where one must deal with e.g. short counts and interrupts, and the latter are the Standard C I/O functions, implemented by the C library using the former.)

Unlike many other man page collections, the Linux man pages list the Standard each function or syscall wrapper is based on, usually a short History list of related past standards that implemented the same, plus notes with e.g. any known Linux-specific details.  These are reliable; and when bugs or issues are found, Kerrisk is very friendly and appreciates fixes and contributions – I can say that from personal experience.

Side note: One of the things that really, really bug me about systems-level C (low-level libraries or services) programming outside Windows, is how few understand and use the POSIX interfaces.  A particular annoyance is whenever someone writes code using opendir(), readdir(), closedir() when nftw(), scandir(), and glob() are not only free for use (baked in to the base C library, no size cost or anything), but are also more robustly written than self-coded tree traversals, and should deal things like file and directory renames and moves during traversal.  A second one is arbitrary line length limitation due to the use of fgets(), when getline() and getdelim() automagically manage a dynamic memory buffer for you.
Simply put, there is a TON of extremely useful POSIX C functions baked in to the standard C libraries outside Windows that are underutilized, because MS never implemented them.

Anyway, a question at the end:

If you already know C, why do you go to C++ for GUI applications, instead of using GTK?

GTK has a pure C interface.  Granted, because it is object-oriented as UI toolkits tend to be, it can feel quite odd at first.  I recommend creating user interfaces either by hand or using Glade, and saving the interface as an .ui XML file.  In the C code, one uses GtkBuilder to instantiate the objects from the .ui file.  There are two separate approaches for attaching the callbacks –– the functions that e.g. clicking on a button causes to be called ––: relying on GModule to automatically match the names to same-named functions in the global scope, or using gtk_builder_add_callback_symbol() (or gtk_builder_add_callback_symbols()) to explicitly associate names with callback functions.
I'm not averse to using dedicated ELF sections to collect callback function name-to-function mappings, but it will not work for native Windows GTK apps.
Some dislike GTK, but to me, it is just another option for creating UIs.  Gtk and Qt are my go-to ones, but I'm not tied to either one.

Note that while GTK is associated with the GNOME project, you don't need GNOME to be able to use GTK.  You can easily run GTK apps on any desktop environments, including KDE (which uses Qt), by just installing the support libraries (and none of the desktop applications).  The same is true of all the toolkits, really.

If you want an example of GTK UI application, just say something simple it should do/have.  Because I haven't bothered to upgrade my Mint 20.3 yet, I'm using GTK 3, not GTK 4 yet.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18031
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: hello world for linux in C++
« Reply #138 on: September 17, 2024, 06:46:19 pm »
I am not one bit familiar with windows. The sum total of what I can do is write low level C for micro controllers. I abhor the HAL rubbish that manufacturers put out.

If I understand correctly the syscalls are ultimately what the standard C library interfaces to.

I thought it might be time to use C++ for the increased flexibility ultimately I will use what works. What I really lack is all the background stuff or setting up the environment and understanding how everything works. GTK? sure, whatever works, but I seem to just go in circles.
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11727
  • Country: us
    • Personal site
Re: hello world for linux in C++
« Reply #139 on: September 17, 2024, 06:58:22 pm »
If I understand correctly the syscalls are ultimately what the standard C library interfaces to.
Syscalls are OS APIs. And since you need your standard library to interact with the OS, it has to use OS APIs for that.

The fact that those syscalls look very close in functionality and arguments to the C library is just a side effect of the fact that both were designed and developed concurrently.


I thought it might be time to use C++ for the increased flexibility ultimately I will use what works. What I really lack is all the background stuff or setting up the environment and understanding how everything works. GTK? sure, whatever works, but I seem to just go in circles.
The best thing you can do is get all the libraries you can think of and build their examples. You will see how much code and effort it takes to achieve the result. Then you can pick whichever you like most and you will also have the starting point, since you already built the example. You can take it and expand it for your needs.
Alex
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18031
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: hello world for linux in C++
« Reply #140 on: September 17, 2024, 08:03:58 pm »
Yes i need to play with the fltk example when I get a minute. Then see if anything else is really worth it.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15318
  • Country: fr
Re: hello world for linux in C++
« Reply #141 on: September 17, 2024, 08:52:17 pm »
IMHO C++ is not worth the trouble for embedded dev on MCUs. (Of course, you'll always find die-hards who will swear by it.)
If you want to learn C++ for other purposes, fine, why not. But if you're looking to do desktop GUI stuff in C++ mainly to get proficient enough in C++ to reuse that skill for your embedded development, I don't think that's worth your time.

Time may be better invested in learning (if you're not comfortable with that yet, sorry if you are) how to install and use toolchains at a low level, with makefiles or Cmake (or whatever build system you like), not relying on complex IDEs and pre-digested environments. That will be much more invaluable in embedded contexts, again IMHO.

Just my 2 cents. Have fun with FLTK though.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6863
  • Country: fi
    • My home page and email address
Re: hello world for linux in C++
« Reply #142 on: September 17, 2024, 10:11:49 pm »
If I understand correctly the syscalls are ultimately what the standard C library interfaces to.
They are what all programming languages library functions ultimately interface to.  Some, like Python, are written on top of the standard C libraries; some, like Rust, use their own.  But yes, these are the only way an userspace process (an application or a service) can interface to things outside.

What I really lack is all the background stuff or setting up the environment and understanding how everything works.
I wish I could help, but I basically breathe this stuff nowadays, so cannot really tell what the best approach to get there is.  (I've got the same problem with programming guides: that phase was so long ago for me, and so much better stuff is now available, I simply don't have the context to recommend guides and tutorials.)

I, too, would recommend Mint over Debian or Ubuntu.  And if using Cinnamon Desktop, to install Synaptic package manager; it's a graphical interface to the same package repositories you can access via apt on the command line.  When you pick a package to be installed, it will automatically find all the dependencies, and ask whether it is okay to include them in the set.  The same interface allows you to uninstall (or purge, removing even configuration files) anything you've installed, but again dependencies may install a lot more than you intended, so always look at the additional changes; having any packages with -desktop in them means you're trying to delete something that (one of) the desktop environment requires.  After you've got a suitable set of changes, click on Apply.  It will give you a final opportunity to check what will be installed/removed/upgraded, before accepting.
Remember: it will not stop you from making your system unusable; it is up to you to be sensible about what you remove.

I think you'll get a pretty good base set of packages and libraries useful for C and C++ software development if you install binutils libc6-dev pkg-config libgtk-3-dev manpages manpages-dev gcc g++ clang make cmake glade libgladeui-dev libfltk1.3 libfltk1.3-dev qt5-default qtbase5-dev qtbase5-dev-tools qtchooser qtcreator qttools5-dev qttools5-dev-tools, but I probably am missing lots and lots.  build-essential is a metapackage that pulls in typical packages needed to build or rebuild Debian packages from sources.

In any case, you should use the package manager (like Synaptic) to look for the libraries you need, noting that if you want to compile programs to use said libraries, you typically need both the runtime parts (like say liblzma5 for XZ-format compression) and the development parts (liblzma-dev for aforementioned XZ-format compression library).  Just remember that you can only have one package manager application open at the same time. For example, if you have Synaptic running, command-line apt commands may fail.

If you run Mint etc. in a virtual machine, I recommend you checkpoint the VM before installing or uninstalling stuff.  That way, if you make a catastrophic mistake and remove your desktop environment or critical parts like Bash, you can always revert the VM to the checkpoint before any of the changes.  It is easy to accidentally slip and click Ok before you meant to, and install or remove things you didn't intend, so the VM checkpoint acts as a safety net; I recommend it.
« Last Edit: September 17, 2024, 10:14:05 pm by Nominal Animal »
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18031
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: hello world for linux in C++
« Reply #143 on: September 18, 2024, 06:31:32 am »
IMHO C++ is not worth the trouble for embedded dev on MCUs. (Of course, you'll always find die-hards who will swear by it.)
If you want to learn C++ for other purposes, fine, why not. But if you're looking to do desktop GUI stuff in C++ mainly to get proficient enough in C++ to reuse that skill for your embedded development, I don't think that's worth your time.

Time may be better invested in learning (if you're not comfortable with that yet, sorry if you are) how to install and use toolchains at a low level, with makefiles or Cmake (or whatever build system you like), not relying on complex IDEs and pre-digested environments. That will be much more invaluable in embedded contexts, again IMHO.

Just my 2 cents. Have fun with FLTK though.

I am looking to progress into C++ solely for the GUI stuff. I don't see how going to all the effort of learning a GUI is time well spent only to say great, now I can do C++ on MCU's. I need both C and C++ probably.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf