Share code between projects

Using remobjects c#, does anyone know how code can be shared between projects.

I’ve created a class library and added it as a reference to my android and osx project but i cant access the classes from my library.

If you want to share code between different platforms you can add 1 file to multiple projects (when in the Add Existing File dialog, use the “Add As Link” option under the “Add” button). So say you have 3 projects, one for android, one for .net and one for osx you could have a layout like:

  • Android\MyProject.hydrogene<< these use linked files
  • iOS\MyProject.hydrogene<< these use linked files
  • Net\MyProject.hydrogene << these use linked files
  • Common\*.pas << shared files here

If you modify the main class file, the changes wont be replicated on other projects.

they will if you use Add As Link:

then VS won’t copy the file but use a relative file path.

Thanks. Would there be support for class library in the future?

Not sure what you mean there. You can do the same kind of thing with a class library (3 class libraries for each of the 3 platforms). A class library is really a .net only concept for a dll, on java it’s a .jar and osx has static and dynamic libraries.

You can share a lib between multiple apps on one platform, or share code between platforms, but not share one lib between different platforms

What Project Type would you recommend for the “Common” project in your above example ?

Without a project, creating new, common code files is a PITA. There are no templates when creating new files via “File -> New…” as opposed to when using “Add New Item”. And when using “Add New Item”, the newly added item obviously isn’t added as a link.

As far as I can see, this means having to create files outside of Visual Studio and then adding them (as links) to projects. When you have multiple platforms and multiple projects per platform (Free version + Pro version) this quickly becomes unwieldy and error prone.

There doesn’t appear to be a general purpose, platform agnostic “Common Code” Project type for Oxygene/RO C# files - and there really needs to be. Even more critical is a solution for shared assets (drawables, layouts etc), since there is no work around for these.

fyi - It occurred to me to try working around this for assets by creating symbolic links from one project to another. But I cannot create those in Windows since my code is stored on a Mac volume, and if I create them on the Mac volume they appear in Windows as shortcuts and do not function in the desired manner.

fyi 2 - I keep my code in dropbox, but currently I do not use dropbox to sync my Windows VM and the Host Mac, using a Parallels shared folder instead. If I used DropBox Sync then the Windows side of things would be on an NTFS volume and I imagine I could then create symbolic links on that side, but a) this is a massively inefficient (and I suspect problematic) way to share files between a guest and host and b) I suspect that difficulties may arise when Dropbox tries to sync folders which are in fact symlinks (and/or on any other synced machines).

Add as Link is an incomplete solution to this problem (which is perhaps why Microsoft created a specific “Shared Code” project type). I think we need the same sort of thing for Oxygene/RO C# code (and assets).

Whilst I agree that a common code/shared code project is very desirable (keeping multiple projects with the same code files in sync is a PITA of the highest order), I’m not convinced that a shared assets solution is needed or indeed desirable. I would not expect to use the same layouts etc in Android as I would in iOS. To my mind, most of the time assets are an application level resource, not a shared library one.

I don’t know if it’s possible but it would be great to be able to choose a shared library’s target architecture at build time. If it’s referenced from a .Net app build the library for .Net, if it’s Android build the lib for Android etc.

Shared assets is not for sharing across platforms, but is important when you have different versions of the same app - a "Free"and a “Paid” version, for example.

There are other ways of achieving a common code base for free/paid variations of an app, but these are not always appropriate./desirable

e.g. One such alternative is for the “Paid” app to be a simple “unlock” key. i.e. You have only one “app” (the free version), which checks for the presence of the paid for “app” and if it finds it, enables the required additional functionality or makes whatever other changes are required to transform the “free” app into the "paid"version.

But in my recent txt-2-park app, the basic app has very minimal requirements in terms of permissions. The free version has in-app advertising which the paid version does not. Adding the required library references and permissions to support advertising in the free version adds minor variations in the manifest, trivial changes in the code but makes an enormous difference to the required permissions and the size of the app. My paid version of the app doesn’t include any of the bulky overhead required to support the advertising and as a result has minimal requirements and is only a few KB in size (vs the 100’s of KB for the advertising supported version).

In this scenario, almost all of my code AND assets in the two versions of the app are identical but instead I have had to duplicate everything. In the case of this trivial app, this was a bearable solution. But for more significant projects I have to find a better approach. This is simply not workable for anything other than trivial apps.

As for re-targetting libraries, I don’t think it is possible to choose the target for a shared “library”. But it also isn’t necessary, as long as you have a decent mechanism for sharing untargeted code between targeted projects. You can then create projects for the required platform targets of the appropriate library type. The library projects then become simple “Project Heads”, controlling the build of the code imported from the “Headless” code library.

Which is exactly how Microsoft’s “Shared Code Projects” work (which is perhaps why they created them ? Maybe ?) :).

Oh I see. Thinking about it, a similar situation (but at an App level) is where you have an App Store and a Direct Sale version of a Mac App. The direct sale version has to deal with licensing and autoupdates but the App Store version doesn’t (actually even having Sparkle in your bundle will get you an app store rejection). The vast majority of the code is the same apart from half a dozen files.

We’re looking into adding support for these as we speak. No promises yet on how feasible it will be to use them, as Microsoft made them pretty VC#-specific.

Great news! :smile:

I for one can’t wait and for what it’s worth I think it would be a break-thru feature.

FYI - I managed to get a bit further with an effort to address this with a Project Type built using “MPF for Projects”… I got as far as tweaking/fixing the MPF framework to support projects without References and drag/drop of files as references, but ran into another stonewall. Namely that it appears to be the drop TARGET that is responsible for handling the dropped source. Which makes sense I guess, but means that in order to make my “Shared Oxygene Code” project type actually work with the RO Project Types I would have to modify those (or recreate an entire, parallel RO Project System from scratch).

What’s possible with the VS Project System is amazing. But the amount of work required to achieve what really should be so simple is a whole different league of “staggering”.

But maybe if you could quickly tweak your project types to support VSRef DropDataType objects… ? :wink: LOL

You are right in that this is going to need some changes from our side; Basically what we’re doing is introducing a new .targets file that does basically nothing when compiling. This will be the shared targets, a shared project Imports this.

on the ide side we have to change it so when adding/removing items from the project they’ll get added to the underlying Include file instead of the project file, and the projects that use it get notified of changes. The projects that use it will use an on the underlying include file. All of this will require IDE changes though, but might even be more powerful than the microsoft shared project stuff is, in the end, as I want to support an “IFDEF” modifier on files too so you can conditionally choose which files to include or not.

You got any info on that?

Conditional modifiers on files would be awesome - I had had a similar idea, specifically around layouts and manifests, but as well as a file being conditionally included you might want to have different variants of a file for different builds. You could then have FREE/PRO type variations within a project simply by changing build configurations.

In the case of XML based assets, even better would be to have the ability to create a required asset by merging two sources - one common core file plus additions.

So I might then have an AndroidManifest.xml in my shared (android) assets projects which provides the base manifest. Then in my Free and Pro android app projects I would have a further, partial AndroidManifest.xml with the specific additions for that project. The same principle could be applied to any xml based asset (strings, styles, drawables etc etc).

But I’m not sure either how you would implement this in the MSBuild system or how you would surface it in the Solution Explorer in a way that made sense. I figured this would fall the wrong side of an 80:20 rule, taking a lot more work to provide only really an incremental change beyond what shareable code/assets would provide.

As far as my quip w.r.t VSRef drop types…

I’ve been stumbling around using the MPFProj12 framework. in ProjectNode.CopyPaste.cs there is a method which creates the copy/paste/drag/drop data object for a selected hierarchy node within a project node (it took me a while to figure out that this is all handled by the project node, not the file node for the file being dragged!).

This method is PackageSelectionDataObject(). In the framework this is hard-wired to creaet a CF_VSSTGPROJECTITEMS format drop object (Storage Item - i.e. a file). With this in place at one point I was able to drag/drop an Oxygene source file from my project type into a WPF project, but the file was copied rather than linked.

So I changed this to use the CF_VSREFPROJECTITEMS format (reference item) which corresponds to the corresponds to the MPF framework enum value DropDataType.VsRef. But the Oxygene WPF Application project then refuses to accept the dragged file. In either event, using CTRL+SHIFT when dragging (which usually changes the drop action semantic to link vs move or copy) results in a “no entry” drag cursor.

Having looked at the code in the MPF framework around implementing support for accepting drop data into a project, I speculate that there is something about the data object being dragged from my shared code project which the Oxygene project implementation does not support, or that “link” drop actions are simply not supported, period. (hence the “no entry” cursor).

But it may be (far) more complicated than simply accepting VSREF format data (for one thing the response has to be different, obviously - it’s not just about the data object format but what to do with it when it is dropped). :slight_smile:

Something like this: (No conditionals yet):

1 Like

Yes, EXACTLY like that !!! Awesome with a capital O !!! (Kiwi joke)

When can I have it ? :slight_smile:

Hopefully tomorrow.