GNUstep under Ubuntu Linux
From GNUstepWiki
(Difference between revisions)
| Revision as of 23:47, 12 August 2012 Pakl (Talk | contribs) ← Previous diff |
Current revision Pakl (Talk | contribs) Comments |
||
| Line 1: | Line 1: | ||
| + | Objective C 2.0 on a fresh install of Ubuntu 12.10 Server | ||
| + | |||
| <pre> | <pre> | ||
| - | # ----------------------------------------------------------------- | + | # Objective C 2.0 on a fresh install of Ubuntu 12.10 Server |
| - | # Objective C 2.0 on Ubuntu (from source) | + | |
| - | # ----------------------------------------------------------------- | + | |
| - | # PART 1: LIBOBJC2 from source (with ARC) | + | |
| - | # PART 2: LIBDISPATCH from source | + | |
| - | # ON UBUNTU 12.04 SERVER | + | |
| - | # ----------------------------------------------------------------- | + | |
| - | # Step 1 based on David Chisnall (http://etoileos.com/news/archive/2011/08/14/1206/) | + | |
| - | # Step 2 based on Chris Mowforth http://chris.mowforth.com/installing-grand-central-dispatch-on-linux) | + | |
| - | # ----------------------------------------------------------------- | + | |
| - | # ----------------------------------------------------------------- | + | |
| - | + | ||
| - | # ============================== | + | |
| - | # ============================== | + | |
| - | # PART 1: new libobjc2 on Ubuntu | + | |
| - | # ============================== | + | |
| - | # ============================== | + | |
| - | + | ||
| - | # -------------------------------------------------------------------- | + | |
| - | # Some examples to test Objective C and ARC once we get it installed | + | |
| - | # -------------------------------------------------------------------- | + | |
| + | # Dependencies | ||
| + | sudo aptitude install build-essential git subversion ninja cmake | ||
| + | # Dependencies for GNUStep Base | ||
| + | sudo aptitude install libffi-dev libxml2-dev libgnutls-dev libicu-dev | ||
| + | # Dependencies for libdispatch | ||
| + | sudo aptitude install libblocksruntime-dev libkqueue-dev libpthread-workqueue-dev autoconf libtool | ||
| cd ~ | cd ~ | ||
| - | + | git clone git://github.com/nickhutchinson/libdispatch.git | |
| - | cat > Fraction.h << EOF | + | |
| - | + | ||
| - | #import <Foundation/NSObject.h> | + | |
| - | + | ||
| - | @interface Fraction: NSObject { | + | |
| - | int numerator; | + | |
| - | int denominator; | + | |
| - | } | + | |
| - | + | ||
| - | -(void) print; | + | |
| - | -(void) setNumerator: (int) n; | + | |
| - | -(void) setDenominator: (int) d; | + | |
| - | -(int) numerator; | + | |
| - | -(int) denominator; | + | |
| - | @end | + | |
| - | + | ||
| - | EOF | + | |
| - | + | ||
| - | + | ||
| - | cat > Fraction.m << EOF | + | |
| - | #import "Fraction.h" | + | |
| - | #import <stdio.h> | + | |
| - | + | ||
| - | @implementation Fraction | + | |
| - | -(void) print { | + | |
| - | printf( "%i/%i", numerator, denominator ); | + | |
| - | } | + | |
| - | + | ||
| - | -(void) setNumerator: (int) n { | + | |
| - | numerator = n; | + | |
| - | } | + | |
| - | + | ||
| - | -(void) setDenominator: (int) d { | + | |
| - | denominator = d; | + | |
| - | } | + | |
| - | + | ||
| - | -(int) denominator { | + | |
| - | return denominator; | + | |
| - | } | + | |
| - | + | ||
| - | -(int) numerator { | + | |
| - | return numerator; | + | |
| - | } | + | |
| - | @end | + | |
| - | + | ||
| - | EOF | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | cat > main.m << EOF | + | |
| - | + | ||
| - | #import <stdio.h> | + | |
| - | #import "Fraction.h" | + | |
| - | + | ||
| - | int main( int argc, const char *argv[] ) { | + | |
| - | // create a new instance | + | |
| - | Fraction *frac = [[Fraction alloc] init]; | + | |
| - | + | ||
| - | // set the values | + | |
| - | [frac setNumerator: 1]; | + | |
| - | [frac setDenominator: 3]; | + | |
| - | + | ||
| - | // print it | + | |
| - | printf( "The fraction is: " ); | + | |
| - | [frac print]; | + | |
| - | printf( "\n" ); | + | |
| - | + | ||
| - | // free memory | + | |
| - | [frac release]; | + | |
| - | + | ||
| - | return 0; | + | |
| - | } | + | |
| - | + | ||
| - | EOF | + | |
| - | + | ||
| - | cat > mainarc.m << EOF | + | |
| - | #import <stdio.h> | + | |
| - | #import "Fraction.h" | + | |
| - | + | ||
| - | int main( int argc, const char *argv[] ) { | + | |
| - | // create a new instance | + | |
| - | Fraction *frac = [[Fraction alloc] init]; | + | |
| - | + | ||
| - | // set the values | + | |
| - | [frac setNumerator: 1]; | + | |
| - | [frac setDenominator: 3]; | + | |
| - | + | ||
| - | // print it | + | |
| - | printf( "The fraction is: " ); | + | |
| - | [frac print]; | + | |
| - | printf( "\n" ); | + | |
| - | + | ||
| - | // free memory | + | |
| - | // [frac release]; // valgrind should show less leakage with -fobjc-arc | + | |
| - | + | ||
| - | return 0; | + | |
| - | } | + | |
| - | + | ||
| - | EOF | + | |
| - | + | ||
| - | + | ||
| - | # ----------------------------------------------------------------- | + | |
| - | # INITIAL REQUIREMENTS | + | |
| - | # ----------------------------------------------------------------- | + | |
| - | sudo apt-get -y install build-essential subversion clang libicu-dev libxml2-dev libxml2 libgnutls-dev libssl-dev | + | |
| - | + | ||
| - | #sudo apt-get -y install gnustep # If you want old runtime | + | |
| - | #sudo apt-get -y install gnustep-make | + | |
| - | #sudo apt-get -y install libgnustep-base-dev | + | |
| - | + | ||
| - | sudo apt-get -y install gobjc # Def required for below. | + | |
| - | + | ||
| - | # -------------------------------------------------------------------- | + | |
| - | # TEST (may fail w/ segfault if you did not apt-get install gnustep) | + | |
| - | # -------------------------------------------------------------------- | + | |
| - | + | ||
| - | cd ~ | + | |
| - | gcc `gnustep-config --objc-flags` main.m Fraction.m -o test -lobjc -lgnustep-base | + | |
| - | ./test | + | |
| - | clang `gnustep-config --objc-flags` main.m Fraction.m -o test -lobjc -lgnustep-base | + | |
| - | ./test | + | |
| - | + | ||
| - | # -------------------------------------------------------------------- | + | |
| - | # OK, let's install the new GNUstep from Subversion repositories! | + | |
| - | # (based on David Chisnall http://etoileos.com/news/archive/2011/08/14/1206/) | + | |
| - | # -------------------------------------------------------------------- | + | |
| - | mkdir gs | + | |
| - | cd gs | + | |
| - | + | ||
| - | svn co svn://svn.gna.org/svn/gnustep/tools/make/trunk make | + | |
| svn co http://svn.gna.org/svn/gnustep/modules/core | svn co http://svn.gna.org/svn/gnustep/modules/core | ||
| - | svn co svn://svn.gna.org/svn/gnustep/libs/libobjc2/trunk libobjc | + | svn co http://svn.gna.org/svn/gnustep/libs/libobjc2/trunk libobjc2 |
| - | + | svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm | |
| - | # -------------------------------------------------------------------- | + | cd llvm/tools |
| - | # 1) Install GNUstep Make a first time. | + | svn co http://llvm.org/svn/llvm-project/cfe/trunk clang |
| - | # -------------------------------------------------------------------- | + | |
| - | + | ||
| - | cd ~/gs/make | + | |
| - | export CC=clang | + | |
| - | export CXX=clang++ | + | |
| - | ./configure --enable-debug-by-default --with-layout=fhs | + | |
| - | make && sudo -E make install | + | |
| - | . /usr/local/share/GNUstep/Makefiles/GNUstep.sh | + | |
| - | cd .. | + | |
| - | + | ||
| - | cd ~/gs/core/base | + | |
| - | ./configure | + | |
| - | make # On this FIRST TIME THRU, WILL SAY CAN'T BUILD NSBLOCKS for this runtime | + | |
| - | sudo make install | + | |
| - | cd .. | + | |
| - | + | ||
| - | # -------------------------------------------------------------------- | + | |
| - | # TEST (the resulting binary will segfault if we don't have a runtime) | + | |
| - | # -------------------------------------------------------------------- | + | |
| - | cd ~ | + | |
| - | clang `gnustep-config --objc-flags` main.m Fraction.m -o test -lobjc -lgnustep-base | + | |
| + | cd ~/llvm | ||
| + | mkdir build | ||
| + | cd build | ||
| + | cmake .. | ||
| + | make -j8 # 8=your number of build CPUs | ||
| - | # -------------------------------------------------------------------- | + | echo "export PATH=\$PATH:~/llvm/build/bin" >> ~/.bashrc |
| - | # 2) Build libobjc2 | + | echo "export CC=clang" >> ~/.bashrc |
| - | # -------------------------------------------------------------------- | + | echo "export CXX=clang++" >> ~/.bashrc |
| - | cd ~/gs/libobjc | + | source ~/.bashrc |
| - | make -f Makefile | + | clang -v |
| - | sudo make -f Makefile install | + | clang++ -v |
| - | cd .. | + | |
| - | # -------------------------------------------------------------------- | + | cd ~/libobjc2 |
| - | # 3) NOW GO BACK, RECOMPILE GNUStep MAKE (TO DETECT THE NEW OBJC RUNTIME) | + | mkdir build |
| - | # -------------------------------------------------------------------- | + | cd build |
| + | cmake .. | ||
| + | make -j8 | ||
| + | sudo -E make install | ||
| - | cd ~/gs/make | + | cd ~/core/make |
| - | ./configure --enable-objc-nonfragile-abi --enable-native-objc-exceptions --with-layout=fhs --enable-debug-by-default CC=clang CXX=clang++ | + | ./configure --enable-debug-by-default --with-layout=gnustep |
| make && sudo -E make install | make && sudo -E make install | ||
| - | . /usr/local/share/GNUstep/Makefiles/GNUstep.sh | + | echo ". /usr/GNUstep/System/Library/Makefiles/GNUstep.sh" >> ~/.bashrc |
| - | cd .. | + | source ~/.bashrc |
| - | # -------------------------------------------------------------------- | + | cd ~/core/base/ |
| - | # 4) AND THEN RECOMPILE CORE/BASE | + | ./configure |
| - | # -------------------------------------------------------------------- | + | make -j8 |
| + | sudo -E make install | ||
| - | cd ~/core/base | + | cd ~/libdispatch |
| - | ./configure --disable-mixedabi CC=clang CXX=clang++ | + | sh autogen.sh |
| - | make # THIS TIME THRU, NO COMPLAINTS ABOUT BLOCKS | + | ./configure CFLAGS="-I/usr/include/kqueue" LDFLAGS="-lkqueue -lpthread_workqueue -pthread -lm" |
| - | sudo make install | + | make -j8 |
| - | cd .. | + | sudo -E make install |
| + | sudo ldconfig | ||
| - | # -------------------------------------------------------------------- | + | # ---------------------------------------------------------------------------------------- |
| - | # 5) FINALLY TEST AGAIN AND ENJOY OBJECTIVE C WITH ARC | + | # TEST COMPILING SOME CODE FROM THE INTERNET |
| - | # Note that I need to add GNUSTEP-CONFIG --OBJC-LIBS below. | + | # ---------------------------------------------------------------------------------------- |
| - | # If you don't want ARC, omit -fobj-arc | + | |
| - | # -------------------------------------------------------------------- | + | |
| - | cd ~ | + | You can compile the following code with: |
| - | clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -fobj-arc -fobjc-nonfragile-abi mainarc.m Fraction.m -o test -lobjc -lgnustep-base | + | |
| - | ./test | + | |
| + | clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -fobj-arc -fobjc-runtime=gnustep -fblocks -lobjc blocktest.m | ||
| + | clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -fobj-arc -fobjc-runtime=gnustep -fblocks -lobjc -ldispatch -lgnustep-base Fraction.m helloGCD_objc.m | ||
| - | # ============================== | ||
| - | # ============================== | ||
| - | # PART 2: libdispatch on Ubuntu | ||
| - | # ============================== | ||
| - | # ============================== | ||
| - | # -------------------------------------------------------------------- | + | cat > blocktest.m << EOF |
| - | # Some examples to test GCD once we get it installed | + | |
| - | # -------------------------------------------------------------------- | + | |
| - | + | ||
| - | cd ~ | + | |
| - | + | ||
| - | cat > helloGCD.c << EOF | + | |
| - | #include <dispatch/dispatch.h> | + | |
| #include <stdio.h> | #include <stdio.h> | ||
| int main() { | int main() { | ||
| - | dispatch_queue_t queue = dispatch_queue_create(NULL, NULL); | + | void (^hello)(void) = ^(void) { |
| - | + | printf("Hello, block!\n"); | |
| - | dispatch_sync(queue, ^{ | + | }; |
| - | printf("Hello, world from a dispatch queue!\n"); | + | hello(); |
| - | }); | + | return 0; |
| - | + | ||
| - | dispatch_release(queue); | + | |
| - | + | ||
| - | return 0; | + | |
| } | } | ||
| - | |||
| EOF | EOF | ||
| - | cat > helloGCD_objc.c << EOF | + | cat > helloGCD_objc.m << EOF |
| #include <dispatch/dispatch.h> | #include <dispatch/dispatch.h> | ||
| Line 280: | Line 107: | ||
| EOF | EOF | ||
| - | # -------------------------------------------------------------------- | + | cat > Fraction.h << EOF |
| - | # INSTALLING LIBDISPATCH | + | |
| - | # (based on Chris Mowforth http://chris.mowforth.com/installing-grand-central-dispatch-on-linux) | + | |
| - | # -------------------------------------------------------------------- | + | |
| - | sudo apt-get install clang libblocksruntime-dev libkqueue-dev | + | #import <Foundation/NSObject.h> |
| - | # Visit http://packages.ubuntu.com/oneiric/libpthread-workqueue0 for download links | + | @interface Fraction: NSObject { |
| - | # Visit http://packages.ubuntu.com/oneiric/libpthread-workqueue-dev for download link | + | int numerator; |
| + | int denominator; | ||
| + | } | ||
| - | mkdir dispatch | + | -(void) print; |
| - | cd dispatch | + | -(void) setNumerator: (int) n; |
| - | sudo apt-get install make autoconf autogen libtool build-essential gcc-multilib | + | -(void) setDenominator: (int) d; |
| - | sudo apt-get install pkg-config | + | -(int) numerator; |
| + | -(int) denominator; | ||
| + | @end | ||
| - | wget http://mirror.pnl.gov/ubuntu//pool/universe/libp/libpthread-workqueue/libpthread-workqueue0_0.8.2-1_amd64.deb | + | EOF |
| - | wget http://mirror.pnl.gov/ubuntu//pool/universe/libp/libpthread-workqueue/libpthread-workqueue-dev_0.8.2-1_amd64.deb | + | |
| - | sudo dpkg -i libpthread-workqueue0_0.8.2-1_amd64.deb | ||
| - | sudo dpkg -i libpthread-workqueue-dev_0.8.2-1_amd64.deb | ||
| - | wget http://archive.ubuntu.com/ubuntu/pool/universe/libd/libdispatch/libdispatch_0~svn197.orig.tar.gz | + | cat > Fraction.m << EOF |
| + | #import "Fraction.h" | ||
| + | #import <stdio.h> | ||
| - | tar xvfz libdispatch_0~svn197.orig.tar.gz | + | @implementation Fraction |
| - | cd libdispatch-0~svn197/ | + | -(void) print { |
| - | export CC=clang | + | printf( "%i/%i", numerator, denominator ); |
| - | export CXX=clang++ | + | } |
| - | make distclean | + | |
| - | ./configure | + | |
| - | make | + | |
| - | # dispatch_starfish.o: In function `_dispatch_time_mach2nano': | + | -(void) setNumerator: (int) n { |
| - | # dispatch_starfish.c:(.text+0x5bc): undefined reference to `_dispatch_host_time_data' | + | numerator = n; |
| - | # dispatch_starfish.c:(.text+0x5ea): undefined reference to `_dispatch_get_host_time_init' | + | } |
| - | # /usr/bin/ld: .libs/dispatch_starfish: hidden symbol `_dispatch_host_time_data' isn't defined | + | |
| - | # /usr/bin/ld: final link failed: Bad value | + | |
| - | # clang: error: linker command failed with exit code 1 (use -v to see invocation) | + | |
| - | # make[1]: *** [dispatch_starfish] Error 1 | + | |
| - | # make[1]: Leaving directory `/home/patryk/dispatch/libdispatch-0~svn197/testing' | + | |
| - | # make: *** [all-recursive] Error 1 | + | |
| - | # -------------------------------------------------------------------- | + | -(void) setDenominator: (int) d { |
| - | # To fix compile, comment out build of "testing" from Makefile | + | denominator = d; |
| - | # -------------------------------------------------------------------- | + | } |
| - | make clean | + | -(int) denominator { |
| - | sed "s/testing/#testing/" Makefile > Makefile.new | + | return denominator; |
| - | mv Makefile.new Makefile | + | } |
| - | make | + | |
| - | sudo make install | + | |
| - | sudo ldconfig | + | |
| - | # -------------------------------------------------------------------- | + | -(int) numerator { |
| - | # Testing | + | return numerator; |
| - | # -------------------------------------------------------------------- | + | } |
| - | # Plain C: When not compiling with libobjc2 (just plain C) on Ubuntu you must add -lBlocksRuntime | + | @end |
| - | # -------------------------------------------------------------------- | + | |
| - | + | ||
| - | clang -o hi helloGCD.c -fblocks -ldispatch -lBlocksRuntime | + | |
| - | ./hi | + | |
| - | + | ||
| - | clang -o hi helloGCD.c -fblocks -ldispatch | + | |
| - | # /usr/bin/ld: /tmp/helloGCD-eXxFYY.o: undefined reference to symbol '_NSConcreteGlobalBlock' | + | |
| - | # /usr/bin/ld: note: '_NSConcreteGlobalBlock' is defined in DSO /usr/lib/libBlocksRuntime.so.0 | + | |
| - | # so try adding it to the linker command line | + | |
| - | # /usr/lib/libBlocksRuntime.so.0: could not read symbols: Invalid operation | + | |
| - | # clang: error: linker command failed with exit code 1 (use -v to see invocation) | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | # -------------------------------------------------------------------- | + | |
| - | # Compiling Objective C with ARC and blocks and libdispatch | + | |
| - | # -------------------------------------------------------------------- | + | |
| - | # Note: do not use -lBlocksRuntime here since Apple on is not | + | |
| - | # compatible with the libobjc2 one which has its own. (Note from | + | |
| - | # David Chisnall) | + | |
| - | # -------------------------------------------------------------------- | + | |
| - | + | ||
| - | clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -fobj-arc -fobjc-nonfragile-abi -fblocks helloGCD_objc.m Fraction.m -o test -lobjc -lgnustep-base -ldispatch | + | |
| - | ./test | + | |
| + | EOF | ||
| </pre> | </pre> | ||
Current revision
Objective C 2.0 on a fresh install of Ubuntu 12.10 Server
# Objective C 2.0 on a fresh install of Ubuntu 12.10 Server
# Dependencies
sudo aptitude install build-essential git subversion ninja cmake
# Dependencies for GNUStep Base
sudo aptitude install libffi-dev libxml2-dev libgnutls-dev libicu-dev
# Dependencies for libdispatch
sudo aptitude install libblocksruntime-dev libkqueue-dev libpthread-workqueue-dev autoconf libtool
cd ~
git clone git://github.com/nickhutchinson/libdispatch.git
svn co http://svn.gna.org/svn/gnustep/modules/core
svn co http://svn.gna.org/svn/gnustep/libs/libobjc2/trunk libobjc2
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
cd ~/llvm
mkdir build
cd build
cmake ..
make -j8 # 8=your number of build CPUs
echo "export PATH=\$PATH:~/llvm/build/bin" >> ~/.bashrc
echo "export CC=clang" >> ~/.bashrc
echo "export CXX=clang++" >> ~/.bashrc
source ~/.bashrc
clang -v
clang++ -v
cd ~/libobjc2
mkdir build
cd build
cmake ..
make -j8
sudo -E make install
cd ~/core/make
./configure --enable-debug-by-default --with-layout=gnustep
make && sudo -E make install
echo ". /usr/GNUstep/System/Library/Makefiles/GNUstep.sh" >> ~/.bashrc
source ~/.bashrc
cd ~/core/base/
./configure
make -j8
sudo -E make install
cd ~/libdispatch
sh autogen.sh
./configure CFLAGS="-I/usr/include/kqueue" LDFLAGS="-lkqueue -lpthread_workqueue -pthread -lm"
make -j8
sudo -E make install
sudo ldconfig
# ----------------------------------------------------------------------------------------
# TEST COMPILING SOME CODE FROM THE INTERNET
# ----------------------------------------------------------------------------------------
You can compile the following code with:
clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -fobj-arc -fobjc-runtime=gnustep -fblocks -lobjc blocktest.m
clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -fobj-arc -fobjc-runtime=gnustep -fblocks -lobjc -ldispatch -lgnustep-base Fraction.m helloGCD_objc.m
cat > blocktest.m << EOF
#include <stdio.h>
int main() {
void (^hello)(void) = ^(void) {
printf("Hello, block!\n");
};
hello();
return 0;
}
EOF
cat > helloGCD_objc.m << EOF
#include <dispatch/dispatch.h>
#import <stdio.h>
#import "Fraction.h"
int main( int argc, const char *argv[] ) {
dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
Fraction *frac = [[Fraction alloc] init];
[frac setNumerator: 1];
[frac setDenominator: 3];
// print it
dispatch_sync(queue, ^{
printf( "The fraction is: " );
[frac print];
printf( "\n" );
});
dispatch_release(queue);
return 0;
}
EOF
cat > Fraction.h << EOF
#import <Foundation/NSObject.h>
@interface Fraction: NSObject {
int numerator;
int denominator;
}
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
-(int) numerator;
-(int) denominator;
@end
EOF
cat > Fraction.m << EOF
#import "Fraction.h"
#import <stdio.h>
@implementation Fraction
-(void) print {
printf( "%i/%i", numerator, denominator );
}
-(void) setNumerator: (int) n {
numerator = n;
}
-(void) setDenominator: (int) d {
denominator = d;
}
-(int) denominator {
return denominator;
}
-(int) numerator {
return numerator;
}
@end
EOF
