Magnificent presentation, thank you. Other professors make it seem too difficult because they don’t properly address with simple words when programming. They would give the correct definition of pthread_join, but then not clarify that it is basically a wait() function for threads. They were like this all the way through the lessons, so this was tremendous help, thank you.
I discovered your channel 3 years ago when I needed help with my "Programming 2" class which involved lists, pipes and processes and couldn't figure out how they work. Now here you are again coming to my rescue perfectly explaining in 8 minutes what my teacher cannot explain in 2 hours. Thanks for preventing me from dropping out of Engineering.
I can`t find right words to fully express how simple and great this lesson starts thread theme... like u`ve said that I`d heard, read, seen so many times, but in an absolutly clear way and now I`m starting to feel that threads aren`t that scary and wierd - thank u soooo much!👍
I've seen my fair share of youtube tutorials, and I must say yours are top-notch. Thank you for your hard work and for sharing your passion so selflessly. You do make one feel welcome here.
I've been watching most of your videos about threads. They've been really useful to refresh my concepts that I haven't been using from a long time!!! Thank you so much for the great content you created!!!
just took a year off from my degree and completely forgot about how to use P_threads and this basically caught me back up to speed, incredibly good explanation.
hello, everytime i got the learn somethings new for a project at 42, you are here with a video. the starting point for philosophers :) Are you a 42 students ? thanks you for all your stuff :)
As a little update: in the "void routine()" function you should add the parameter void *arg so there won't be any errors: void *routine(void *arg){...}
It's the official C/C++ extension from Microsoft but it doesn't show descriptions on Windows or Mac because the header files don't have them. Those descriptions only exist on Linux it seems
This is helpfull, thank you I will watch it all. I have have a question, I'm learning Go it has routine, does it similar to thread in c? (because Go was build base on C, I believe)
3:00 Why do you need ampersant "&" ? Function name without brackets is already returning the address of the function. This is equal: &function_name == function_name
Both ways seem to be accepted by the standard. I just thought it was easier to understand with the ampersand. Without the ampersand it's technically an implicit cast from function type to pointer to function type
is it possible to give a thread a timeout, so if my function is not done executing in some time ebcause it is hanging or something, have the thread return
Yes, there is the function pthread_kill ( man7.org/linux/man-pages/man3/pthread_kill.3.html ) You could create another thread that waits for a while and pthread_kills the thread you want to timeout
I saw in a tutorial comparision between user level threads and kernel level threads that Multithreading isn't possible in user level threads. First , I would like to make sure and classify the threads that we are creating here . They are probably user level Threads because according to their definition they are created by the user just like we did here. But the thing that I don't understand is , how multithreading not possible user level Threads? Isn't that we did in our case executing two threads end getting same output twice called multithreading?
I researched for a while to find an answer and, for these specific videos running pthread on this specific OS (Linux) we are mapping each user-level thread created using pthread_create to a kernel-level thread. So you could say we are using kernel-level threads in this video. But all this is dependent on the underlying operating system and their implementation of pthread. Here is a clear answer (and more details to your question if you are interested in reading more about it): stackoverflow.com/a/53958312
Basically it's to check if the pthread_join was successful. Of course, in real-world projects you would handle the errors differently, not just return an error code probably.
How do we know how many cpus are involved in multiple threads? Let say I have 8 cpus and I created 8 thread, how do we make sure that each cpu gets exactly one thread? And even if we are just interested in knowing how these 8 threads are split among 8 cpus, how we could find out this?
We don't. The scheduler is the one that handles this problem. Although, usually, these high-computing work is assigned to its own CPU core in most schedulers if there's nothing much else going on in the background. Although, again, there is nothing guaranteeing this
Is there any difference between posix threads & thread from std namespace? Like performance or user friendly? How to decide which one to use and when ?
pthreads (posix threads) are Unix-specific (available in C/C++) and std::thread is part of the C++ standard library. Both are just interfaces for working with (usually) the same entities under the hood. So, aside from the interface overhead, there shouldn't be any differences really
You have to understand that pthread lets you create multiple threads in the same process. So any thread you create are actually running under the same process. If, say, you create 4 threads to do some hard work that takes a while, but, in the main function, right after creating them, you reach the return statement then the process itself terminates and the threads fail to completely finish their work. Basically when calling pthread_join for a certain thread, it waits until that thread finishes execution
What I have understood about the function pthread_join() is that , it waits until the thread passed in its first argument is terminated. That logically means that removing the call of this function doesn't stop the thread from executing, because that's the job of the pthread_create() function . But when I tried so and removed the call of the pthread_join() function I didn't get an output, which means the thread t1 didn't execute. Why?
I Think I have just found the answer. The function pthread_join() 's job is to make the calling thread wait until the created thread finishes execution. Here main() represents the calling thread. In case of removing the pthread_join() the main thread will finish exection throught return 0 and the program ends before the execution of the thread t1. That's why I had no output.
That's correct. This is different from processes where they can still execute on their own even if the parent process stopped executing. Threads simply terminate execution when the process that created them
Great video thanks. Can you please help explain why you only wrote if statement in pthread_create and pthread_join, but no else statement? I understand if pthread_create doesn't return 0 then it's an error, but I'd think there needs to be an else statement to tell the program what to do when there is no error.
When there is no error it just simply continues its execution like expected. if (a == b) { return; } printf("a doesn't equal b "); Basically, in this code above, because we have a return statement in the if block, the code below only executes if the statement a == b is false (if it was true it would've returned out of the function and never execute anything below it)
@@CodeVault Thanks, I understand what you are saying, but, your code is more like - int main(int argc, char* argv[]{ int a; if(a != 0){ printf("Error"); } return 0; } If my understanding is correct, when a==0 is true, the program will just simply run to the end without printing anything.
How do i prevent memory leaks in Pthreads? The first time i execute the program, answer is right but if i add a while loop, it is providing incorrect values.Even after adding pthread_join, same thing is happening.
Hi, first of all THANK YOU for all the great and clear videos, you should definitely be looking for a teaching career. I would like to ask you the link of the settings for the json files. I can't find it anywhere. I looked in the "Unix processes" playlist but they are different. Thank you in advance.
If pthread_create returns 0 that means it was successful. If it returns anything else, we exit the program because something wrong happened with creating a thread
No, it's using the pthread library which is only available natively on Unix systems. You could install WSL on Windows and run Linux under Windows that way.
Hi, I am using Ubuntu 20.04.4 LTS. On VSCode I can't include the header , only works. I can locate pthread.h in /usr/include/pthread.h. How do I include the header in VSCode?
@@CodeVault I'm passing a number like sleep(3) after printf("something") Then again printf("something") but instead of waiting in the middle it waits at the start for 5 seconds and prints both at the same time
You can't do that with threads since they run on the same process. Signals are used to communicate between processes, not threads. If you want to synchronize threads just use any of the tools we discussed in the course: semaphore, condition variables, mutexes etc.
That simply controls which thread executes the handler for those signals. Certain signals might be process-wide. See: man7.org/linux/man-pages/man3/pthread_kill.3.html (in the Notes section)
I've tried adding pthread in tasks.json but it just doesn't seem to work when I run the program using vscode. It works through the terminal but not vscode. It still gives the undefined reference error. Is anyone able to help?
@@CodeVault I'm using ubuntu 20.04. I compiled the file using a buildtask where I included '-pthreads' and when I execute the code by typing './threads' in the vscode terminal, it works properly but it doesn't work when I press the run code button or through the keyboard shortcut ctrl+alt+n This might be tedious but I can't seem to figure out the problem
Thank you so much for this beautiful explanation, I have a doubt pthread_join() is not exiting itself in my machine. Is it compiler configuration which is letting this happen or is it something else?
Hello, how are you so sure that the threads are operating in parallel i.e. on separate processors/cpus? The same effect can also be achieved by context switching ?
You're right, I'm not sure. But it's just to simplify things and, for most purposes, it's almost the same thing. If we run 4 threads on a 1 core CPU and they context switch at the right times it's like running all of them in parallel... just takes longer. And, the thing is, with multi-threaded programming, assuming that threads do in fact run in parallel is better since then you have to think about race conditions and the like.
If your critical section is the majority of the code executed by each thread, the serialized version might be better (since it doesn't have to do all the locks and unlocks).
@@CodeVault So you can develop on a Windows machine over ssh. So I work in 2019 and it deploys on my Pi4. I found it... Go to Project Properties > Configuration Properties > Linker > Command Line Add -pthread to Additional Options box and Apply.
@@thedarkglovemusic Hi Matt, do you mind to share more on how to add the -pthread? somehow my VS2019 dont have such Project Properties > Configuration Properties > Linker > Command Line.. I'm using CMAKE by the way.
@@wkl3968 I don't know if using cmake makes a difference... I'm no expert so am limited help but be aware that there seem to be several windows that look very similar so it looks like the option is not there I had the wrong window open. Hope that helps.
You've been such an amazing help for my Operating Systems class. Thank you, thank you, thank you
You're coding operating systems... In java?
@@atiedebee1020 im pretty sure she’s coding in c and linux because the video is in c and in a linux env
@@nonyabizness577 I'm confused, as I don't know where I got java from
@@atiedebee1020 hahahahaha
Magnificent presentation, thank you. Other professors make it seem too difficult because they don’t properly address with simple words when programming. They would give the correct definition of pthread_join, but then not clarify that it is basically a wait() function for threads. They were like this all the way through the lessons, so this was tremendous help, thank you.
I know you get this a lot, but your videos on C are a godsend! You've really helped me and countless others to succeed in our education.
yeah I watch his videos before working on stupid college projects
I discovered your channel 3 years ago when I needed help with my "Programming 2" class which involved lists, pipes and processes and couldn't figure out how they work. Now here you are again coming to my rescue perfectly explaining in 8 minutes what my teacher cannot explain in 2 hours. Thanks for preventing me from dropping out of Engineering.
I can`t find right words to fully express how simple and great this lesson starts thread theme... like u`ve said that I`d heard, read, seen so many times, but in an absolutly clear way and now I`m starting to feel that threads aren`t that scary and wierd - thank u soooo much!👍
I've seen my fair share of youtube tutorials, and I must say yours are top-notch. Thank you for your hard work and for sharing your passion so selflessly. You do make one feel welcome here.
I've been watching most of your videos about threads. They've been really useful to refresh my concepts that I haven't been using from a long time!!! Thank you so much for the great content you created!!!
Taking an Operating systems class, and you have been a great help throughout the course!
This is the best channel for C programming! Thank you!
just took a year off from my degree and completely forgot about how to use P_threads and this basically caught me back up to speed, incredibly good explanation.
Binging your videos like I binged Money Heist!! literal Bella Ciao feeling in my mind for my C rejuvenation!!
Perfect! Thanks for your job Sir!
Very clear and straightforward. I am amazed by the quality of the presentation. Thank you !
i love your videos man learning threads rn is a pain but you make it easier
I wish you more subscribers dude...you deserve them all.
hello, everytime i got the learn somethings new for a project at 42, you are here with a video. the starting point for philosophers :) Are you a 42 students ? thanks you for all your stuff :)
it's much more clear than my professor, thank you!
*Thanks to my master, CodeVault, I will pass the operating systems course with an A.*
so did u pass with A grade ?
saving me bratannnn, spasibo bolshoye
As a little update: in the "void routine()" function you should add the parameter void *arg so there won't be any errors: void *routine(void *arg){...}
Yep, I left that out for the first videos so it doesn't get confusing. You shouldn't get an error unless you're using g++ to compile your project
Great Lesson !!! Thank you !!
Best teacher on the web. WP
Thank you, very clear understanding of code
Amazing class, this you won't even after paying!
Dude u are very good I like your classes, thx for the content It will be such a greate help for me
thank you for the series I passed my exam on the second try after watching your videos, our professor didnt explain it well
Thank you sir, your videos are really very helpful for me.
Great tutorial! Very clear and straightforward.
Your course helped me a lot dude, thank you, thanks a lot
i love you so muccchhhhh codevault
you are better than most of professors teaching c in china
If you are here from 42 👍😉
What project were you doing and which circle?
@@shenghongzhong I finished minishell and now I do philosophers in circle 3 and you
Yes, for push_swap. I want to have realtime visuals of the stacks for fun.
Great video! Could you tell us what VSCode extension you are using for function descriptions when you hover over them? Thanks!
It's the official C/C++ extension from Microsoft but it doesn't show descriptions on Windows or Mac because the header files don't have them. Those descriptions only exist on Linux it seems
@@CodeVault Oh, that's a shame... Thank you very much for your response!
amazing teacher. thanks for this!!! :))
thank you, thank you, thank you 🚀🚀
Great tutorial - thank you very much!
is there a package in atom that show function's prototype like vs at @1:29 ?
I'm not familiar with Atom, sorry
saved me for my computer system fundamentals exam
Amazing teaching !
Спасибо!
Thank you very much!
@@CodeVault Many thanks for fostering of my transformation from devops to the programmer with understanding low-level(basic I believe) principles!
Thanks for tutorial!!! One comment (unless I am wrong): it would make it cleaner to return NULL in all the void* functions
You're not wrong. It was an oversight and indeed the void* functions should return NULL if nothing else
Great explanation! thanks very much
This is helpfull, thank you I will watch it all. I have have a question, I'm learning Go it has routine, does it similar to thread in c? (because Go was build base on C, I believe)
I am not familiar with Go, sorry
I think if you're using Cmake the dependent libraries options are automatically set for compile/link
Just use GCC (or make) for small projects (or maybe even larger ones). You will have less headaches overall
Thaks! you are the "Julio Profe" for C
3:00 Why do you need ampersant "&" ? Function name without brackets is already returning the address of the function.
This is equal:
&function_name == function_name
Both ways seem to be accepted by the standard. I just thought it was easier to understand with the ampersand. Without the ampersand it's technically an implicit cast from function type to pointer to function type
@@CodeVault Thank you for a fast answer.
is it possible to give a thread a timeout, so if my function is not done executing in some time ebcause it is hanging or something, have the thread return
Yes, there is the function pthread_kill ( man7.org/linux/man-pages/man3/pthread_kill.3.html )
You could create another thread that waits for a while and pthread_kills the thread you want to timeout
This is only topic that I had to refer to other channels to learn. Now issue resolved
thank you so much this really helped me a lot!!!
nice and clear explanation!
I saw in a tutorial comparision between user level threads and kernel level threads that Multithreading isn't possible in user level threads. First , I would like to make sure and classify the threads that we are creating here . They are probably user level Threads because according to their definition they are created by the user just like we did here. But the thing that I don't understand is , how multithreading not possible user level Threads? Isn't that we did in our case executing two threads end getting same output twice called multithreading?
I researched for a while to find an answer and, for these specific videos running pthread on this specific OS (Linux) we are mapping each user-level thread created using pthread_create to a kernel-level thread. So you could say we are using kernel-level threads in this video. But all this is dependent on the underlying operating system and their implementation of pthread.
Here is a clear answer (and more details to your question if you are interested in reading more about it): stackoverflow.com/a/53958312
Many thanks!
Nice video. I still didn't get the last part with the if statement. Why that?
Basically it's to check if the pthread_join was successful. Of course, in real-world projects you would handle the errors differently, not just return an error code probably.
@@CodeVault Got it. Thank you so much.
you are a life saver
How do we know how many cpus are involved in multiple threads? Let say I have 8 cpus and I created 8 thread, how do we make sure that each cpu gets exactly one thread? And even if we are just interested in knowing how these 8 threads are split among 8 cpus, how we could find out this?
We don't. The scheduler is the one that handles this problem. Although, usually, these high-computing work is assigned to its own CPU core in most schedulers if there's nothing much else going on in the background. Although, again, there is nothing guaranteeing this
Thank you!
Thank you very much! You saved me in my OS class!!!!!!
Is there any difference between posix threads & thread from std namespace?
Like performance or user friendly?
How to decide which one to use and when ?
pthreads (posix threads) are Unix-specific (available in C/C++) and std::thread is part of the C++ standard library. Both are just interfaces for working with (usually) the same entities under the hood. So, aside from the interface overhead, there shouldn't be any differences really
your video was very helpfull to me
thank you !!
how to setup pthread.h library under vs code? Please help me.
As I said in the video, just add -pthread to the gcc command. In VSCode that should be adding in tasks.json under the args array.
i did not understood the use of pthread_join properly. what if we try running this program by commenting the pthread_join?
You have to understand that pthread lets you create multiple threads in the same process. So any thread you create are actually running under the same process. If, say, you create 4 threads to do some hard work that takes a while, but, in the main function, right after creating them, you reach the return statement then the process itself terminates and the threads fail to completely finish their work.
Basically when calling pthread_join for a certain thread, it waits until that thread finishes execution
How do you get VS code to show the pop up with the different arguments, for things such as pthread_create?
It should by default do that if you have the C/C++ extension installed
Thank you so much!
What I have understood about the function pthread_join() is that , it waits until the thread passed in its first argument is terminated. That logically means that removing the call of this function doesn't stop the thread from executing, because that's the job of the pthread_create() function . But when I tried so and removed the call of the pthread_join() function I didn't get an output, which means the thread t1 didn't execute. Why?
I Think I have just found the answer. The function pthread_join() 's job is to make the calling thread wait until the created thread finishes execution. Here main() represents the calling thread. In case of removing the pthread_join() the main thread will finish exection throught return 0 and the program ends before the execution of the thread t1. That's why I had no output.
That's correct. This is different from processes where they can still execute on their own even if the parent process stopped executing. Threads simply terminate execution when the process that created them
Great video thanks. Can you please help explain why you only wrote if statement in pthread_create and pthread_join, but no else statement? I understand if pthread_create doesn't return 0 then it's an error, but I'd think there needs to be an else statement to tell the program what to do when there is no error.
When there is no error it just simply continues its execution like expected.
if (a == b) {
return;
}
printf("a doesn't equal b
");
Basically, in this code above, because we have a return statement in the if block, the code below only executes if the statement a == b is false (if it was true it would've returned out of the function and never execute anything below it)
@@CodeVault Thanks, I understand what you are saying, but, your code is more like -
int main(int argc, char* argv[]{
int a;
if(a != 0){
printf("Error");
}
return 0;
}
If my understanding is correct, when a==0 is true, the program will just simply run to the end without printing anything.
thank you so much
How do i prevent memory leaks in Pthreads? The first time i execute the program, answer is right but if i add a while loop, it is providing incorrect values.Even after adding pthread_join, same thing is happening.
Can you share the code? I can't exactly tell what you're doing wrong
what is the API you talked about ? I've been searching in Google - can you help me with it ?
Ohh, I was just talking about the pthread API there: man7.org/linux/man-pages/man7/pthreads.7.html
can you please make a video about sockets? my final exam is coming up and I have no idea how they work !!
oh my goodness, me too!
I am not in school but would love to learn about sockets using C
Hi, first of all THANK YOU for all the great and clear videos, you should definitely be looking for a teaching career. I would like to ask you the link of the settings for the json files. I can't find it anywhere. I looked in the "Unix processes" playlist but they are different. Thank you in advance.
Here's the video related to setting up vscode: code-vault.net/lesson/ublnbln8uf:1603733528013
@@CodeVault You are just amazing!
You are very good at explaining things... Congrats :)
Thank you! 😃
thank you so much
Good morning. Do you have a video explaining function that return void *?
There's a video explaining what void* is: code-vault.net/lesson/qon6f2tjor:1603733520405
Those functions return exactly that data type
@@CodeVault Thank you so much! I will check it out.
Hi Sir,
could you please tell again how this if condition make safer our code and didn't understand this condition "!=0 " . Please reply anyone.
If pthread_create returns 0 that means it was successful. If it returns anything else, we exit the program because something wrong happened with creating a thread
Thank you! But is this only for Linux? Does it work in Windows as well?
No, it's using the pthread library which is only available natively on Unix systems. You could install WSL on Windows and run Linux under Windows that way.
what code edtor is he using
Hi, I am using Ubuntu 20.04.4 LTS. On VSCode I can't include the header , only works. I can locate pthread.h in /usr/include/pthread.h. How do I include the header in VSCode?
I found the problem. In tasks.json I changed "command": "/usr/bin/g++" to "command": "g++".
Idk why but when I'm using sleep()
It is not stopping there :(
Plz help
From the documentation, you need to pass in the number of seconds you want to wait for
www.man7.org/linux/man-pages/man3/sleep.3.html
@@CodeVault I'm passing a number like sleep(3) after printf("something")
Then again printf("something") but instead of waiting in the middle it waits at the start for 5 seconds and prints both at the same time
Make sure you add a
at the end of the string you are trying to print to flush the buffer
@@CodeVault yes sir now its working
Thank you very much 🙏🙏
how to use user defined signals with threads ? More specifically i want to signal a thread and pause that thread
You can't do that with threads since they run on the same process. Signals are used to communicate between processes, not threads. If you want to synchronize threads just use any of the tools we discussed in the course: semaphore, condition variables, mutexes etc.
@@CodeVault pthread_kill ? for Posix thread seem to work. What is problem with that?
That simply controls which thread executes the handler for those signals. Certain signals might be process-wide. See: man7.org/linux/man-pages/man3/pthread_kill.3.html (in the Notes section)
Could `perror` be used to print an error message on why a `pthread_create` or `pthread_join` failed?
Of course!
I like using fprintf(stderr, "format string", ...);
Since it allows for format strings and parameters
why the parameters in the main function? can someone help?
It's just the standard. There is this video explaining what they are exactly: code-vault.net/lesson/dbijqbwu2a:1603733526118
How can I join to your Discord server?
At this link: discord.code-vault.net/
Great series.
you don't actually need to pass a pointer to a function, just the function name should be enough. At least in c99.
what compiler are using , and what version?
gcc 6.3.0
Great Video, love to study with your videos. :)
Great video!
Can you please make a video on pthread conditions and Semaphores in C (Synchronization).
Thank you again.
Yes, expect to see videos on these topics too
Why the name is pthread_join whereas it is waiting for execution of the thread?
I actually have no idea. Now that you point it out it does seem counter-intuitive to call it pthread_join and not something like pthread_wait
I've tried adding pthread in tasks.json but it just doesn't seem to work when I run the program using vscode.
It works through the terminal but not vscode. It still gives the undefined reference error. Is anyone able to help?
Double check you're running the correct build task, also, how did you compile it in the terminal when it worked? Are you trying this on Windows?
@@CodeVault I'm using ubuntu 20.04. I compiled the file using a buildtask where I included '-pthreads' and when I execute the code by typing './threads' in the vscode terminal, it works properly but it doesn't work when I press the run code button or through the keyboard shortcut ctrl+alt+n
This might be tedious but I can't seem to figure out the problem
@@CodeVault is it possible that it might not be using the build task I created when I press the run code button or use the shortcut?
Make sure that in launch.json, the preLaunchTask matches the name of the compilation task in tasks.json exactly
sorry, why the function has a pointer?
It's the return type, a void pointer (void*). Here's a video on the topic: code-vault.net/lesson/qon6f2tjor:1603733520405
Thank you so much for this beautiful explanation,
I have a doubt pthread_join() is not exiting itself in my machine.
Is it compiler configuration which is letting this happen or is it something else?
What do you mean by "exiting itself"?
@@CodeVault my main function is not ending it's stuck in infinite loop I think
How to print process Id and thread id knowing that threads are executing within the same process
I talk about getting the thread id in this video: code-vault.net/course/6q6s9eerd0:1609007479575/lesson/18ec1942c2da46840693efe9b5210e1b
Is threads important for cyber security in C?
I guess so. If the software you're trying to secure uses threads, race conditions and other issues of the like are really nasty vulnerabilities
Thank you! It really helped me
where are you from?
Romania
Amazing 🤩
Hello, how are you so sure that the threads are operating in parallel i.e. on separate processors/cpus? The same effect can also be achieved by context switching ?
You're right, I'm not sure. But it's just to simplify things and, for most purposes, it's almost the same thing. If we run 4 threads on a 1 core CPU and they context switch at the right times it's like running all of them in parallel... just takes longer. And, the thing is, with multi-threaded programming, assuming that threads do in fact run in parallel is better since then you have to think about race conditions and the like.
@@CodeVault Thank you, I had struggled so much with this topic.
Why is my parallel version slower than the serial version ? .Did anybody face this issue ?
If your critical section is the majority of the code executed by each thread, the serialized version might be better (since it doesn't have to do all the locks and unlocks).
Thanks for this. Do you know how to add the argument "-pthread" when using VS2019 (developing on raspbian)?
Hmm... VS2019 on raspbian? Wasn't Visual Studio only for Windows? Or am I missing something
@@CodeVault So you can develop on a Windows machine over ssh. So I work in 2019 and it deploys on my Pi4.
I found it...
Go to Project Properties > Configuration Properties > Linker > Command Line
Add -pthread to Additional Options box and Apply.
@@thedarkglovemusic Hi Matt, do you mind to share more on how to add the -pthread? somehow my VS2019 dont have such Project Properties > Configuration Properties > Linker > Command Line.. I'm using CMAKE by the way.
@@wkl3968 I don't know if using cmake makes a difference... I'm no expert so am limited help but be aware that there seem to be several windows that look very similar so it looks like the option is not there I had the wrong window open. Hope that helps.
great explanation! thanks!