diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..6949bae --- /dev/null +++ b/.clang-format @@ -0,0 +1,29 @@ +--- +Language: ObjC +BasedOnStyle: LLVM +IndentWidth: 4 +TabWidth: 4 +ColumnLimit: 100 +UseTab: Always + +# Objective-C specific settings +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true + +# Break constructor initializers before the colon and after commas +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon + +# Add a space after C-style casts +SpaceAfterCStyleCast: true + +# Break before all operators +BreakBeforeBinaryOperators: NonAssignment + +# Pointer alignment +DerivePointerAlignment: false +PointerAlignment: Right + +# Keep empty lines at the start of blocks +KeepEmptyLinesAtTheStartOfBlocks: false \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7801c93..66a296a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,68 +1,150 @@ -# Xcode -# -# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - -## User settings -xcuserdata/ - -## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) -*.xcscmblueprint -*.xccheckout - -## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) -build/ -DerivedData/ -*.moved-aside -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 - -## Obj-C/Swift specific -*.hmap - -## App packaging -*.ipa -*.dSYM.zip -*.dSYM - -# CocoaPods -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# -# Pods/ -# -# Add this line if you want to avoid checking in source code from the Xcode workspace -# *.xcworkspace - -# Carthage -# -# Add this line if you want to avoid checking in source code from Carthage dependencies. -# Carthage/Checkouts - -Carthage/Build/ - -# fastlane -# -# It is recommended to not store the screenshots in the git repo. -# Instead, use fastlane to re-generate the screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://docs.fastlane.tools/best-practices/source-control/#source-control - -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots/**/*.png -fastlane/test_output - -# Code Injection -# -# After new code Injection tools there's a generated folder /iOSInjectionProject -# https://github.com/johnno1962/injectionforxcode - -iOSInjectionProject/ +### C ### +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.out + +# Debug files +*.dSYM/ + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +### Meson ### +# subproject directories +/subprojects/* +!/subprojects/*.wrap + +# Meson Directories +meson-logs +meson-private + +# Meson Files +meson_benchmark_setup.dat +meson_test_setup.dat +sanitycheckcpp.cc # C++ specific +sanitycheckcpp.exe # C++ specific + +# Ninja +build.ninja +.ninja_deps +.ninja_logs + +# Misc +compile_commands.json + + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# objc-boilerplate +build/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c37d954 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +This boilerplate is a simple example of how to use Objective-C 2.0 and Foundation on Linux with GNUstep. +We use the GNUstep configuration tool `gnustep-config` to get the GNUstep and Objective-C specific compiler +and linker flags. + +Make sure to source the `GNUstep.sh` script in your shell before compiling and running the program, otherwise +meson might not be able to locate `gnustep-config`. + +If you used the standard FHS installation layout, or did not explicitly set a layout when building GNUstep, +you can source the script like this: + +```bash +source /usr/share/GNUstep/Makefiles/GNUstep.sh +``` +Note that the Makefiles directory might be located in a different place on your system, depending on your distribution. + +Meson also looks for CC, and OBJC environment variables to be set. Use clang as the compiler, as GCC does not +support Objective-C 2.0. + +## Dependencies +- A working GNUstep installation with Objective-C 2.0 support (libobjc2, gnustep-make, gnustep-base) + Please note that as of writing this, the GNUstep debian packages do not support Objective-C 2.0, and use the GCC runtime. + +## Building +First, setup the meson project and `build/` directory: +```bash +# Source the GNUstep environment script if not already done by your shell configuration (e.g. source /usr/share/GNUstep/Makefiles/GNUstep.sh) +OBJC=clang meson setup build +``` + +You can now compile and execute the example program: +```bash +ninja -C build +./build/objc-boilerplate +``` + +If everything worked, you should see an output similar to this: +```bash +2023-10-16 11:28:06.806 objc-boilerplate[40560:40560] Hello, World! +``` diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..12b05aa --- /dev/null +++ b/meson.build @@ -0,0 +1,38 @@ +project('objc-boilerplate', 'objc', version : '0.1.0') + +# Ensure clang is used for Objective-C +objc_compiler = meson.get_compiler('objc') +if objc_compiler.get_id() != 'clang' + error('Clang is required for this project. Please set CC=clang, and OBJC=clang before running Meson.') +endif + +# Objective-C (GNUstep) support from gnustep-config +gnustep_config = find_program('gnustep-config', required: true) +if not gnustep_config.found() + error('GNUstep is required for this project. Please install GNUstep and ensure gnustep-config is in your PATH. You might want to source GNUstep.sh before running Meson.') +endif + +gnustep_flags = run_command(gnustep_config, '--objc-flags', check: true).stdout().strip().split() +gnustep_base_libs = run_command(gnustep_config, '--base-libs', check: true).stdout().strip().split() + +# Filter out flags that are handled by Meson's built-in options +filtered_objc_flags = [] +foreach flag : gnustep_flags +if flag != '-Wall' and flag != '-g' and flag != '-O2' + filtered_objc_flags += flag +endif +endforeach + +# Enable ARC (Automatic Reference Counting) +filtered_objc_flags += '-fobjc-arc' + +# Add Objective-C flags and libraries +add_project_arguments(filtered_objc_flags, language: 'objc') +add_project_link_arguments(gnustep_base_libs, language: 'objc') + +source = [ + # Objc files + 'src/main.m', +] + +executable('objc-boilerplate', source) \ No newline at end of file diff --git a/src/main.m b/src/main.m new file mode 100644 index 0000000..7b37846 --- /dev/null +++ b/src/main.m @@ -0,0 +1,8 @@ +#import + +int main(int argc, const char *argv[]) { + @autoreleasepool { + NSLog(@"Hello, World!"); + } + return 0; +} \ No newline at end of file