Difference between revisions of "Multiplatform Programming Guide"

From Free Pascal wiki
Jump to navigationJump to search
m
Line 5: Line 5:
 
==Introduction to Multiplatform Programming==
 
==Introduction to Multiplatform Programming==
  
==Porting process between Windows to Linux==
+
==Porting process between Windows and Linux==
 +
 
 +
===File system differences===
  
 
===On Linux there is no "application directory"===
 
===On Linux there is no "application directory"===
Line 13: Line 15:
 
Even if Application.ExeName could in fact know the directory where the file under execution is, that file could be a symbolic link, so you would get the directory of the link instead.
 
Even if Application.ExeName could in fact know the directory where the file under execution is, that file could be a symbolic link, so you would get the directory of the link instead.
  
So what to do? On Linux you should use two different places to store configurations and resource files:
+
So what should we do? On Linux you should use two different places to store configurations and resource files:
  
* A fixed privileged location for the executable and resource files witch will not change.
+
* Resource files (i.e. images, help files)
 +
 
 +
A fixed privileged location for the executable and resource files witch will not change.
  
 
This location can be something like: /usr/share/app_name or /opt/app_name
 
This location can be something like: /usr/share/app_name or /opt/app_name
Line 21: Line 25:
 
Most programs will be executed without root privileges and the fixed directory for a given application usually only available for the root user to write, so don't write on this directory. Only read information from it.
 
Most programs will be executed without root privileges and the fixed directory for a given application usually only available for the root user to write, so don't write on this directory. Only read information from it.
  
* The user's home directory
+
* Configuration files
 +
 
 +
You can use the GetAppConfigDir function from SysUtils unit to get a suitable place to store configuration files on different system. The function has one parameter, called Global. If it is True then the directory returned is a global directory, i.e. valid for all users on the system. If the parameter Global is false, then the directory is specific for the user who is executing the program. On systems that do not support multi-user environments, these two directories may be the same.
 +
 
 +
There is also the GetAppConfigFile witch will return an appropriate name for an application configuration file.
 +
 
 +
Here is an example of the use of those functions on a GNU/Linux system:
 +
 
 +
<pre>
 +
program project1;
 +
 
 +
{$mode objfpc}{$H+}
 +
 
 +
uses
 +
  SysUtils
 +
  { add your units here };
 +
 
 +
begin
 +
  WriteLn(GetAppConfigDir(True));
 +
  WriteLn(GetAppConfigDir(False));
 +
  WriteLn(GetAppConfigFile(True));
 +
  WriteLn(GetAppConfigFile(False));
 +
end.
 +
</pre>
 +
 
 +
And here is the output of the program:
 +
 
 +
<pre>
 +
/etc
 +
/home/felipe/project1
 +
/etc/project1.cfg
 +
/home/felipe/.project1
 +
</pre>
  
You can create a hidden folder on the user's home directory to store configurations and resource files that may change.
 
  
Directories whose name begin with a dot (.) are hidden, so you can create a hidden directory on a place like <i>/home/user_name/.app_name</i> and then store configuration files there.
+
You can notice that glocal configuration files are stored on the /etc directory and local configurations are stored on a hidden folder on the user's home directory. Directories whose name begin with a dot (.) are hidden on Linux. You can create a directory on the location returned by GetAppConfigDir and then store configuration files there.
  
 
==See Also==
 
==See Also==
  
 
* http://www.midnightbeach.com/jon/pubs/Kylix.html A guide for Windows programmers starting with Kylix. Many of concepts / code snipts apply on Lazarus.
 
* http://www.midnightbeach.com/jon/pubs/Kylix.html A guide for Windows programmers starting with Kylix. Many of concepts / code snipts apply on Lazarus.

Revision as of 02:51, 13 December 2005

This page is the start of a tutorial with regard to writing multiplatform applications on Lazarus. It will cover both the necessary precautions to ensure that a program can be easely ported and the porting process for an already existing program. I invite others to help improve the article.

Introduction to Multiplatform Programming

Porting process between Windows and Linux

File system differences

On Linux there is no "application directory"

One concern when porting applications between Linux and Windows is the file system. Many programmers are used to call ExtractFilePath(ParamStr(0)) or Application.ExeName to get the location of the executable, and then search for the necessary files for the program execution (Images, XML files, database files, etc) based on the location of the executable. This is incorrect in Linux. The string on ParamStr(0) may not only not contain the directory of the executable, as it also varies between different shell programs (sh, bash, etc).

Even if Application.ExeName could in fact know the directory where the file under execution is, that file could be a symbolic link, so you would get the directory of the link instead.

So what should we do? On Linux you should use two different places to store configurations and resource files:

  • Resource files (i.e. images, help files)

A fixed privileged location for the executable and resource files witch will not change.

This location can be something like: /usr/share/app_name or /opt/app_name

Most programs will be executed without root privileges and the fixed directory for a given application usually only available for the root user to write, so don't write on this directory. Only read information from it.

  • Configuration files

You can use the GetAppConfigDir function from SysUtils unit to get a suitable place to store configuration files on different system. The function has one parameter, called Global. If it is True then the directory returned is a global directory, i.e. valid for all users on the system. If the parameter Global is false, then the directory is specific for the user who is executing the program. On systems that do not support multi-user environments, these two directories may be the same.

There is also the GetAppConfigFile witch will return an appropriate name for an application configuration file.

Here is an example of the use of those functions on a GNU/Linux system:

program project1;

{$mode objfpc}{$H+}

uses
  SysUtils
  { add your units here };

begin
  WriteLn(GetAppConfigDir(True));
  WriteLn(GetAppConfigDir(False));
  WriteLn(GetAppConfigFile(True));
  WriteLn(GetAppConfigFile(False));
end.

And here is the output of the program:

/etc
/home/felipe/project1
/etc/project1.cfg
/home/felipe/.project1


You can notice that glocal configuration files are stored on the /etc directory and local configurations are stored on a hidden folder on the user's home directory. Directories whose name begin with a dot (.) are hidden on Linux. You can create a directory on the location returned by GetAppConfigDir and then store configuration files there.

See Also