|
|
(41 intermediate revisions by 3 users not shown) |
Line 1: |
Line 1: |
− | Objective-C under Ubuntu Linux
| + | Usually it is a good a idea to just use the package manager of your distribution to get a stable and well integrated GNUstep environment: |
| | | |
− | == Compiling Everything from Scratch (Ubuntu 14.04) ==
| + | sudo apt-get install gnustep gnustep-devel |
| | | |
− | The following script installs everything from scratch. It uses clang and libobjc2 for all the new Objective-C 2 features like ARC, Blocks, etc. '''Reference manuals''' for GNUStep, including available APIs, etc, are available at http://www.gnustep.org/developers/documentation.html
| + | If you want to develop new apps and try the newest features consider the approach described below. |
| | | |
− | These instructions were tested on a fresh installation of Ubuntu 14.04 on May 31, 2015.
| + | = Compiling Everything from Scratch = |
| | | |
− | Note: If you are using Ubuntu 12.04, your version of CMake and/or g++ may be too old to handle the newer versions of LLVM. See the bottom of this wiki page for instructions on how to get a newer version of CMake working on 12.04.
| + | The following repo contains scripts that compile and install everything needed for GNUstep Objective-C 2.0. The script uses clang and libobjc2 for all the awesome new features like ARC, blocks/Grand Central Dispatch, etc. |
− | <pre>
| |
− | #!/bin/bash
| |
| | | |
− | sudo apt-get update
| + | For example, to build GNUstep under Ubuntu 19.04, do: |
− | sudo apt-get -y install build-essential git subversion ninja cmake libffi-dev libxml2-dev libgnutls-dev libicu-dev libblocksruntime-dev libkqueue-dev libpthread-workqueue-dev autoconf libtool libjpeg-dev libtiff-dev libffi-dev libcairo-dev libx11-dev:i386 libxt-dev libXft-dev
| |
| | | |
− | cd ~
| + | git clone https://github.com/plaurent/gnustep-build |
− | git clone git://github.com/nickhutchinson/libdispatch.git | + | cd gnustep-build/ubuntu-19.04-clang-8.0-runtime-2.0/ |
− | svn co http://svn.gna.org/svn/gnustep/modules/core
| + | ./GNUstep-buildon-ubuntu1904.sh |
− | 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
| + | The demo.sh and demo-gui.sh scripts show example code and compilation examples (using command line as well as the recommended GNUmakefile approach.) |
− | rm -rf build
| |
− | mkdir build
| |
− | cd build
| |
− | cmake ..
| |
− | make -j8 # 8=your number of build CPUs
| |
| | | |
− | echo "export PATH=\$PATH:~/llvm/build/bin" >> ~/.bashrc
| + | Reference manuals for GNUStep, including available APIs, etc, are available at http://www.gnustep.org/developers/documentation.html |
− | echo "export CC=clang" >> ~/.bashrc
| |
− | echo "export CXX=clang++" >> ~/.bashrc
| |
− | export PATH=$PATH:~/llvm/build/bin
| |
− | export CC=clang
| |
− | export CXX=clang++
| |
| | | |
− | . ~/.bashrc
| + | General Note: When compiling your own code, it is generally good to tell clang both the family and version of the runtime: -fobjc-runtime=gnustep-2.0 |
− | clang -v
| + | (The current version number can be had by looking at the latest ANNOUNCE filename in https://github.com/gnustep/libobjc2 (e.g., ANNOUNCE.1.8.1)) |
− | clang++ -v
| |
− | | |
− | cd ~/libobjc2
| |
− | rm -rf build
| |
− | mkdir build
| |
− | cd build
| |
− | cmake ..
| |
− | make -j8
| |
− | sudo -E make install
| |
− | | |
− | cd ~/core/make
| |
− | ./configure --enable-debug-by-default --with-layout=gnustep --enable-objc-nonfragile-abi
| |
− | make && sudo -E make install
| |
− | echo ". /usr/GNUstep/System/Library/Makefiles/GNUstep.sh" >> ~/.bashrc
| |
− | | |
− | . /usr/GNUstep/System/Library/Makefiles/GNUstep.sh
| |
− | | |
− | sudo /sbin/ldconfig
| |
− | | |
− | cd ~/core/base/
| |
− | ./configure
| |
− | make -j8
| |
− | sudo -E make install
| |
− | | |
− | cd ~/libdispatch
| |
− | rm -rf libdispatch-build
| |
− | mkdir libdispatch-build && cd libdispatch-build
| |
− | ../configure
| |
− | make
| |
− | sudo make install
| |
− | sudo ldconfig
| |
− | | |
− | cd ~/core/gui
| |
− | ./configure
| |
− | make -j8
| |
− | sudo -E make install
| |
− | | |
− | cd ~/core/back
| |
− | ./configure
| |
− | make -j8
| |
− | sudo -E make install
| |
− | | |
− | echo "Install is done. Open a new terminal or type source ~/.bashrc"
| |
− | </pre>
| |
− | | |
− | === Test Code ===
| |
− | | |
− | <pre>
| |
− | | |
− | 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
| |
− | | |
− | | |
− | | |
− | cat > guitest.m << EOF
| |
− | #import <AppKit/AppKit.h>
| |
− | | |
− | int main()
| |
− | {
| |
− | NSApplication *app; // Without these 2 lines, seg fault may occur
| |
− | app = [NSApplication sharedApplication];
| |
− | | |
− | NSAlert * alert = [[NSAlert alloc] init];
| |
− | [alert setMessageText:@"Hello alert"];
| |
− | [alert addButtonWithTitle:@"All done"];
| |
− | int result = [alert runModal];
| |
− | if (result == NSAlertFirstButtonReturn) {
| |
− | NSLog(@"First button pressed");
| |
− | }
| |
− | }
| |
− | EOF
| |
− | | |
− | # ======================================================================
| |
− | # COMPILE USING THE FOLLOWING COMMAND LINES, OR CREATE A MAKEFILE
| |
− | # ======================================================================
| |
− | | |
− | clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -fobjc-runtime=gnustep -fblocks -fobjc-arc -lobjc blocktest.m
| |
− | | |
− | clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -fobjc-runtime=gnustep -fblocks -lobjc -ldispatch -lgnustep-base Fraction.m helloGCD_objc.m
| |
− | | |
− | clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -fobjc-runtime=gnustep -fblocks -lobjc -fobjc-arc -ldispatch -lgnustep-base -lgnustep-gui guitest.m
| |
− | </pre>
| |
− | | |
− | General Note: When compiling your own code, it is generally good to tell clang both the family and version of the runtime: -fobjc-runtime=gnustep-1.7 | |
− | (The current version number can be had by looking at the latest ANNOUNCE filename in http://svn.gna.org/svn/gnustep/libs/libobjc2/trunk/ (e.g., ANNOUNCE.1.7)) | |
− | | |
− | <b>Ubuntu 12.04 Help</b>
| |
− | | |
− | On Ubuntu 12.04, the default installed version of CMake is 2.8.7 but you need 2.8.8 or later to compile LLVM. And the default installed version of GCC and G++ is 4.6 but you need 4.8 or later to compile LLVM.
| |
− | | |
− | For CMake, the solution is to download and compile CMake yourself. Use the existing CMake 2.8.7 and then replace it:
| |
− | | |
− | # Download the latest CMake version from the CMake web site (http://www.cmake.org/cmake/resources/software.html), and uncompress it in a folder.
| |
− | # Create a _build directory in the CMake sources folder.
| |
− | # From the _build directory, run the following commands to build and install CMake from sources:
| |
− | | |
− | <pre>
| |
− | cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
| |
− | make
| |
− | cpack -G DEB
| |
− | sudo apt-get remove cmake cmake-data
| |
− | sudo dpkg -i cmake*.deb
| |
− | </pre>
| |
− | | |
− | To get GCC and G++ 4.8, do the following:
| |
− | | |
− | <pre>
| |
− | sudo add-apt-repository ppa:ubuntu-toolchain-r/test
| |
− | sudo apt-get update
| |
− | sudo apt-get install gcc-4.8 g++-4.8
| |
− | sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50
| |
− | sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50
| |
− | </pre>
| |
− | | |
− | You should be good to go.
| |