Friday, August 3, 2018

CLANG, -fblock undefined reference to `_NSConcreteGlobalBlock'

Recently i pickup objective-c to play with. And stumbled upon with this little beast called
Block which similar to lambda function. I am running *debian 8 x64*

During compilation:
$ clang `gnustep-config --objc-flags` -fblocks -o method-2 method-2.m -I/usr/lib/gcc/x86_64-linux-gnu/4.9/include -I/opt/obj-c/libobjc2/ -I/usr/lib/ -lgnustep-base  -lobjc

it outputs:
In file included from method-2.m:1:
In file included from /usr/include/GNUstep/Foundation/Foundation.h:30:
In file included from /usr/include/GNUstep/GNUstepBase/GSVersionMacros.h:219:
/usr/include/GNUstep/GNUstepBase/GSConfig.h:416:13: warning: ignoring
      redefinition of Objective-C qualifier macro [-Wobjc-macro-redefinition]
#    define __strong
            ^
/usr/include/GNUstep/GNUstepBase/GSConfig.h:417:13: warning: ignoring
      redefinition of Objective-C qualifier macro [-Wobjc-macro-redefinition]
#    define __weak
            ^
2 warnings generated.
/tmp/method-2-ed2a94.o:(.data.rel.ro+0x30): undefined reference to `_NSConcreteGlobalBlock'
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)
Makefile:9: recipe for target 'method-2' failed
make: *** [method-2] Error 1

After minutes of googling found this link that saying to add the -lBlocksRuntime
which has the neccessary reference to *_NSConcreteGlobalBlock*

i then edit the compile rules to
$ clang `gnustep-config --objc-flags` -fblocks -o method-2 method-2.m -I/usr/lib/gcc/x86_64-linux-gnu/4.9/include -I/opt/obj-c/libobjc2/ -I/usr/lib/ -lgnustep-base  -lobjc -lBlocksRuntime

it compiled successfully. ^^

here is the source code of method-2.m:

#import 

typedef void (^CompletionBlock)();
@interface SampleClass:NSObject
/* method declaration */
- (int)max:(int)num1 addNum:(int)num2 callback:(CompletionBlock)callbackFN;
@end

@implementation SampleClass

/* method returning the max between two numbers */
- (int)max:(int)num1 addNum:(int)num2 callback:(CompletionBlock)callbackFN{

   /* local variable declaration */
   int result;

   callbackFN();

   if (num1 > num2) {
         result = num1;
      } else {
            result = num2;
         }
 
   return result; 
}

@end

int main () {
   
   /* local variable definition */
   int a = 100;
   int b = 200;
   int ret;
   
   SampleClass *sampleClass = [[SampleClass alloc]init];

   /* calling a method to get max value */
   ret = [sampleClass max:a addNum:b callback:^{
      NSLog(@"Callback is called");
   }];
 
   NSLog(@"Max value is : %d\n", ret );
   return 0;
}


And i also use this headers file located in
https://github.com/gnustep/libobjc2

No comments: