How To Install My C Program

cgiordan

New Member
Joined
Apr 8, 2020
Messages
1
Reaction score
0
Credits
0
Hi everyone, just want to preface this by saying I am a complete newbie here when it comes to Linux, so some of the most basic things about it... probably not there yet with the gurus unfortunately. A little info about me - I am an electrical engineer who primarily does software work these days (for the better part of 14 years in the field in automotive). I am used to doing a lot of C programming for MCUs (low-level firmware drivers and higher-level apps - and usually an integration into an RTOS of some fashion) and such, but this Linux thing is very new to me and I do have aspirations to become familiar enough with it to do great things in due time.

Regarding this request, I can create a simple "Hello World" program and all that fun stuff using gcc I installed on my PC (Mint v.19.3 distro), but I was curious how to get it installed like a package on my machine. Not looking to share it with the world or place it in some public repo - this is for learning at this point. I mean, it is simple enough to go into the directory where the executable is located and call it to make it print "Hello World", but getting more elaborate would be to have it contain an icon that can be clicked and executed.

I am way more used to the MS (Windows) way of life and their build tools - which I also have created SW distributions to be placed in a system via installer. I gather it is different here in Linux.. I have done some 'apt-get' type stuff such as installing my gcc compiler off the bat. Either way, jut not too sure how to ask this question or if I am missing something here. I figure I need to start somewhere and just start asking questions so I can ask better ones later on.

Thanks in advance, treat me like someone who knows very little about this stuff I suppose and I can start to pick up the simple things first to build a conceptual foundation about the Linux world. I promise I will try :)

FWIW, this next part sounds scary, but I am supposed to start learning about the Yocto project at work (I.MX platform). I have built a "hello world" layer per the NXP docs using the whole bitbake stuff, so I am diving in deep here... You don't want to know what I am expected to deliver later on down the road, haha! I believe I have my work cut our for me, but hey, I love a challenge and I am sure that I have the aptitude to figure this stuff out. I've always compared learning to peeling an onion. Each time you take a layer off, a little crying happens! Well, I don't necessarily cry, but I do struggle from time to time - not afraid to fail here. Anyhow, thanks again!
 


Once you have built your application - installation is as simple, or as complex as you decide to make it.

At the simplest level - you could just write a couple of shell-scripts to copy your executable to a directory that is in the systems $PATH environment variable, or to remove it from the install location.
e.g. installing/uninstalling to/from a personal bin directory, or /usr/bin/, or /usr/local/bin/ etc.
I'll talk more about these destinations shortly....

A slightly more elaborate way would be to add "install" and "uninstall" targets to the makefile for your program that contain the commands to copy/remove relevant files to/from a directory in $PATH. Then you can use make install, or make uninstall from the source-tree of your program. This is probably the most traditional method.

At the most complex level - you could add a makepkg target to your make-file that will build a Debian package for your machine and then you could install/uninstall the .deb package using apt.
Personally, I’ve never really looked at packaging. Something I really aught to get onto at some point. But as I know nothing about it - I won't discuss it any further here!

For my personal pet projects - If it's just for myself, then rather than putting them in a main system directory like /usr/bin/, I tend to use my personal bin directory /home/username/bin/ and put any man pages in my personal man directory too - /home/username/man/man1/. I like to include man pages for my personal projects - even if they are only for my own use.

Or if I want my project to be available to other users - I'll put it in /usr/local/bin/ and put man-pages in /usr/local/share/man/man1/. (or man2/, or man3/ etc. depending on the sub-section the page belongs in). Again - I like to provide documentation for others who might end up using my projects.

As for the installation method - I'll usually either add install/uninstall targets to my programs makefile, or create an install/uninstall script. - again - depending on the project and what's involved.

Setting up a personal bin/ directory (and optional man directory)
To set up a personal bin directory - the first thing to do is check /etc/X11/Xsession, to see if it already has any hooks set up to detect a personal bin directory. Some distros do, others do not!

You can do that using this command:
grep -RiHn --color "HOME/bin:" /etc/X11/Xsession

If you see something like this:
/etc/X11/Xsession:65: PATH="$HOME/bin:$PATH"
- then your system already has the hooks and you're almost good to go.

If you do not see any output from grep, they aren't set up and you will need to edit the file as root using your preferred text editor.
In my case it's vim, so I'd use sudo vim /etc/X11/Xsession you use whatever editor you prefer to use and add the following lines of code:
Bash:
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi
Save that and you're almost ready to go.
NOTE: if the Xsession file does NOT exist - simply create it (as root) and add the above lines

The Xsession file is a startup used by X when the user logs in. The snippet above tests for the existence of a folder called bin in the current users home directory. If there is a bin directory present - it is prepended to $PATH. Meaning that any executables that are in that directory will be available as system executables.

Once you have ensured you have the hooks set up for a personal bin directory, the only things left to do are to run: mkdir ~/bin/ to create your personal bin directory.
NOTE: ~/ is a terminal shortcut/alias for /home/$USER/ (current users home directory - e.g. /home/yourusername/). So ~/bin/ equates to /home/yourusername/bin/

===============================
EDIT :
I forgot to include that you also need to put the hook into your .profile.
/home/yourusername/.profile
If the file doesn't exist - create it and copy paste the snippet of code in the code-block above.
The hook in the Xsession allow your desktop to run programs in your personal bin directory. But I forgot that you also need to put it the hook in .profile so $PATH is updated for any new terminal sessions too!
===============================

And optionally - if you want to use a personal man directory for man-pages, run:
mkdir -p ~/man/man1/. I think man is usually set up to check for a personal man directory anyway, so there shouldn't be any other setup required. Again - I like to include man-pages for my projects - even if they are only for my use.

The only other thing to do now is to log out, and log back in again. When you log back in - the hooks in /etc/X11/Xsession will detect your personal bin directory and add it to $PATH.

From then on - you can copy executable files or scripts into /home/yourusername/bin/ and execute them from anywhere in the terminal. And because the $PATH was modified at the Xsession level - you should also be able to run your programs from any graphical or text-based launchers/runners that you have installed on your system too.
e.g. Any applications that are similar to the windows desktop's "run" command, or dmenu.

It won't appear in any of the graphical menus. To do that you'd need to add a .desktop file (more on that later)

If you added a personal man directory - you can also copy any man pages for your projects there and then you can use the man command from anywhere in the terminal to view them. And again, I got you to set up a directory for section 1 man pages, if you need to put pages in any other section, create the appropriate sub-directory for the section in ~/man/.
e.g. ~/man/man2, ~/man/man3 etc.

So with those directories set up - If you were in your programs source tree and you have a program called myprogram and a man page called myprogram.1
You'd copy myprogram to ~/bin/ and your man page myproject.1 to ~/man/man1/ like this:
Bash:
cp myprogram ~/bin
cp myproject.1 ~/man/man1/

Now you can run your program from anywhere in the terminal like this:
myprogram
And access the man page from anywhere in the terminal like this:
man myprogram

So that's how you'd set up and use a personal bin directory and a personal man directory.

And like I said - if you want to make the program and/or documentation available system wide - copy the program to /usr/local/bin and any man pages to the relevant sub-directory in /usr/local/share/man/ instead!

Creating a .desktop file and getting it into the system menu
In order to make your program accessible via an icon in your systems menu, you will need to create a .desktop file.

So for myprogram - assuming it is a terminal only program, you would open up your text editor and create a file called myprogram.desktop which would look something like this:
Code:
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Name=myprogram
GenericName=A description - e.g, System tool to do something
Comment=A desktop tooltip for your program
Type=Application
Icon=utilities-terminal
Categories=Utility;
Exec=/path/to/myprogram
Terminal=true

Save that somewhere in your projects source-tree and we'll copy it somewhere appropriate later.

NOTES:
Use the above as a rough guideline on how to create a .desktop file.
Adjust the content of the fields to match your program/project.
You might want to take a look at some of the other .desktop files in /usr/share/applications/ and see what settings some of those programs use. There are many additional fields available.
Also take a look at the Desktop Entry Specification at freedesktop.org

Analysing the example above:
The Encoding field is related to the encoding of the .desktop file
The Version field relates to which version of freedesktop.org's .desktop file specification we're using.

The line Exec= contains the path to the executable that will be ran when the desktop icon is clicked - So replace /path/to/myprogram with the absolute/fully qualified path to your program - so if you put it in your personal bin directory - change it to /home/yourusername/bin/myprogram (where yourusername is YOUR username and myprogram is the name of your program). Or if you made it system-wide and put it in /usr/local/bin/, change the entry to /usr/local/bin/myprogram

For the Icon= line - I have used a generic icon called utilities-terminal - which is available in most DE/WM's themes used for terminal based programs. If you want to use a different icon - you can either use the name of the icon, OR use /path/to/icon where /path/to/icon is the fully qualified path/filename for the icon you want to use.
Any custom Icons can be put into /usr/share/icons/

The Categories= line should be a semicolon ; delimited list of categories for your application - this will determine where the icon will appear in your DE/WM's menu. I've just put it in the "Utility" category for now. I think that will typically put it in the "Accessories" menu in the categorised graphical menu. Again - take a look at the freedesktop specs and the .desktop files for any similar applications you might have installed and decide which categories to put your application in.

The Terminal=true field - this one is important - because it marks your program as a terminal program and should cause the DE/WM to fire up your program in a new terminal.

Now you have created a .desktop file somewhere in the source-tree for your project - make sure it has standard 644 file permissions using chmod 644 yourprogram.desktop. The next step is to copy it somewhere.

If this is just for your personal use, you could simply copy it to your desktop directory
e.g.
cp yourprogram.desktop ~/Desktop/
And then you can double click the icon on your desktop to run your program, or by opening your file manager to your desktop diretory and clicking on the icon.

However - If you want it to appear in your systems graphical menu - you can copy the .desktop file to ~/.local/share/applications/
e.g.
cp yourprogram.desktop ~/.local/share/applications/
And then it will only be available in your menu - it won't be available for other users.

or for a system-wide installation, you should copy it to /usr/share/applications/ using sudo.
e.g.
sudo cp yourprogram.desktop /usr/share/applications/
Then your program will be available to ALL users.

NOTE:
In my example .desktop file - it will most likely appear in the "Accessories" section in most desktop environments. But don't quote me on that - because I use a tiling wm with no graphical menu.

Also - once upon a time, for most DE's/WM's - you used to have to run various additional tools in order to get the system menu to update, but nowadays I think most DE's and WM''s automatically update the menu when you add a new .desktop file to either ~/.local/share/applications/ or to /usr/share/applications/. But again - don't quote me on that because I don't use a normal DE/WM. There may be some DE's WM's that require you to take additional steps in order to update the system menu.

One other thing - when you run your program via a desktop icon - you might find that a window pops up and disappears, or you might see nothing but a strange flash.
If this happens - the window is popping up and then immediately closing as soon as your program has finished.
To work around this issue, change the Exec= field in your .desktop file to this:
Code:
Exec=xterm -e '/path/to/executable;read -p "press any key to  continue..." -n1 -s'
Substitute /path/to/executable with the path to your executable.
What this does is fires up xterm, runs your program and then gets the shell to wait for the user to press any key.
xterm is a terminal emulator that is usually installed by default on most, if not all Linux distros. If you don't have xterm installed, then use whatever terminal you prefer. But you'll need to look up the appropriate parameters to pass to it!
But this will prevent the terminal window from closing as soon as your program has finished.

And I think that's about it!
Outside of packaging - that's pretty much a complete guide to installing and running your own executables on linux.

Let me know if you have any questions!
 
Last edited:


Top