Better Way to Build C

  Рет қаралды 32,797

Tsoding Daily

4 ай бұрын

Previous Episodes: kzfaq.info/sun/PLpM-Dvs8t0Vak1rrE2NJn8XYEJ5M7-BqT
References:
- Tsoding - Musializer - github.com/tsoding/musializer
- Tsoding Daily - The Best Coding Interview Question Ever - kzfaq.info/get/bejne/m99ma9Z8uKyucYk.html
Support:
- BTC: bc1qj820dmeazpeq5pjn89mlh9lhws7ghs9v34x9v9
- Servers: zap-hosting.com/en/shop/donation/2038e94867b5e65cab2e72abf8ad956c/
Chapters:
- 0:00:00 - Announcement
- 0:00:42 - Build System of Musializer
- 0:04:15 - Configuration
- 0:10:54 - Best Interview Question
- 0:11:42 - Taking Full Responsibility
- 0:13:10 - Boilerplate
- 0:15:25 - config.h approach
- 0:16:09 - Shortcomings of config.h
- 0:18:29 - Environment variables
- 0:19:38 - Better approach
- 0:21:31 - Generating config.h
- 0:25:46 - Second Stage
- 0:30:29 - Crossplatformness
- 0:32:35 - Shared config
- 0:33:05 - Is This Too Much Voodoo?
- 0:33:49 - Building C code is easy
- 0:34:31 - Two Stages, One File
- 0:38:34 - Testing the UX
- 0:39:51 - Multi-staging is a Powerful Idea
- 0:41:39 - Shortcomings of CMake
- 0:43:13 - "Modifying C is meh"
- 0:43:23 - Integrating Two Stages with Musializer
- 0:52:47 - Tea spill
- 0:53:09 - -D is crossplatform
- 0:54:52 - Microsoft being out of character
- 0:55:34 - Never Trust Twitch Chat
- 0:55:53 - Subcommands
- 0:58:41 - Removing Config structure
- 0:59:39 - Checking UX of adding parameters
- 1:02:49 - Including config.h and logging the stages
- 1:03:27 - Removing Config related code
- 1:04:31 - Build function per target
- 1:11:52 - Hotreload parameter
- 1:12:28 - Shared microphone feature parameter
- 1:15:34 - It's not about C
- 1:16:40 - ./build/ in search folder
- 1:17:18 - target names
- 1:18:52 - String literals in preprocessor
- 1:20:45 - MUSIALIZER_TARGET_NAME
- 1:22:20 - File per target
- 1:24:28 - nob_linux.c
- 1:25:51 - reset of the target files
- 1:27:20 - build_raylib()
- 1:30:42 - build_dist()
- 1:32:31 - nob subcommands
- 1:34:46 - Adjust defaults
- 1:35:32 - More compilation errors
- 1:36:14 - Sharing hotreload parameter config
- 1:37:42 - Testing hotreloading
- 1:38:20 - Testing disabled hotreloading
- 1:39:06 - Sharing microphone parameter config
- 1:40:21 - Testing microphone feature
- 1:41:03 - Summary
- 1:42:00 - Q: Why not pass config via cmd args?
- 1:43:30 - Outro

Пікірлер: 112
@Mozartenhimer
@Mozartenhimer 4 ай бұрын
"Nightly mode for using the application at night" 😂
@Omar-fn2im
@Omar-fn2im 4 ай бұрын
Terry Davis reference in the title, I'm really looking forward to this one
@karoI508
@karoI508 4 ай бұрын
For archival purposes: the title was "Is this voodoo magic or divine intellect?"
@0ia
@0ia 4 ай бұрын
He has left us. It is now "Better Way to Build C"
@konstantinrebrov675
@konstantinrebrov675 4 ай бұрын
If we consider that the universe is a computer simulation, then random numbers are in fact pseudo-random, the results of a deterministic process. Nothing in the Universe is truly random. Have you heard of stories of incredible coincidences that should statistically be less common than they appear in real life? This is because random numbers are usually not along the normal distribution. The distribution of random numbers can be changed via prayer and manifestation to concentrate around a specific value. Terry Davis understood this, which was his quote, "God controls random numbers". And it's true, out of chaos becomes order. So we can use chaos theory to communicate with God. Just like the ancient Chinese meditated on a question, they heated bones over a fire and cracked them, the cracks resembled Chinese characters that they would then read as the answer to that question. Or various shamanic techniques such as divination on beans, and flipping coins. Just like TV/radio is static (random) until a signal comes in and changes the image, so the presence of a thought or a question changes the random number distribution into a deterministic value. So Terry Davis created a divination computer program, that generated random numbers in response to a question, and used these random numbers as an index into a lookup table containing quotes from the Bible. The computer prompts the user to enter a question, that string is then hashed into a number which is then used as the seed for the RNG. Then a sequence of random numbers are generated, which are then mapped into a sequence of strings containing quotes from the Bible. The result is a cryptic message, from God allegedly. I've written a similar program in C++. The key is to make the lookup table for the results very large, for me it's 11,000 different strings that can be chosen from. This is to keep the modulo from looping on itself, and to give it a variety. And it actually works and produces consistent answers to my questions! It doesn't work all the time, but it works much more often than conventional statistics would assume. Perhaps every 1 out of 7 times it gives me a relevant answer to the question that I posed. To improve the results the lookup table should be as long as possible, and as varied as possible, encompassing a wide variety of answers to possible questions, such as personal development, studying, encouragement, relationships, discipline, health, and lifestyle questions.
@lievenpetersen
@lievenpetersen 4 ай бұрын
"a nightly mode, for using application at night" xD 7:43 casually roasting crustaceans
@siniarskimar
@siniarskimar 4 ай бұрын
I love how Andrew Kelley (the lead of Zig) went with the same approach as you did with nob. Why have another tool (and language in case of cmake) if you already have one that can do that.
@FullGardenStudent
@FullGardenStudent 4 ай бұрын
Odin also goes for same approach but something like this existed for over a decade now. Check out tup build system.
@Daniel_Zhu_a6f
@Daniel_Zhu_a6f 4 ай бұрын
many languages did it to some degree (most famous is Kotlin&Gradle). you don't want to invent a domain-specific language, when you can just write a library for an existing language.
@charliegnu
@charliegnu 4 ай бұрын
And I love how Tsoding hated it when he tried zig.
@talhaakram
@talhaakram 4 ай бұрын
Indeed the hardest question in programming.
@alfiegordon9013
@alfiegordon9013 4 ай бұрын
Hardest nob you say?
@henrikholst7490
@henrikholst7490 4 ай бұрын
What question?
@talhaakram
@talhaakram 4 ай бұрын
@@henrikholst7490 it is a reference to the previous title of this video: is it too much voodoo magic or is it divine intellect?
@paulzupan3732
@paulzupan3732 3 ай бұрын
@@talhaakram I remember the quote differently
@ItzHapso
@ItzHapso 4 ай бұрын
didn't know programming could be this exciting
@disusdev
@disusdev 4 ай бұрын
@TsodingDaily I don't know if it was answered, but you can compare pointers to static strings in the preprocessor because static strings are stored in the hash table. If you have two similar strings, they point to the same memory address. I'm not sure if it is a part of the standard tho; it could be a compiler-specific thing. If we use another, less popular compiler that stores strings in a different way, it will have different addresses. But works for me with clang :) Example: const char* str1 = "hello"; const char* str2 = YOUR_STRING_IN_PREP; #if str1 == str2 printf("Yes! "); #else printf("No!"); #endif
@jaitjacob
@jaitjacob 4 ай бұрын
I learn so much from you & your videos. Thank you making me a slightly better programmer.
@iWillAvert
@iWillAvert 4 ай бұрын
Only just started the video.. Musializer is one of the few projects you've done that I have learned about since discovering your channel that I have not played around with. Mainly because I don't tend to have music or anything downloaded on my PC. Now I think I'm gonna check it out and maybe rip a few mp3s off KZfaq to play around with it. 😂 Very interested in the build system. I've honestly learned an absolute ton from your videos so I'm always happy to check out a Tzozin project! 😀 Maybe some day I can even contribute but you mostly write in languages I don't know well just yet lol.
@in70x
@in70x 4 ай бұрын
This dude is hilarious why am I just finding these videos?
@lesechko
@lesechko 4 ай бұрын
Thanks for the friendly and educative content. I wonder if there is something similar on KZfaq/Twitch but Java dedicated. Suggestions are apreciated!
@ecosta
@ecosta 4 ай бұрын
Another amazing stream with loads of ideas which will help with my own build system. I'm kicking myself for not thinking about this multi-stage bootstrap concept (eventually I fell into the "CMake" trap and now I need yet another refactoring).
@ZoraAlven
@ZoraAlven 4 ай бұрын
Deep shit. Thx for the stream. Great pleasure.
@alh-xj6gt
@alh-xj6gt 4 ай бұрын
Really like where you are going with nob.
@Vlad-xh9sy
@Vlad-xh9sy 4 ай бұрын
very exciting to watch 😁
@labsendeyshent
@labsendeyshent 4 ай бұрын
23:13 - "We will be working with sisters" monkaS
@kaltwarraith5172
@kaltwarraith5172 3 ай бұрын
you ask the right questions when developing. sadly missing in much of the development world
@Czeckie
@Czeckie 4 ай бұрын
52:47 finally something I could actually recreate in my own project!
@Ansatz66
@Ansatz66 4 ай бұрын
It feels bad to have so much conditional compilation. Better to have multiple different build_musializer functions like build_musializer_linux() and build_musializer_macos() and so on, then choose which to call using #if. That way the compiler could always check for errors in the build script regardless of the chosen target, and we could keep the #endif on the screen as the #if.
@Muskar2
@Muskar2 4 ай бұрын
Even beyond that, it'd be easier to create a generic platform file that had a struct with function pointers, and then a file for each platform that each included the platform layer and assigned the function pointers to that platform. This would make it a lot easier to: 1. develop at first because you'd only need to support your own platform, and thus don't need to constantly refactor code for other platforms 2. implement a new platform because it just needs a new platform file that basically does the same things as the other platform APIs do (which isn't clustered all around) 3. be sure that all cases are always covered
@0ia
@0ia 4 ай бұрын
Just a note: I do not find it highly important to optimize making it easy to implement platforms because most times I solely support between 1 and 3 platforms (Windows/Linux/Mac). So if this structure pushes to make that easier at _enough_ opportunity cost, it's not entirely useful to me. @@Muskar2
@Daniel_Zhu_a6f
@Daniel_Zhu_a6f 4 ай бұрын
@@Muskar2 structs with function pointers seem like an overkill. it may please some FP people, but why not just switch between platform-dependent steps in the main function, at runtime? the idea that you can first define an interface and then just implement it is a tempting one, but often leads to disasters. the approach where you have step1_win, step1_posix, step2_win, step2_posix functions and if-elses in main isn't a spectacular one, but you can eyeball it and it just works.
@Muskar2
@Muskar2 4 ай бұрын
​@@Daniel_Zhu_a6f Sure it may be overkill if you're just making something small. But it's scalable, if you need it to be. Switching between platform-dependent steps in the main function at runtime tends to become verbose and hard to keep track of, in my experience. But I agree that inlining is preferred over abstraction levels, until they become necessary. I'm not sure what disasters you're referring to in this specific case though. Creating an interface boundary between the functions that will run on every platform versus the things that need to happen uniquely on individual platforms is logical, because it's a certainty that the distinction will be necessary. Making it as easy as possible to handle platform-specific bugs or implementations is something I think makes it a lot simpler to work with. But if you're making a 10k LOC library, then it probably wont be a noticeable benefit, sure.
@ecosta
@ecosta 4 ай бұрын
1:08:40 - out of my experience, this might be a problem. It is quite easy to leave some platforms go "stale"; or assume something just works but it explodes because the platform's compiler/libc/etc has weird compilation quirks.
@skreyer
@skreyer 4 ай бұрын
Shouldnt there be a dependency tracking for generating config.h, i.e. if you modify nob.c to add a new config, config. H should be regenerated automatically without the need to manually delete config.h? Btw this example also shows that one should use cmake because a dedicated build system is the only guarantee that building is performed correctly and is complete..
@sanjaux
@sanjaux 4 ай бұрын
20:43 *vsauce music plays*
@effexon
@effexon 4 ай бұрын
I was left thinking what if I like interpreted config style: no need to recompile at all config file... seems at @21:37 until this point relistened this is not taken into account, eg can ship binary and config is separate file. To clarify "each developer has their own config.h" -> this means need to always recompile even in this better approach if I understood correctly. So what if can know binary is compatible but need to modify config only in client machine(eg one developer local machine whose folders and settings are a bit different, otherwise program works exact same).
@sirynka
@sirynka 4 ай бұрын
Why haven't you moved enum with targets to the config?
@JekasObps
@JekasObps 4 ай бұрын
How do your build system know to perform config stage when you add other variables to config but an old version of config exists?
@JekasObps
@JekasObps 4 ай бұрын
I mean if you change first stage nob.c which in turn may change a config you have to skip checking if config.h exists and straight up regenerate it
@tomaspecl1082
@tomaspecl1082 4 ай бұрын
Nice, I like this.
@rogo7330
@rogo7330 4 ай бұрын
C never gets outdated == Build system never gets outdated. Though, they wanna delete K&R style for functions declaration, like this ``` int foo(a, b, c) cont char *a; int b; void *c; { ... } ``` which is literally how documentation for Xlib is done. But I think you already showed that in one of the streams.
@thebatchicle3429
@thebatchicle3429 4 ай бұрын
They don’t _want_ to remove them, they’ve literally already removed them in C23
@ZoraAlven
@ZoraAlven 4 ай бұрын
⁠@@thebatchicle3429 foken zoomers from the committee. Why they just can't get the simplest point that k&r times were times of non-highlighted syntax? I mean yeah, I'm not using that style for the obvious comfort reason, but why to exclude it..
@RandomGeometryDashStuff
@RandomGeometryDashStuff 4 ай бұрын
38:00 freepascal extra dangerous?
@maurolimaok
@maurolimaok 4 ай бұрын
Saved for the future. Today I understand nothing. In future, I will.
@anon_y_mousse
@anon_y_mousse 4 ай бұрын
Also, in case anyone needed another reason to hate C, both gcc and msvc allow a form of main that takes the environment variables as an array of strings, int main ( int ac, char **av, char **env ), so give that a try.
@thebatchicle3429
@thebatchicle3429 4 ай бұрын
That’s not a compiler extension; it’s an operating system thing. Linux and the BSDs accept a third argument but it’s optional. I’m not sure why that’s a reason to hate C? Just don’t use it, nobody does.
@anon_y_mousse
@anon_y_mousse 4 ай бұрын
@@thebatchicle3429 I assumed anyone reading this would've seen my prior post and gotten that I meant "hate" sarcastically, and it was kind of a nudge towards what Tsoding said about C. However, I never referred to the environment variables argument as being a compiler extension, and it's technically a conforming implementation to provide access to the environment, even if the standard doesn't specify it be in a third argument. It could just as easily be provided in argv past argc, or even tacked onto the command line arguments with no boundary between the two, or with an empty string, as it's up to the implementation how to provide that as long as argv[argc] == NULL.
@freezingcicada6852
@freezingcicada6852 4 ай бұрын
That whole bit in the beginning with CMake. Is exactly why I never bothered to learn CMake or build tools in general. I'd rather be a caveman basically handing a note that says type this stuff in your compiler of choice to use this shit.
@wchen2340
@wchen2340 4 ай бұрын
i didnt know cmake exists before i found myself moving away from the arduino ide to esp-idf couple of months ago. their build system is wrapped and interlocked with cmake up to a point where i didnt see myself having a chance at all to derive a "build.sh"-type notes-file that would allow me to stay in my cave. I went for the fumble-around-till-it-works approach and never looked back up till today. So definitly no divine intellect badge for me. ¯\_(ツ)_/¯
@ukyoize
@ukyoize 4 ай бұрын
I just use regular make
@PranshuTheGamer
@PranshuTheGamer 4 ай бұрын
@@ukyoize its technically also a build system
@anon_y_mousse
@anon_y_mousse 4 ай бұрын
@@PranshuTheGamer Sure, but nearly every Linux system comes with it pre-installed. Screw Windows and Mac.
@PranshuTheGamer
@PranshuTheGamer 4 ай бұрын
@@anon_y_mousse yea, wait until you see porteus
@vbachris
@vbachris 4 ай бұрын
wonder if you could create a script to ping people for live on twitch
@alib5503
@alib5503 4 ай бұрын
Does/can/should it generate compile_commands.json?
@thebatchicle3429
@thebatchicle3429 4 ай бұрын
Use bear(1) for that
@alib5503
@alib5503 4 ай бұрын
@@thebatchicle3429 I didn't test that but are you sure bear can parse output of nob as well?
@ikeofili355
@ikeofili355 4 ай бұрын
Merry Christmas y'all
@anon_y_mousse
@anon_y_mousse 4 ай бұрын
Every programming language sucks, just that C sucks the least. That's the real takeaway.
@c.Orange
@c.Orange 4 ай бұрын
tis highly adviced to read cursed tomes of eldrich knowledge to build a tolerance to finally read javaScript documentation lest one risks high chance of hysteria, insanity and / or severe brain damage.
@amigaworkbench720
@amigaworkbench720 4 ай бұрын
My venture into C unfolds like this: I'm set on crafting my own C library. Naturally, I'll include my string functions, but they must reside in heap memory. Yet, this entails the need for subsequent deallocation. Thus, I'm inclined to construct my own malloc. The catch is, I aspire to implement a form of "garbage collection," envisaging a struct (not an object) capable of allocating to a linked list, complete with IDs. This approach would facilitate the liberation of memory in cohesive groups, perpetually and so forth. Perhaps opting for C++ might offer a more straightforward solution... I firmly believe that in C, writing elongated functions that focus on accomplishing a singular task exceptionally well is the key, as that's the essence of what I recall from my days with C.
@robbugel3964
@robbugel3964 4 ай бұрын
Why not go one step further and do the build in the application itself (3 step: config -> build -> run application ... )
@voodoo5191
@voodoo5191 4 ай бұрын
cool title
@ahmedsat4780
@ahmedsat4780 4 ай бұрын
nob needs it's own repo
@thehackr258
@thehackr258 4 ай бұрын
Red Circle 🔴
@DobryWujaszekKun
@DobryWujaszekKun 4 ай бұрын
Could you include into the scene your live keystrokes next time? I'm wondering how you move in Emacs ( ͡° ͜ʖ ͡°)
@labsendeyshent
@labsendeyshent 4 ай бұрын
C-n and C-p
@jaumeguimeramarquez2244
@jaumeguimeramarquez2244 4 ай бұрын
See how to build system of C program in C.
@RedCoastLab
@RedCoastLab 4 ай бұрын
I can definitely see a three step build process being used for extending this to cross compilation as well…
@0ia
@0ia 4 ай бұрын
Now what we need next is to replace Regex with C code.
@wissambenhaddad
@wissambenhaddad 4 ай бұрын
First, azozzinnng
@uyohn
@uyohn 4 ай бұрын
Why not build raylib in it's own stage? Stage 1: generate `config.h` Stage 2: build raylib (and possibly other deps) Stage 3: build app. Or is that too much like make?
@EEEEMMMMKKKK
@EEEEMMMMKKKK 4 ай бұрын
I never understand this trend of hating programming languages, especially when large part of your code is written in that language. Like we don't have enough hate in this world... It is sad to see at 1:43:40 how you are twisting on the chair because it's hard to say something good about C(or any language) it's always more cool to just hate on something...
@lowlevelcodingch
@lowlevelcodingch 6 күн бұрын
23:13 I know what he is up to
@areshaistg
@areshaistg 4 ай бұрын
Too much voodoo or divine intellect or better way to build c
@labsendeyshent
@labsendeyshent 4 ай бұрын
Original title was more interesting
@StevenMartinGuitar
@StevenMartinGuitar 4 ай бұрын
So are you telling me that this feature extension will even makes the haters like nob?
@user-xd4nb8wm5l
@user-xd4nb8wm5l Ай бұрын
1:15:40 So use D as betterC instead!
@cheebadigga4092
@cheebadigga4092 4 ай бұрын
"c is shit" - love it :D
@diaboempessoa
@diaboempessoa 4 ай бұрын
Tsoding already done Neural Networks, which is quite OP. So I am in the wait of when he maybe tries less op machine learning techniques like Reinforcement Learning and Genetic Algorithms.
@Vulto166
@Vulto166 4 ай бұрын
Tsoding is very close to the suckless way of programing. Many suckless programs has a file called config.def.h and after you build the program for the first time you have config.h wich you can customize.
@anon_y_mousse
@anon_y_mousse 4 ай бұрын
That's not a suckless thing, it's an autoconf thing.
@Vulto166
@Vulto166 4 ай бұрын
@@anon_y_mousse autoconf can generate c header files?
@anon_y_mousse
@anon_y_mousse 4 ай бұрын
@@Vulto166 It can do a lot of things, including generate configure scripts. Check it out.
@thebatchicle3429
@thebatchicle3429 4 ай бұрын
@@anon_y_mousseit’s also a Suckless thing
@patto2k358
@patto2k358 4 ай бұрын
A neat hack, but so is C
@BanAaron
@BanAaron 4 ай бұрын
21:12 lmao
@Dimkar3000
@Dimkar3000 4 ай бұрын
You could try to builld a bigger project using nob, for example raylib.
@TsodingDaily
@TsodingDaily 4 ай бұрын
It literally fucking builds the entire raylib as part of the musializer build ffs
@Dimkar3000
@Dimkar3000 4 ай бұрын
@@TsodingDaily awesome
@nanothrill7171
@nanothrill7171 4 ай бұрын
CPP, humanity's greatest invention
@charlieking7600
@charlieking7600 4 ай бұрын
The only greater invention was Free Pascal.
@infosecholsta
@infosecholsta 4 ай бұрын
Those who do not understand make(1) are doomed to reimplement it.
@TsodingDaily
@TsodingDaily 4 ай бұрын
What's so special about topological sort and modification date checking?
@merthyr1831
@merthyr1831 4 ай бұрын
inb4 linux kernel built with nob????????
@lowlevelcodingch
@lowlevelcodingch 6 күн бұрын
ill do it
@annybodykila
@annybodykila 3 ай бұрын
Void main(void) { #if LINUX #elif MAC #elif WIN #endif Defer: Free() Free() Return 0; } Why did u copy/paste main and defer so many times.
@Mozartenhimer
@Mozartenhimer 4 ай бұрын
Tsoding is wrong on the internet and let me tell you why: I'm a fan of letting the compiler do all your parsimg building a config.h header, but moving so that the build code only builds on the platform you're building on is hairy because as Mr. Tsoding demonstrated he's got a bunch of compile errors on windows and crapple, that can't be tested on Linux. Generally I try to move my preprocessor statements into the language ASAP so that it becomes normal code.
@cgnico3978
@cgnico3978 4 ай бұрын
not scalable but cmake is bloated
@tamrix
@tamrix 4 ай бұрын
I agree. C is shit. But it’s fun haha.
@lordadamson
@lordadamson 4 ай бұрын
why do you cringe at the word 'scalable'? 😂