compiling for multiple OS's lazarus / 21-General ---------------------------------------------------------------------- petevick · 2024-03-10 07:25 Old timers on here may know about this, but for a relative newbie like myself who compiles for Linux and Windows, they might be unaware. Many times I've added a unit to the uses section only to get an error when compiling because it's only specific to Windows or Linux, then I came across {$IFDEF xxxx} - {$ENDIF}, and it all became easy. The following example shows how it can be used for uses section...... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i interface {$IFDEF Linux}uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,  Contnrs, LCLType, BCTypes, process;{$ENDIF} {$IFDEF WINDOWS}uses  Classes, SysUtils, Forms, Controls, Dialogs, Graphics, StdCtrls, ExtCtrls,  Contnrs, LCLType, BCTypes, process, jwatlhelp32, WinDirs, Registry;{$ENDIF} The same structure can also be applied to sections of OS specific code as well. I'me sure the above code could be written in various ways, but this works for me. Hopefully this might be useful to someone. ---------------------------------------------------------------------- paweld · 2024-03-10 07:44 If I can such a comment: there is no need to repeat common parts of the code, because in my opinion it then becomes less readable.For the attached example, you can do just that:Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,  Contnrs, LCLType, BCTypes, process  {$IFDEF WINDOWS}  , jwatlhelp32, WinDirs, Registry  {$ENDIF}    ; ---------------------------------------------------------------------- jollytall · 2024-03-10 07:46 Yes, itis a possibility. However with this logic, you could write two separate programs that defeats the purpose of write once, compile anywhere. One would normally write what is the same for any operating system, only once and put those into the {if} that is indeed OS specific. Most of the standard units are not. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,  Contnrs, LCLType, BCTypes, process {$IFDEF WINDOWS}  ,  jwatlhelp32, WinDirs, Registry{$ENDIF}; Also in some cases you can use {$else} if that is easier. (I do not see why you had Graphics and Dialogs in different order. I do not recall any reason for it.) ---------------------------------------------------------------------- TRon · 2024-03-10 08:00 I know my programming is flawed but, at least I have the courtesy: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  sysutils,  {$if defined(haiku)}  hai_ints  {$elseif defined(OS2)}  os2_ints  {$else}    {$fatal platform not supported}  {$endif}  ; ---------------------------------------------------------------------- petevick · 2024-03-10 08:45 As I said.... Quote from: petevick on March 10, 2024, 08:25:11 amI'me sure the above code could be written in various ways, but this works for me. Hopefully this might be useful to someone. ---------------------------------------------------------------------- Thaddy · 2024-03-10 09:11 Yes there is nothing wrong in doing it your way, but note that the {$if Defined()} and/or {$if declared()}  syntax will soon prove to be more flexible because you can have multiple conditions in the same define using boolean operators like and, or and not. When your defines run out of control that is. In addition, there is {$ifopt} which is highly useful to determine the compiler options - only the short notation - with which a program is to be compiled and {$undef} which lets you undefine a previously defined condition. Just for completeness. Your way of working will work in most simple cases and there is nothing wrong with that. ---------------------------------------------------------------------- MarkMLl · 2024-03-10 10:02 Quote from: Thaddy on March 10, 2024, 10:11:34 amYes there is nothing wrong in doing it your way, but note that the {$if Defined()} and/or {$if declared()}  syntax will soon prove to be more flexible because you can have multiple conditions in the same define using boolean operators like and, or and not. When your defines run out of control that is. In addition, there is {$ifopt} which is highly useful to determine the compiler options - only the short notation - with which a program is to be compiled and {$undef} which lets you undefine a previously defined condition. Just for completeness. Your way of working will work in most simple cases and there is nothing wrong with that. With the caveat that when I last saw it discusses declared can't "reach inside" a class to determine whether a property or method is available. This probably doesn't matter much for something gross like an OS dependency, but does if trying accommodate different library versions etc. Apart from that, I find doing this style useful: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$undef specialosstuff }uses  sysutils,  {$if defined(haiku)}  {$define specialosstuff }  hai_ints  {$elseif defined(OS2)}  {$define specialosstuff }  os2_ints  {$endif}  ; {$ifndef specialosstuff }    {$fatal platform not supported}{$endif }  Hope that makes sense, have to go out /now/... MarkMLl ---------------------------------------------------------------------- Dzandaa · 2024-03-10 10:45 Hi, I also create my programs compatible with Windows, Linux and MacOS. In Option->Paths I activate Debug and Release mode, then in "Target file name (-o)" For debug: bin\Debug\$(TargetCPU)-$(TargetOS)\TestProj For Release: bin\Release\$(TargetCPU)-$(TargetOS)\TestProj Thus, programs are created in different directories depending on the O.S. and the type debug or Release. B-> ---------------------------------------------------------------------- TRon · 2024-03-10 19:53 Quote from: MarkMLl on March 10, 2024, 11:02:53 amApart from that, I find doing this style useful: Hope that makes sense, have to go out /now/... That makes absolutely sense in case you want your code to actually be ported to/for another platform and make the person doing so /very/ happy Thank you for the fine-grained example. ---------------------------------------------------------------------- MarkMLl · 2024-03-11 07:48 Quote from: TRon on March 10, 2024, 08:53:09 pmThat makes absolutely sense in case you want your code to actually be ported to/for another platform and make the person doing so /very/ happy Thank you for the fine-grained example. Somewhat less rushed now. The particular place where I find that style useful is when handling multiple widget sets, hence something like Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i (*$IFDEF DELPHI *)          widV= 'Linked with the Delphi widget set';  (*$DEFINE WIDGETSET *)(*$ENDIF        *)(*$IFDEF LCLWIN *)          widV= 'Linked with the Windows widget set';  (*$DEFINE WIDGETSET *)(*$ENDIF       *)...(*$IFDEF WIDGETSET *)          about6= widV;(*$ELSE         *)          about6= '';(*$ENDIF        *)  Now it would be possible to do that in other ways, for example by defining widV as a macro (ignoring the squeals of indignation from the core team) or by using declared(widV). However FPC's macro facility is painfully incomplete, and TBH I'm uncomfortable with mixing in- language declarations (i.e. that a constant exists) with out-of- language directives (i.e. declared()): doing so is obviously extremely useful but the degree to which it's implemented and the precise semantics vary wildly across language families and implementations. Hence my preferred style is to keep it within what I choose to call the directive domain (others might prefer "preprocessor" or similar), i.e. strictly outside the syntax of the language. And that works particularly well for things that are related but disjoint, i.e widget set or OS names as distinct from the continuum of compiler versions. MarkMLl ---------------------------------------------------------------------- Seenkao · 2024-03-11 10:32 Лучше всего общие модули писать отдельно, а зависящие от платформы отдельно. Программист будет видеть, если решит добавить поддержку дополнительных операционных систем, какие модули уже добавлены и в какую сторону смотреть, чтоб заменить те модули, которые выделены отдельно для определённой операционной системы. К сожаленью, для мобильных платформ это работать корректно не будет, если вы захотите использовать LCL. ---------------------------------- Google translate: It is best to write general modules separately, and platform-dependent ones separately. The programmer will see, if he decides to add support for additional operating systems, which modules have already been added and which direction to look in order to replace those modules that are allocated separately for a specific operating system. Unfortunately, this will not work correctly for mobile platforms if you want to use LCL. ---------------------------------------------------------------------- MarkMLl · 2024-03-11 11:07 Quote from: Seenkao on March 11, 2024, 11:32:48 amIt is best to write general modules separately, and platform-dependent ones separately. The programmer will see, if he decides to add support for additional operating systems, which modules have already been added "The road to Hell is paved with good intentions". For example, it's not possible to make the build process depend on whether a particular file exists on the filesystem, i.e. on whether developers have actually written a library which can be used or whether a particular variant of a project has been shipped with a specific support library. There's possibly ways round that if building from a makefile or by using the "run before" facility of a Lazarus project, hence something like Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  SysUtils, Classes {$include other_library_tree.inc } ;  I refuse to take responsibility for peoples' reactions when they read that... MarkMLl ---------------------------------------------------------------------- Seenkao · 2024-03-11 11:56 MarkMLl, надо понимать, что если человек полез в кроссплатформенную разработку, то зачастую он знает какие модули будут использоваться. Но так же надо понимать, что большинство новичков не знают даже основных используемых модулей. Потому что зачастую это делается автоматически и им не надо в это вникать. --------------------------- Google translate: MarkMLl, you need to understand that if a person gets into cross- platform development, then he often knows which modules will be used. But you also need to understand that most beginners do not even know the basic modules used. Because often this is done automatically and they don’t have to delve into it. ---------------------------------------------------------------------- MarkMLl · 2024-03-11 12:03 Quote from: Seenkao on March 11, 2024, 12:56:51 pmMarkMLl, you need to understand that if a person gets into cross-platform development, then he often knows which modules will be used. Perhaps if you'd told me that 50 years ago it might have been informative >:-) MarkMLl ---------------------------------------------------------------------- Seenkao · 2024-03-11 15:24 Quote from: MarkMLl on March 11, 2024, 01:03:33 pmPerhaps if you'd told me that 50 years ago it might have been informative >:-) Да, но вы не новичок в FPC/Lazarus. Я думаю большинство новичков вообще не задумываются даже об этом. А мы, как люди бывалые, о таких мелочах забываем... ----------------- Google translate: Yes, but you are not new to FPC/Lazarus. I think most beginners don’t even think about this at all. And we, as experienced people, forget about such little things... ---------------------------------------------------------------------- MarkMLl · 2024-03-12 07:09 Quote from: Seenkao on March 11, 2024, 04:24:22 pmYes, but you are not new to FPC/Lazarus. I think most beginners don’t even think about this at all. And we, as experienced people, forget about such little things... I am, indeed, not a newcomer. I'm tempted to call myself an oldleaver, but dread to think how Google Translate will handle it :-) Beginners quite reasonably expect that a facility will be represented by a single library and that they won't need to fiddle with names or paths to handle e.g. different widget sets. But somebody has to write that single library, which is where directives such as $ifdef and more-complex build systems come into play. MarkMLl