[HN Gopher] C-Macs - a pure C macOS application
___________________________________________________________________
C-Macs - a pure C macOS application
Author : dgellow
Score : 142 points
Date : 2024-04-19 10:53 UTC (12 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| magicmicah85 wrote:
| Good example of digging with a spoon as they stated was the
| original goal. And it still compiles on an M1 macbook despite
| being a decade old code base.
| codazoda wrote:
| No license typically means copyright with all rights reserved in
| the U.S.
|
| Perhaps you want to release this into the public domain (see
| SQLite)?
| actionfromafar wrote:
| I'd say the license is:
|
| " Use it at your own risk, and don't blame me if anything bad
| happens. Oh, and if you extend it, make sure there isn't any
| Objective-C in it!"
|
| I'd classify it as Open Source.
| nicky0 wrote:
| Oh no that won't fly at all. People around here really like
| "proper" licenses. And they'll tell you about it.
| actionfromafar wrote:
| I don't like the (perhaps actually a) license, because it
| set's limits on what the user can do with the source code.
| (Not allowing Objective C in it.)
| fao_ wrote:
| yeah i accidentally added objective c code and now im
| kissing my ass bracing for the lawsuit!!!!!!!111
| gleenn wrote:
| I'm not a lawyer but one would definitely let you know that
| at least in the US, software without a license is more
| dangerous than software with even a very restrictive one.
| Someone can come along and determine the license at any
| time. So there is good reason to point it out unless you
| crave legal jeopardy.
| williamcotton wrote:
| It's open source but it is still under copyright. There are
| notices in the source file:
|
| https://github.com/CodaFi/C-Macs/blob/master/CMacs/View.c#L5.
| ..
|
| I would definitely ask permission and encourage the author to
| change the license before using this code.
|
| Since API calls are purely functional and not covered by
| copyright you can mimic the behavior here but you'll need to
| rewrite everything from scratch, notably the most expressive
| parts, which are:
|
| https://github.com/CodaFi/C-Macs/blob/master/CMacs/CMacsType.
| ..
|
| https://github.com/CodaFi/C-Macs/blob/master/CMacs/CMacsType.
| ..
|
| The organization and structure of this code is arbitrary and
| within the author's creative expression.
| actionfromafar wrote:
| In most jurisdictions _almost everything_ is under
| copyright, until it expires. (Which is approximately right
| before the heat death of the universe, after Disney get
| their way. Or 70 years after the authors death, or
| something like that.)
| ranger_danger wrote:
| https://arstechnica.com/tech-policy/2021/04/how-the-
| supreme-...
| ngcc_hk wrote:
| Actually Micky is free.
| numpad0 wrote:
| Copyleft licenses depend on copyright. I think it was in an
| FSF FAQ somewhere. GPL is as copyright maximalist as it
| gets.
| williamcotton wrote:
| I always see the strangest fluctuations in upvotes and
| downvotes whenever I state the laws and doctrines of
| copyright.
|
| FWIW, I do court ordered code inspections to assess alleged
| copyright infringement for a living.
| embirico wrote:
| I do love the vibe of that license
| actionfromafar wrote:
| If it weren't for it claiming to not be a license in the
| sentence before, it would be pretty good. Reminds me of the
| WTFPL license. :)
|
| https://directory.fsf.org/wiki/License:WTFPL
| dec0dedab0de wrote:
| It's definitely not Open Source with that Objective-C
| restriction. Though it does fit the attitude of the project.
| chunsj wrote:
| It seems that the code is the result of the ObjC preprocessor.
| :-)
| CodeWriter23 wrote:
| I know humor is not allowed on HN but lol
| 9dev wrote:
| As someone with no experience in native application development,
| could someone explain to me why this is significant? I have a
| rough idea, but I would like to understand it properly.
| jojobas wrote:
| I guess it's normally impossible to write a GUI application for
| mac os without objective-c libraries doing the talking to the
| OS, but what do I know.
| swatcoder wrote:
| It is not. This was just a new wave of people finally looking
| under the hood.
|
| (Where they would have found many many dusty but detailed man
| pages and docs waiting for them)
| astrange wrote:
| You can write one in X11 if you like, if you make people
| install Xquartz.
| ngcc_hk wrote:
| Is there example how to do that on mac. Just happy to have
| an old emu ibm 5100 sun x program. Wonder I need to boot up
| a vm or can try squartz ...
| steve1977 wrote:
| Beneath Cocoa are Core Foundation and things like Core
| Graphics for example, which both are C.
| williamcotton wrote:
| MacOS apps are typically written in either Objective-C or Swift
| as these are the officially supported languages for the MacOS
| APIs.
|
| The code in this template is interfacing with the Objective-C
| runtime but with pure C.
| rankam wrote:
| Does this mean that, theoretically, this could lead to the
| ability to build MacOS apps in higher languages that
| interoperate well with C such as Python? I know you can build
| MacOS apps with Python now, but does this potentially improve
| the experience?
| detourdog wrote:
| That is what objC scripting brige is for.
|
| https://developer.apple.com/documentation/scriptingbridge
| jimbokun wrote:
| I believe RubyMotion does basically this:
|
| http://www.rubymotion.com
|
| It was fun building an app in this a few years ago, but was
| difficult to keep up with updates to MacOS breaking my
| code.
| CodeWriter23 wrote:
| There's already PyCocoa and pretty sure *Cocoa exists for a
| variety of languages.
| flohofwoe wrote:
| You can already do this in the traditional way by building
| an ObjC shim which exposes a C API. The solution shown here
| just skips ObjC and talks directly to the ObjC runtime
| (which has a C API but is not as convenient to use as doing
| the same thing in ObjC or Swift).
|
| In a highly simplified way you can think of Objective-C as
| preprocessor which replaces the ObjC syntax sugar with C
| function calls into the ObjC runtime (it's not how it works
| in reality, but how it _could_ work).
| jackjeff wrote:
| That's essentially what this project does. It creates the
| C code that the ObjC compiler would generate to
| "implement methods" or "send messages".
|
| It's somewhat doable by hand because Objc is a thin
| lawyer.
|
| Over 15 years ago I did stuff similar to this project to
| call some Objc code from a C++ app. Most of it was
| exposed to normal C APIs but one feature only available
| in AppKit. It was much simpler to do it this way than
| figure out how to make GCC or Objc like our C++ or any
| mess with bridging headers.
|
| I think the move to Swift has made that harder in some
| ways.
|
| But then again I don't want to write C or C++ these days
| if I can avoid it.
| gwking wrote:
| In fact, early objective-c was a preprocessor according
| to Wikipedia!
| ChrisMarshallNY wrote:
| That has always been possible. Also, under the ObjC layer, is
| good ol' ANSI C (FreeBSD Unix).
|
| There's a number of apps that run on modern Macs, that were
| written in C, but it is unusual to see ones that leverage the
| GUI.
|
| That said, it's possible to walk from Boston to Portland
| (OR), but I'd rather take a plane.
| thenipper wrote:
| You know i took the train to Boston to PDX, it was really
| relaxing. Not quite walking but definitely a lot different
| then a plane...
| jonhohle wrote:
| It has, but there was also Carbon until around the Intel
| transition.
| LeoNatan25 wrote:
| Full Carbon was there until the 64bit transition
| officially, but much of it remained and still remains
| until now. For example, Apple only started using AppKit
| to draw menus in Sonoma; it was Carbon until now.
| ChrisMarshallNY wrote:
| I think it's cool that a lot of NextStep stuff is still
| there (all those "NS _XXX_ " calls).
| saagarjha wrote:
| Wait until you see the NX* APIs ;)
| ChrisMarshallNY wrote:
| I have not encountered them. Are they public?
| saagarjha wrote:
| Some are, though heavily deprecated: https://developer.ap
| ple.com/documentation/objectivec/nxhasht...
| nxobject wrote:
| Quick! The one comment where my username is relevant!
| Must... reply... before.. opportunity... passes...
| ryandrake wrote:
| I knew this was possible, but I had never actually seen it
| implemented before. And to think, the project is over 10
| years old!
|
| When I first started programming Cocoa, I was always kind
| of miffed that the happy-path was: "Use Objective-C and
| main() should just hand-off the reigns to
| NSApplicationMain()". Kind of like the happy-path on
| Windows is "WinMain plus a bunch of boilerplate crud".
|
| It's always felt somehow vaguely "correct" to have main()
| be your actual application entry point and have it manage
| whatever main loop you need yourself. I see that this
| project doesn't actually quite get there either. It's the
| same kind of voodoo: boilerplate code, and then
| cmacs_void_msgSend(NSApp, sel_getUid("run")); hands over
| the reigns.
| williamcotton wrote:
| It has to hand over the reigns to the Objective-C runtime
| to allow for all the messages being passed between
| objects.
|
| I'm not sure you want to spend your time rewriting what
| NSApp is doing!
| saagarjha wrote:
| The runtime knows how to do that already. -[NSApplication
| run] sets up the runloop to drain events among other
| things.
| astrange wrote:
| Why would you want to manage your own runloop? It's both
| not interesting and possible to get wrong.
| adastra22 wrote:
| Sometimes there are conflicting things you need to do in
| the same main thread.
| mycall wrote:
| > officially supported languages for the MacOS APIs
|
| How often do you need to get support assistance from Apple?
| Just do what you want. If it means using Obj-C or Swift for
| ease, do that. If it means integrating another language, do
| that.
| swatcoder wrote:
| > why this is significant?
|
| Ultimately, because new people keep being born and missed the
| years where this was pretty common and haven't yet bumped into
| the corners where it still is.
|
| The repo and the SO discussion it was inspired by are
| themselves 11 years old and seem to be rooted in a new
| generation of iOS app developers starting to get more deeply
| curious about the system they're running on and how else it
| might be approached, which this person then ran with on MacOS.
|
| Apple invites people to get started in making software for
| their platforms using (what's meant to be) more accessible
| tooling like Objective-C, Interface Builder, Swift, SwiftUI,
| etc but there's of course a whole BSD-rooted operating system
| sitting there once those those developers start digging. It's
| no secret, but it's a discovery that some people need to make
| on their own.
| LeoNatan25 wrote:
| This isn't an example of that. Have you looked at the code?
| This uses ObjC and Cocoa implementations in an unintuitive
| method. Nice exercise to learn about the ObjC runtime, but
| has zero practicality or use.
| johnnyjeans wrote:
| The funny thing is, Apple themselves seems to have forgotten
| about the whole BSD-rooted operating system. Anybody who
| ventures off the beaten path of developing software for a
| modern Mac will inevitably encounter a lot of cobwebs. One of
| my favorites: When Apple implemented app bundles, they never
| updated dyld's search paths to be aware of the app bundle
| directory structure, meaning you have to manually patch your
| rpaths. Not a huge deal, and one that's hidden from you if
| you only ever know xcode, but it's one of many very sloppy
| things I noticed coming from a strong Unix background to Mac.
| There's a lot of really weird incongruence where the deeper
| you go into the system, the more everything feels covered in
| dust and neglected. I was always sold on Macs having really
| great top-to-bottom integration and have all the polish and
| attention to detail you can expect out of a corporate Unix-
| like, but that's not what I found. It's more like a really
| shiny superstructure bolted on top of an ancient, rust-eaten
| BSD. Don't get me started on how a lot of the "newer" stuff
| at that low level tends to be some of the absolute worst
| takes on a concept. The "App Sandbox" might be the most
| disgusting, slap-dash design for process isolation I've ever
| seen bolted onto a kernel.
|
| I get Apple's target market is quite literally the opposite
| kind of user that I am. That being said, I always find it
| curious that people still tout Mac as this kind of "Super
| Polished Desktop/Workstation Unix" and often cite the Unix
| certification. It feels like the more you try to use a Mac
| like you would any other Unix machine, the more you have to
| fight it. Often it doesn't feel any different to trying to
| wrangle Windows with WSL. I had less hiccups and trip-ups
| learning Plan 9 than I did coming to terms with macOS.
| saagarjha wrote:
| App bundles have no fixed layout. How would rpaths work if
| you didn't specify them yourself?
| astrange wrote:
| > When Apple implemented app bundles, they never updated
| dyld's search paths to be aware of the app bundle directory
| structure, meaning you have to manually patch your rpaths.
|
| Typically things like this have binary compatibility
| reasons. (It wouldn't be because they forgot, actually I
| happen to know the same person has worked on dyld since the
| 90s.)
|
| > but it's one of many very sloppy things I noticed coming
| from a strong Unix background to Mac
|
| Funny thing to complain about. Sloppiness /is/ Unix design,
| that's intentional. It's called "worse is better".
|
| On the other hand, nobody uses Plan9 because it's too well-
| designed to actually work.
| nxobject wrote:
| Oh wow, employed since NeXT? (There needs to be an
| "Apple/NeXT long-hauler oral history" or something. Chris
| Espinosa, hired 1976, is still around...)
| deergomoo wrote:
| > I always find it curious that people still tout Mac as
| this kind of "Super Polished Desktop/Workstation Unix" and
| often cite the Unix certification
|
| I've always understood people to mean that it's a polished
| desktop operating system (though that's becoming
| increasingly questionable these days) that also happens to
| run the same CLI stuff they're used to using on Linux
| servers.
|
| Pre-WSL just that was a pretty nice selling point by
| itself.
| lsllc wrote:
| It's an exercise in recreating how an Objective-C app works in
| C from first-principles. For example, the creation of the
| AppDelegate (see CreateAppDelegate() in AppDelegate.c) is
| interesting because it shows how to create a class from
| NSObject and attach the applicationDidFinishLaunching: method
| along with it's implementation in C. I've used objc_msgSend()
| before from C (to access the pasteboard from a CLI app), but
| never implemented any ObjC classes using C!
|
| It's similar how you might attempt to build a C++ class from
| only C components by creating a vtable.
| rdrsss wrote:
| Love this, if I never have to write a wrapper around objc again
| I'd be in heaven.
| LeoNatan25 wrote:
| This uses the ObjC runtime to obtain the underlying ObjC method
| implementation functions, to call directly, instead of relying
| on the runtime to call them. If you find this more elegant than
| a wrapper with some ObjC, good for you.
| icedchai wrote:
| I find Objective C more pleasant to use than C++. Maybe I'm
| crazy.
| JKCalhoun wrote:
| I did a straight C++ app for MacOS but 1) I used SDL2 and 2) it
| was a full-screen game so no Cocoa UI needed. It was kind of fun
| though in a retro-computing way.
|
| (I'm a big fan of SDL now.)
| jonhohle wrote:
| Don't people do that all the time with Qt?
| speps wrote:
| The linked project doesn't use any ObjC files at all. SDL2 has
| a bunch of Cocoa files[1] so you did use Cocoa even if
| unknowingly.
|
| [1] https://github.com/libsdl-org/SDL/tree/main/src/video/cocoa
| LeoNatan25 wrote:
| The linked project also uses Cocoa, and guess what,
| considering Cocoa itself is written in ObjC, the linked
| project also uses OBjC "unknowingly".
|
| Considering CodaFi works for Apple now, he knows. Spoiler: he
| knew 11 years ago too.
| anamexis wrote:
| The OP says it is Cocoa-less in the readme, is that not
| true?
| electroly wrote:
| It's not. Open up any of the .c files and you'll see lots
| of references to Cocoa. One of the comments refers to
| Cocoa by name! This is using objc_msgSend to call into
| Cocoa. You'd have to squint your eyes pretty hard for the
| claim in the readme to be true. What it doesn't have is
| Objective-C code, which is different than not having
| Cocoa.
| cancerhacker wrote:
| check out the clang objc rewriter - basically c++front
| for objc.
| https://www.jviotti.com/2023/12/01/understanding-
| objective-c...
| astrange wrote:
| Doesn't work anymore, especially because it doesn't
| support ARC.
| JKCalhoun wrote:
| Yeah, that's okay. It wasn't like a "purity thing" for me,
| just nice to write portable code.
| cnity wrote:
| > A little bit of this also has to do to stick it to all those
| Luddites on the internet who post "that's impossible" or "you're
| doing it wrong" to Stack Overflow questions... Requesting
| permissions in the JNI "oh you have to do that in Java" or other
| dumb stuff like that. I am completely uninterested in your
| opinions of what is or is not possible. This is computer science.
| There aren't restrictions. I can do anything I want. It's just
| bits. You don't own me.
|
| From the wonderful CNLohr's rawdraw justification[0]. I always
| enjoy these kinds of efforts because they embody the true hacker
| spirit. This is Hacker News after all!
|
| 0: https://github.com/cnlohr/rawdrawandroid?tab=readme-ov-
| file#...
| wil421 wrote:
| I like this guys spirit. Once I had to pick up old code from a
| guy with this spirit and it was f-ing horrible.
| mtillman wrote:
| I love this project (from 2014?) and perhaps my favorite part
| other than the f-u of the whole thing is the commit message
| "complete refactoring".
| shrimp_emoji wrote:
| Beats using Java
|
| Think of it as exercise: it sucks up front but you won't end
| up an obese diabetic on the WALL-E ship later.
| jbverschoor wrote:
| This would've been a lot easier to wrap my head around when I had
| to work with Objective C for the first time
| flohofwoe wrote:
| Here's something similar by Garrett Bass:
|
| https://github.com/garettbass/oc
|
| ...I also experimented a bit with parsing macOS system headers
| via clang-ast-dump and then code-generating C and Zig bindings
| but that didn't get far:
|
| https://github.com/floooh/objc-ast-experiments
|
| ...with a bit of effort and maybe using libclang instead of
| clang-ast-dump that's definitely feasible though.
|
| I guess a similar approach is used by the official C++ bindings
| for Metal:
|
| https://developer.apple.com/metal/cpp/
|
| ...also shameless plug: the sokol headers allow to write simple
| macOS applications (just a Metal canvas in a window) in various
| non-Apple languages (currently C, C++, Zig, Rust, Odin, Nim):
|
| https://github.com/floooh/sokol
|
| ...I'm cheating though and use ObjC under the hood to talk to
| Cocoa and Metal ;)
| dgellow wrote:
| I found this repo while looking for an equivalent to Win32 hello
| world[0] as a learning exercise during a long flight (with my
| work MacBook instead of my personal Windows machines).
|
| That's something I really like about Windows APIs -- I can pick a
| new programming language I want to play with, as long as there is
| a way to interface with C I can try to port the Win32 hello world
| then play around.
|
| 0: https://learn.microsoft.com/en-
| us/windows/win32/learnwin32/y...
| tredre3 wrote:
| The WIN32 API is somewhat ugly. I hate how all types are
| capitalized and their short abbreviations in arguments are
| sometimes weird. I hate how they have their own version of lots
| of standard C types that you have to be careful about (they
| weren't standard at the time, to be fair).
|
| But it's quite straightforward and easy to use. Any language
| that has FFI can call into it and build GUI apps, I've made a
| windowed Hello World in PHP with it.
|
| And it has been that way for 30+ years at this point. It's
| quite remarkable, really!
| dgellow wrote:
| Also, UTF-16 (or WTF-16 as defined by
| https://simonsapin.github.io/wtf-8/#wtf-16)
| QuercusMax wrote:
| I remember ages ago when I was about 12, I got a copy of
| Turbo C++ for Windows 3.1 for my birthday. (I had only
| written in Basic before, and wanted to learn a "real"
| programming language. My dad was a Fortran programming
| physicist, and had heard that C++ was what everyone was using
| then-a-days.) I mostly wrote simple console programs, and it
| came with the Borland ObjectWindows library with a fun GUI
| builder, but there was a section in the manual talking about
| how to write directly using the Windows API.
|
| I didn't really understand any of what I was reading, but I
| typed in the whole basic sample complete with HWNDs and all
| that nonsense. I can't remember if I could even get it to
| compile, but the idea of an event-loop was beyond my
| comprehension as a 12yo. I'm sure if I went back it would
| make a lot more sense to me, but back in 1994 it seemed like
| dark magic, especially compared to the much simpler and more
| understandable OWL components.
| cossinle wrote:
| Crazy that this has to be a thing .. Why does Objective C even
| exist anyways??
| astrange wrote:
| Because Brad Cox liked Smalltalk.
| w10-1 wrote:
| Draw a line through this 12+-year-old effort from Robert Widmann
| and his 8-year-old exercise in type-lifting Swift [1] and ask
| yourself: what is he doing now at Apple?
|
| [1] https://github.com/typelift/Swiftz
| saagarjha wrote:
| You can peek at his GitHub
| vineek wrote:
| Very nice. In similar fashion, a few years back I set out to
| create Wuhoo.
|
| Wuhoo loosely stands for W indows U sing H eaders O nly. It is an
| attempt to create a single-header library (in the spirit of STB)
| for graphics related window management, compatible with both C
| and C++.
|
| It works on Windows, Linux and Mac.
|
| https://github.com/ViNeek/wuhoo
| ks2048 wrote:
| This would seem more complete if it had a simple Makefile rather
| than an xcodeproj.
| cornstalks wrote:
| If you want to optimize this (and you enjoy pain), you can
| eliminate the dependency on objc/* headers and use compiler
| attributes and link sections to compile your code to the
| same(ish) assembly that Objective-C compiles to. I don't have a C
| example on hand, but here's a Rust example that's pretty easy to
| translate to C:
| https://github.com/objrs/objrs/blob/master/HOW_IT_WORKS.md
| MaxLeiter wrote:
| For an iOS attempt, I've often gone back to this wonderful
| StackOverflow post: https://stackoverflow.com/a/10289913
| lapcat wrote:
| This app uses objc_msgSend, which feels a lot like cheating, but
| if you simply want to avoid using nibs (while still using
| Objective-C or Swift), check out my NiblessMenu project and my
| "Working without a nib" blog series.
|
| https://github.com/lapcat/NiblessMenu
|
| https://lapcatsoftware.com/articles/working-without-a-nib-pa...
| krackers wrote:
| You can probably do a "true" pure C application (as in no Cocoa
| at all) by dropping down to the CoreGraphics layer, but a lot
| of it is undocumented.
|
| There's also Carbon (which I always assumed directly hit the
| same underlying quartz apis), but that's long deprecated and
| iirc never supported the UI portions in 64-bit
| KerrAvon wrote:
| Seeing some confusion. This is using what are effectively FFI
| interfaces to the Objective-C runtime. There's really no good
| reason to do this in production code that isn't a language
| bridge. It's not as efficient at runtime as writing the
| functionally equivalent Objective-C, because the ObjC compiler
| statically allocates class/method data structures, and it's not
| as safe, because you're bypassing ARC.
| hgs3 wrote:
| It would be nice to have something like this except for Metal.
| I'm unsure why Apple made Metal an Objective-C API when C + Core
| Foundation would suffice. One big advantage of a C API is it's
| easy to interop with other programming languages.
| AceJohnny2 wrote:
| Apple is opinionated about which languages should be used on
| their platforms, and they enforce it with these kinds of
| decisions.
|
| For example, there was a time where Steve Jobs threatened to
| forbid iPhone apps not written in Obj-C, which would have
| destroyed the cross-platform ecosystem, at Apple's expense.
| Luckily, he was talked down from being that extreme.
___________________________________________________________________
(page generated 2024-04-19 23:00 UTC)