Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for GNUStep #176

Open
freakboy3742 opened this issue Apr 27, 2020 · 2 comments
Open

Add support for GNUStep #176

freakboy3742 opened this issue Apr 27, 2020 · 2 comments
Labels
enhancement New features, or improvements to existing features.

Comments

@freakboy3742
Copy link
Member

In theory, Rubicon should be able to work for any Objective C implementation. GNUStep is the most prominent Linux alternative to the macOS frameworks, and in theory, it's compatible; so we should add support for GNUStep.

An initial attempt was made with #122; however, that effort stalled due to issues driving the compiler and linking process. Someone with more GNUStep experience is required.

@freakboy3742 freakboy3742 added enhancement New features, or improvements to existing features. help wanted labels Apr 27, 2020
@dgelessus
Copy link
Collaborator

Related: #113

@dgelessus
Copy link
Collaborator

Just did some quick experimenting with Rubicon and GNUstep. My test system is Kubuntu 19.10 with the gnustep-core-devel package installed. My impression so far: GNUstep's environment is quite different from what you get on Apple, in multiple ways (large and small). This means that supporting GNUstep in Rubicon would require a bit of work, and it's not just changing a few library and function names.


The first thing I noticed (because it's the first thing that Rubicon failed at under GNUstep) is that GNUstep doesn't use frameworks in the way that Apple platforms do. The concept of frameworks seems to exist, but in practice GNUstep frameworks seem to be more like regular libraries with extra bundle data attached.

For example, the Foundation framework in GNUstep has its main header at /usr/include/GNUstep/Foundation/Foundation.h (the directory /usr/include/GNUstep is placed on the compiler include path by gnustep-config --objc-flags), but the corresponding library is located at /usr/lib/libgnustep-base.so.1.26, and its bundle data is located at /usr/share/GNUstep/Libraries/gnustep-base/Versions/1.25/Resources.

This actually isn't a huge problem for Rubicon - we don't really care about frameworks except that we need to load them, so the only change needed here is loading the library gnustep-base instead of Foundation. We don't even need to look for the library in a special location, because the libgnustep-base.so is located in the regular /usr/lib directory, which is already on the default library search path.


The differences in the Objective-C runtime are the bigger issue. First of all, it seems that there isn't just one GNUstep Objective-C runtime - there are apparently multiple implementations that are used in different cases, depending on what compiler and flags you use (for regular compiled Objective-C programs). I haven't looked into this in detail yet and don't know how it would affect Rubicon.

My initial quick testing was with the Objective-C runtime that I get from ctypes.util.find_library('objc'), which on my test system is libobjc.so.4, which seems to be the same library that is used when I compile an Objective-C program using gcc with the flags from gnustep-config --objc-flags and gnustep-config --base-libs. This Objective-C runtime is fairly similar to the ones on Apple systems, but some features are implemented differently or missing entirely. In particular:

  • object_isClass is implemented as an inline function (for performance reasons), meaning that we cannot call it dynamically at runtime like all other runtime functions and would need to reimplement it in Python. This isn't a big issue though - the implementation is very simple.
  • property_copyAttributeList is missing. We declare this function in rubicon.objc.runtime, but never actually use it, so this isn't a big issue.
  • class_addProperty is missing. We do in fact use this function, but if necessary we could probably emulate it - almost no Objective-C code cares about whether something is a property or not. Rubicon itself needs to know this (to determine whether a method is a property getter and should be "auto-called"), but we could track that information ourselves using our existing declare_property API.
  • The runtime functions for creating protocols at runtime are missing. This is a bit annoying, but we could probably emulate those functions too - like with properties, other Objective-C code almost never cares whether an object conforms to a protocol or not (especially if the protocol is only created at runtime and not defined in a header).
  • The "associated objects" APIs are missing. This is a major issue, because we currently use these APIs to implement parts of our memory management for ObjCInstances and their corresponding Objective-C objects. (Though I've been meaning to look into that code anyway. The "associated objects" API is a relatively obscure and weird feature of the Objective-C runtime - I would like to reimplement our memory management in a more conventional way if possible.)
  • The message sending APIs are different. In Apple's runtime, you have objc_msgSend, which you pass an object, selector (method name) and arguments, and it will call that method on the object. In the GNUstep runtime, you instead have objc_msg_lookup, which takes an object and a selector and returns an IMP (method implementation function pointer) for the method, which you then need to call manually. This shouldn't be that big of an issue - it's fairly easy to implement the equivalent of objc_msgSend in Python using objc_msg_lookup. This could be included as an extra branch in our existing send_message function.

This list is in no way complete - these are just the issues that I ran into with some quick testing. I stopped once I wasn't able to just ignore the errors using try/except AttributeError anymore. I'm sure that more issues would pop up if these ones are properly fixed/worked around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New features, or improvements to existing features.
Projects
None yet
Development

No branches or pull requests

2 participants