libs-base icon indicating copy to clipboard operation
libs-base copied to clipboard

Cross Compiling Guide?

Open andrewapperley opened this issue 2 years ago • 2 comments

Hey GNUStep Team.

I'm currently working on porting Objective-C and libs-base to the Sega Dreamcast / SH4 with @gyrovorbis.

We are using GCC 12.2.0 as our compiler as GCC is the only compiler that has support for KOS, which is the development environment used on DC. This does mean we are using the GCC runtime.

Our progress thus far is running objective-c++ code on the dreamcast directly using the runtime. This is some sample code that works. (c++ 20!!)

#include <objc/objc.h>
#include <objc/Object.h>
#include <objc/runtime.h>
#include <concepts>
#include <regex>
#include <iostream>

template <typename T>
concept ILabel = requires(T v)
{
    {v.toString()} -> std::convertible_to<std::string>;
};

template<typename... Args>
class Stringifier { 
    int i = 0;
public:
    std::string toString(void) {
        return "Test String";
    }
};

@interface Person: Object 
 {
    int age;
 }
- (void)test;
+ (void)initialize;
@end

@implementation Person
+ (void) initialize {
    printf("Objective-C static constructors work!\n\n");
    if constexpr(ILabel<Stringifier<int, float, char>>) { 
        std::cout << "C++20 Concepts + iostream works!" << std::endl;
    }
}

 - (void)test {
    printf("ObjC method dispatch with class reflection work %s\n", class_getName([self class]));
    fflush(stdout);

   if (regex_match ("softwareTesting", regex("(soft)(.*)") ))
      cout << "string:literal => matched\n";
 
   const char mystr[] = "SoftwareTestingHelp";
   string str ("software");
   regex str_expr ("(soft)(.*)");
 
   if (regex_match (str,str_expr))
      cout << "string:object => matched\n";

}  
@end

int main(int argc, char *argv[]) {
    printf("Objective C Class Location!: %p", [Person class]);
    Person* person = class_createInstance(objc_getClass("Person"), 0);
    printf("Objective C Instance Location = %p", person);
    [person test];

    printf("C API works %s\n", class_getName(object_getClass(person)));

    printf("ObjC method again: %d\n", [person isEqual:person]);
    fflush(stdout);
    return 0;
}

An example of what code we are using to test libs-base

#import <Foundation/NSObject.h>

Class object_getClass (id object)
{
  if (object != nil)
    return object->isa;
  else
    return Nil;
}

long sysconf(int name) {
  switch(name){
    case _SC_NPROCESSORS_CONF: return 1;
    case _SC_NPROCESSORS_ONLN: return 1;
    default: return 0;
  }
}

@interface Person: NSObject

@end

@implementation Person
@end

int main(int argc, char **argv, char **envp) {
    Person *person = [[Person alloc] init];

    return 0;
}

The reason we added object_getClass is because it was found to be undefined when compiling this example. There seems to be a mismatch in runtimes when compiling libs-base and our own example code. In GCCs runtime this method isn't inline but in libs-base it is. Is there a way to force gcc's runtime to be used instead?

Now when it comes to libs-base we have got as far as compiling a .a file and then are met with linker errors. We've been working through them as they come up. We had this bizarre one for a while where main was undefined but we tracked it down to NSProcessInfo reimplementing our main function. We have a fork where we store any changes we've been doing to get it to work. Any changes where we comment something out are temporary with the intention to revisit once we get NSObject working on a DC.

I'm wondering if the team has any pointers for doing a cross compile or examples of this being done with GCC that could be pointed to. We would greatly appreciate it because the documentation is scarce on the topic.

If I haven't mentioned it here please reach out to clarify any questions you have about what we have tried.

Thanks.

cc @gcasa

andrewapperley avatar Feb 21 '23 20:02 andrewapperley

Maybe the scripts from the tools-android repo help, which do cross-compilation to Android: https://github.com/gnustep/tools-android/blob/master/phases/20-gnustep-make.sh https://github.com/gnustep/tools-android/blob/master/phases/30-gnustep-base.sh

Note that these are using Clang and the libobjc2 runtime, so you’ll have to adapt for that.

triplef avatar Feb 22 '23 14:02 triplef