Recent

Author Topic: Advice needed on creating a cross platform run time .lpk [SOLVED]  (Read 705 times)

carl_caulkett

  • Hero Member
  • *****
  • Posts: 649
* Mac Mini M1
* macOS 14.6.1
* Lazarus 3.99
* FPC 3.3.1

I've just put together the latest version of my cross-platform (to be!) test app, which I have renamed using my old "ca" prefix from my Delphi days.

You'll see that the project includes a path setting enabling it to use the files in the "./camidi" folder.

I would much prefer to have this as a run-time package, but any attempt to use a "camidi.lpk" has failed. I can create and run the package, but whenI try to run the app, it falls over trying to find the "MacOsAll" file referenced in "caMidiMac" which is enclosed in a "uses {$IFDEF DARWIN}caMidiMac;{$ENDIF}" compiler directive in "caMidi".

The project in "caMacMidi 1.1.2.zip" compiles and runs, but if I try to move the "camidi" folder outside of the project folder, I just cannot seem to use it. If anyone has a few spare minutes, and knows about this kind of thing, can you tell me where I am going wrong? 🙏🏽
« Last Edit: October 07, 2024, 09:42:07 pm by carl_caulkett »
"It builds... ship it!"

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: Advice needed on creating a cross platform run time .lpk
« Reply #1 on: October 06, 2024, 03:33:37 pm »
Is MacOsAll needed in the main unit/form?
Where is this unit at all?

I am on Windows.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11930
  • FPC developer.
Re: Advice needed on creating a cross platform run time .lpk
« Reply #2 on: October 06, 2024, 04:08:59 pm »
To be honest I don't know exactly how this works either.

I use a package for a couple of own units and paths, and open it and compiler it once manually, and then adding it to the "Required Packages" of the project  (project inspector, the tree view near the bottom) works.

However if it hasn't been opened in the IDE recently or so, it seems to forget that it exists. That is somewhat logical, the IDE must know the path of the package of course, but I don't know how this is officially meant to work. I just double click the package, compile and then compiler the main program if directly compiling the main program doesn't work.

carl_caulkett

  • Hero Member
  • *****
  • Posts: 649
Re: Advice needed on creating a cross platform run time .lpk
« Reply #3 on: October 06, 2024, 06:33:05 pm »
Is MacOsAll needed in the main unit/form?
Where is this unit at all?

I am on Windows.

Well spotted! No, that MacOsAll can be (and has been!) removed and it still builds. The only Mac specific code is in caMidiMac.
"It builds... ship it!"

carl_caulkett

  • Hero Member
  • *****
  • Posts: 649
Re: Advice needed on creating a cross platform run time .lpk
« Reply #4 on: October 06, 2024, 10:19:50 pm »
It would help if Lazarus had a global unit search path that could be added to. Then I could just move the code which is currently in the "camidi" subfolder beneath my project folder, to somewhere else and have my project reference that code. The trouble is that I cannot find such a feature. If it is in there, it must be called something pretty counter-intuitive!

As I said before, all attempts to create a run time package containing the contents of the "camidi" folder, have failed because of the Mac specific code, even though I have gone to great pains to isolate the Mac specific code to one init, namely "camidica.pas".

If the worst comes to the worst, I suppose I could use the nuclear option, aka SymLinks, so that the project can be fooled into thinking that the "camidi" code is in a subfolder under the project folder, whereas it is elsewhere, shared amongst many projects! This, though, seems like a very non-Lazarus way of doing things, and, to be honest, I feel dirty for even thinking it ;)
"It builds... ship it!"

carl_caulkett

  • Hero Member
  • *****
  • Posts: 649
Re: Advice needed on creating a cross platform run time .lpk
« Reply #5 on: October 06, 2024, 11:18:26 pm »
I've just investigated the idea of having separate run-time packages: "caMidiMacRun", "caMidiLinuxRun", "caMidiWindowsRun". I've created "caMidiMacRun" and it includes all the files in the "caMidi" folder, but, for some reason the build is failing on the "MacOsAll" reference. Do I need to add something to the package's search path options to allow the use of "MacOsAll"?

I've attached the experimental version of the project with the failing package in the caMidi folder. Any idea, anyone? 🙏🏽

"It builds... ship it!"

TRon

  • Hero Member
  • *****
  • Posts: 3619
Re: Advice needed on creating a cross platform run time .lpk
« Reply #6 on: October 06, 2024, 11:24:12 pm »
It would help if Lazarus had a global unit search path that could be added to.
It is actually the FPC compiler that does that using the standard commandline options, see https://www.freepascal.org/docs-html/user/userap1.html (option -Fu).

Lazarus itself has specific project settings that allows the user to add custom parameters to a project (such as for example adding a custom directory to the unit search path).

If there is a (finished) package then such a package can be installed using the IDE and which allows for a project to include such a package (add dependency). the FPC compiler allows for something like that as well (for non GUI packages) using fppkg but hardly no-one seem to use that (and you can actually do without by adjusting the fpc.cfg file to include a 3th party package unit directory f.e. (using the -Fu option))
« Last Edit: October 06, 2024, 11:28:41 pm by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: Advice needed on creating a cross platform run time .lpk
« Reply #7 on: October 06, 2024, 11:43:00 pm »
You do not need to go for a package at all costs.
I keep my units in one (central) directory, and in Project Options > Compiler Options > Paths I add the path to this directory and to each of its sub-dirs.
This works for you, locally, but not the best way if you want to publish your code. In such case, you need sub-dirs in your project dir, like you already have.

As for the package, you need one OS-independent unit, and that is the one you'll refer to in the package file.
This unit will have uses section with IFDEF for the OS-es:
Code: Pascal  [Select][+][-]
  1. uses blah...blah units,
  2. {$IFDEF darwin}
  3. darwin_midi_unit,
  4. {$ENDIF}
  5. {$IFDEF windows}
  6. windows_midi_unit,
  7. {$ENDIF}
  8. .
  9. .
  10. .
After that, this unit should provide the API (procedures, functions etc.) to the app, and the sub-units (darwin_midi_unit, windows_midi_unit etc) should provide the underlying functions used by this main unit. In the best case, all the underlying units would have the same-named procedures, with the same argument types, so that you don't need to IFDEF in the main unit.
Example: main midi unit has procedure
Code: Pascal  [Select][+][-]
  1. procedure SetMidiBuffer(AVal: string);
  2. begin
  3.   SetMidiBufferInSubUnit(AVal);
  4. end;
and your both darwin_midi_unit and windows_midi_unit have the procedure SetMidiBufferinSubUnit(AVal: string), but each unit with its own code that is OS-specific.
The IFDEFs are respected at installing the package in Lazarus, so the compiler will not complain about windows_midi_unit if you install the package on MacOS.

carl_caulkett

  • Hero Member
  • *****
  • Posts: 649
Re: Advice needed on creating a cross platform run time .lpk
« Reply #8 on: October 06, 2024, 11:48:06 pm »
I've solved the problem, and, in the end, the solution was ridiculously easy. I moved the "caMidi" folder out of the project folder to a location parallel to my project folder. Then all I had to do was to add the non-os-specific units to the Files section of my project. It builds and runs, yay  :D If I ever choose to distribute the "camidi" package (once it's grown to be a bit more functional, it'll still be a bit of a faff to install, but at least being in one place solved the maintainability problem.

I have to thank Bobby100 who answered me in the other thread on this subject. He mentioned the 'PSS-Revive" project which I git cloned. I didn't get a chance to run the project because there were too many 3rd party components that I couldn't find, and the projecy seemed to be for 32 bit systems? The important thing I did notice was the use of the units in the "../units" folder ;)
« Last Edit: October 06, 2024, 11:51:39 pm by carl_caulkett »
"It builds... ship it!"

carl_caulkett

  • Hero Member
  • *****
  • Posts: 649
Re: Advice needed on creating a cross platform run time .lpk
« Reply #9 on: October 06, 2024, 11:50:35 pm »
You do not need to go for a package at all costs.
I keep my units in one (central) directory, and in Project Options > Compiler Options > Paths I add the path to this directory and to each of its sub-dirs.
This works for you, locally, but not the best way if you want to publish your code. In such case, you need sub-dirs in your project dir, like you already have.

You post arrived while I was posting my message! But thanks very much, it's a solution I can work with ;)
"It builds... ship it!"

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: Advice needed on creating a cross platform run time .lpk
« Reply #10 on: October 06, 2024, 11:56:37 pm »
I have to thank Bobby100 who answered me in the other thread on this subject. He mentioned the 'PSS-Revive" project which I git cloned. I didn't get a chance to run the project because there were too many 3rd party components that I couldn't find, and the projecy seemed to be for 32 bit systems? The important thing I did notice was the use of the units in the "../units" folder ;)
Glad you solved your problem. About PSS-Revive and 32-bit - you need to select the target build (Gear with key icon left to Play/Run icon) first. The last one that I've built was for 32-bit Windows, and that's what is left selected there.

carl_caulkett

  • Hero Member
  • *****
  • Posts: 649
Re: Advice needed on creating a cross platform run time .lpk [SOLVED]
« Reply #11 on: October 07, 2024, 05:57:24 pm »
I've used exactly the same technique for my main app, "OsmosePresets" as in the test app, previously discussed in this thread. As soon as I try to build the app, after adding the "camidi.pas", "camidiintf.pas" and "camiditypes.pas", I'm getting the following build errors...
Code: Text  [Select][+][-]
  1. Debug:   "_MIDIObjectGetStringProperty", referenced from:
  2. Debug:       _CAMIDIMAC$_$TCAMIDIMAC_$__$$_GETDEVICES$TCAMIDIINOUT$TSTRINGS in camidimac.o
  3. Debug:   "_MIDIOutputPortCreate", referenced from:
  4. Debug:       _CAMIDIMAC$_$TCAMIDIMAC_$__$$_GETOUTPUTPORT$TSTRINGS$$LONGWORD in camidimac.o
  5. Debug:   "_MIDISend", referenced from:
  6. Debug:       _CAMIDIMAC$_$TCAMIDIMAC_$__$$_SENDMIDIPACKET$LONGWORD$LONGWORD$MIDIPACKET$TSTRINGS in camidimac.o
  7. Debug:   "_kMIDIPropertyName", referenced from:
  8. Debug:       _CAMIDIMAC$_$TCAMIDIMAC_$__$$_GETDEVICES$TCAMIDIINOUT$TSTRINGS in camidimac.o
  9. Error: ld: symbol(s) not found for architecture x86_64
  10. Error: Error while linking
  11.  

As far as I can tell, I'm doing exactly the same as in the previous test project...

« Last Edit: October 07, 2024, 05:59:32 pm by carl_caulkett »
"It builds... ship it!"

carl_caulkett

  • Hero Member
  • *****
  • Posts: 649
Re: Advice needed on creating a cross platform run time .lpk [SOLVED]
« Reply #12 on: October 07, 2024, 06:10:23 pm »
In fact, I don't even have to touch the project structure to get these errors. Just adding "caMidi, caMidiIntf, caMidiTypes;" to the uses clause of my main form in "OsmosePresets" is enough to generate these errors!
"It builds... ship it!"

carl_caulkett

  • Hero Member
  • *****
  • Posts: 649
Re: Advice needed on creating a cross platform run time .lpk
« Reply #13 on: October 07, 2024, 07:54:50 pm »
Can I add to the search path on a file by file basis, by putting in a compiler directive, or something similar?
"It builds... ship it!"

carl_caulkett

  • Hero Member
  • *****
  • Posts: 649
Re: Advice needed on creating a cross platform run time .lpk
« Reply #14 on: October 07, 2024, 08:50:02 pm »
I sorted it by changing the uses clause of my macOS specific code to...
Code: Pascal  [Select][+][-]
  1. uses
  2.   Classes, SysUtils, caMidiIntf, caMidiTypes,
  3.   {$IFDEF DARWIN}
  4.   {$LINKFRAMEWORK CoreMIDI}
  5.   MacOsAll,
  6.   CocoaAll,
  7.   {$ENDIF}
  8.   {$IFDEF LINUX}
  9.   {$ENDIF}
  10.   {$IFDEF WINDOWS}
  11.   {$ENDIF}
  12.   caHelper;
  13.  

The {$LINKFRAMEWORK CoreMIDI} directive seems to have been the key to the solution!

And, happily, both test app, and actual app now build and run  :)
"It builds... ship it!"

 

TinyPortal © 2005-2018