In 54 Minutes, Understand the whole C and C compilation process

47.51k views9186 WordsCopy TextShare
Mike Shah
►C Series Playlist: https://www.youtube.com/playlist?list=PLvv0ScY6vfd8j-tlhYVPYgiIyXduu6m-L ►Find...
Video Transcript:
what's going on folks in this video i'm going to talk about how we compile software it's going to be a little bit specific to c and c plus plus programmers but the process applies to pretty much every language that you use whether it's java javascript python this process of how do we take code from a source file how does our computer parse that code to make sure that it's valid check for errors and then ultimately generate a program that runs so let's go ahead and walk through the compilation pipeline so what i'm going to talk
about in this video is this basic process where we're going to start off with some source file here source.c or cpp and i'll use cpp for this example for c plus and this is where we start here just our text file that we write and then we actually send our code into the next stage which is known as the preprocessor and the preprocessor is used for things that start with a pound symbol so you do pound include pound define or pound if statements in your code so if you've ever seen these in c or c
plus plus code and want to know what they mean then we're going to walk through that process afterwards our preprocessor then takes our source file the source.i and then finally we get to the compiler and the compiler's job is to generate some sort of intermediate representation of your code and then some sort of assembly of your code so here's where you actually get the ones and zeroes for your machine or often you'll get the assembly output in some form so maybe an instruction like move some value like one to some register so that's what we're
getting in this stage and then in the next stage you might have an assembler such as asm that's taking in your source dot s file and that's actually generating valid machine code for your architecture so whatever computer you're running on here maybe it's a fancy mac m1 maybe it's an intel machine maybe it's an arm machine whatever this machine is here that you're using here to run your program the code that's compiled from this assembler is assembled and an object or binary file is created so that's this next step here so i get a source
dot o file and then we're not quite done yet most times when we're working in cnc plus plus here we have to go through one more stage and that's the linker stage so here's our linker and this is where we bring in other libraries and they might be other.o files like if you're using commands like printf for example if you're a c programmer you'll bring in printf.o some other assembly file that's been compiled to an object file and it's going to get glued into the final executable file and then you might also have other types
of files linked in by the dynamic linker so this part's the static linker and this part's the dynamic linker and this is if you're running on a machine like a linux machine which i'm going to demonstrate these are your so files your shared libraries that are dynamically loaded into your program windows users might be familiar with dlls mac users.dylib but these are files or libraries that are going to be shared amongst many executables and can be loaded at runtime they're compiled in slightly different way that i won't dress address directly here but i'll show you
how to which those libraries are but those are brought in during the linking stage and it's important to take a look at this linking stage here because oftentimes you might have different errors in your linker that you have to resolve than your code when you're compiling for example so it's just something to keep in mind when you're doing some bug hunting if you've ever seen an error like undefined reference that's usually because something wrong is going on in your linker okay so that's the idea there so what i will now show is finally after we
get through the linking stage then we have our executable so whatever we want to call it in linux we would just do dot slash source windows users would know this is source.exe mac users maybe source.app but that's the final program that you get to double click on or run on the terminal and compile your code so what i want to do is just write a simple hello world talk about some of the different stages individually in this lesson and how you can peek inside and see what each of the stages are doing and then also
talk a little bit about some of the common flags that you might pass to compiler for working with libraries in this linking stage so the dash capital i flag dash capital l dash lowercase l these common flags that you'll often see where they come into play and we'll build a little project to do that so if i've enticed you to watch the rest of the video it'll be a full lesson but hopefully this is the video that'll take care of problems and bugs just understanding how you build software into the future so with that said
let's go ahead and dive in a little bit okay so i've highlighted the compilation pipeline here the things we're going to talk about the different flags and this whole pipeline here but in order to get started we're going to need to have a file to work with and compile so what i've done is just created a directory here it's empty right now and i'm just going to create a c plus file you can follow along in either c or c plus plus and in fact you can probably follow along in many other compiled languages that
compile things to executable maybe languages like the d language or pascal for example but we're going to use c and c plus plus so what i'm going to do on the right side of the screen again is just create a file here i'm going to call it source.cpp and this is going to be a file that contains a piece of code in it and i'm just going to write a little function here i'm just going to call it i'm just going to take an integer a and b and just return the sum of these values
a plus b it's a very simple function here and let's go ahead and just try to compile this file here so i'll leave the source code on the top here and i'm going to split my window here using tmux so that we can see things in both views here so i can just type in g plus plus and then i can type in the file that we want to compile which is just going to be source here and i can hit enter and you're going to see that's going to give some errors about undefined reference
to main and so on because we need a main function or an entry in our program so let's go ahead and write out the rest of this program here because what i'm going to do just to sketch things out a little bit as i'm going to create three files here i'm going to create source dot cpp i'm going to create source dot hpp and then i'll create a main dot cpp file the main.cpp file will be our entry the source.hbp is going to be a file that we would include to get some functionality so this
is our interface or our functions and our source.cpp is going to be an implementation and i'll just work with something very simple here like that add function here so let's go ahead and create those files here so we've got our source file here so i'll go ahead and just annotate it here just in case you're not clear with them what's going on here and we'll need to create our other files here so let's go ahead and split this window here and create source.hpp and create the source here i'll make this a little bit smaller just
so you can fit everything on this window here source.hppp and all this is going to do is make a note that there is a function called add here and that it takes in a integer two integers as the parameters and returns an integer as a result as we're showing here that's a relatively trivial program here okay so let me go ahead and just leave this here and i'll go ahead and create one more file here this is going to be our bain.cpp so our main cpp is going to be our entry point into the program
and we're just going to return 0 and i'm going to include our source.hpp file so i need to include source.http okay and here we have all of our files included and we can see them all here and there really isn't too much to them they're relatively straightforward source files here so let's go ahead and try now to compile our program and i'm going to just start with the main for now here okay so i'll do g plus plus and our main file and hit enter usually when we do this we get an a dot out
file and i can write a dot out and it doesn't really do anything now just returns zero so we'll want to actually return a result or print something out but what is actually going on here though is i want to take a closer look at this first stage here because we've compiled our file here we have gotten a binary but all of these steps here in between have actually been hidden from us so what seems like magic all these different steps have been omitted from us and we've just gone from our source file to the
final executable and this is great but often we have to debug or build larger software it's important to know how each of these steps all fit together so let's go ahead and look at the first stage which is the preprocessor here so while we're analyzing the preprocessor how can we see what's going on in this main file here i'm going to make this a little bit smaller here just so you can see everything on the screen for just a moment here in fact that might be a little bit too small so let me just leave
that medium font here but the idea is when i just type in g plus plus this is the compiler and this is the file that we're compiling ultimately to executable and by default it'll be a out if we don't give it a name let's give it a name here dash o and prog for program here and that will again generate this executable file here so i can remove the a dot out and just have that here so this is the file that we can execute but again how did we get there so from our main
file the preprocessor step will actually handle all the things that begin with a pound symbol things like the include this is one way that we can do conditional compilation that is to bring in files or source code that we need or perhaps evaluate things at compile time so we can have if or end if statements but what i want to show you here is just the fact that if i run our main here and i patched it past the argument dash e this will output what the preprocessor sees so you'll notice that this is just
dumping to the terminal the text here you can see our int main here as we compiled our main source file but you can also see that this int add function which comes from our source.hbp was pasted in its place so anytime you see include you're literally doing a copy and paste okay so that's important to understand that because that's how we know that this function would be available here this add function so now in my main source code let me go ahead and we can make a call to our add function and do 2 and
3 here so now if i run this code and try to compile it it will it'll still give an error here but it knows that this function is available here it says it's just undefined here so we need to do a few more steps but again if i run it in the preprocessor we'll see okay this function exists somewhere and if i want to promise that it exists somewhere and that the implementation will be included i can type in extern in to be very explicit about it but by default all these functions are externally available
somewhere so this extern can be omitted that's basically saying yeah we promise that this function is available its definition will be in another file so for example in the source.cpp file again i can still try to compile this it's still going to complain and say an undefined reference to add into int because it knows about it it didn't give us a syntax error but later on in the process it's saying yeah we don't know about this so for example just to show the difference on the errors if i don't include this file and i compile
it it'll say air add was not declared in this scope because it doesn't know about the function add but when i include this it'll say yeah of course we know about add it's still here it's not a syntax error we know that function is available but it's just undefined how do we do the add and that's in the source.cpp so we can resolve this by adding in the source dot cpp file here and then if i run it we'll say okay compile main.cpp and source.cpp so now i know about the implementation so that's why you'll
often see programmers compile things all in one line like this or sometimes if you're a little bit lazy you can just put a wildcard here and do star.cpp and that'll compile all the c files together i don't particularly like this it's a shortcut but i want to know exactly what files i'm compiling so i just write them all out one at a time okay but back to this preprocessor idea where i'm showing that during the pre-processing stage when i just emit things with dash capital e i'm essentially again just doing a copy and paste of
whatever is inside this file into my file that i'm trying to compile so what happens if i for instance accidentally include the same file twice whether by accident here or again in a very large project that this could occur so if i run my preprocessor you'll see that i have extern int add included here two times so i'm going to go back and do our trick and say well okay we wanted to build this so i have main.cpp and source.cpp i hit enter here and i try to run it um and this time it's actually
okay um but the danger here is that if you include the same file uh twice let me make sure i've saved this then it might get confused as to the definitions that you have here so for example in our add function here i will also include source.hbp because we're including the definition here and then anytime we compile this file what we really want to do is include the header file with it okay so let's go ahead and compile uh oops looks like i added an additional uh token here so let me just save and if
i rerun this it looks like it's it's doing okay here so it's not complaining about multiple definitions or or any of this issue but this is the danger that it could and i'll show you a common error that you're going to find in c plus projects where a lot of folks will just go ahead and define implementations uh or when you're declaring a class for example in the hpp file so again let's see what happens if we try to compile and this time you'll get the error that says redefinition of int ad ad here because
we've included this file multiple times in multiple places we're just doing the uh include here and essentially copy and paste here so you get sort of these uh weird issues here so even if i'm not doing anything in my source file here let's just comment out everything just to be clear what's going on here i'll try to build this and in my main file above here where i'm still including things twice let's see what the preprocessor gives us so if i just do e and then the main file you can see that it's including in
this file two different times here so it's copying in uh one time here from the source hpp and then it's again coming down here and copying again so you get multiple definitions here and again this will happen multiple times if you have functions defined in your headers or any implementation like if i create a class here for some object or sort of set up the blueprint you'll get multiple definition uh errors here okay so we're going to want to avoid that now an easy way to avoid worrying about these definitions being included multiple times is
to use something called a header guard so this is again the preprocessor where i'm going to say if not defined source hvp and i can make up whatever i want the symbol to be define that symbol hpp and then just do end if okay so that way we're taking advantage of the preprocessor and saying hey if i've already defined this file one time don't include it two times okay so let's go ahead and try this now so i'll compile here and it did compile and i'll just run it through the preprocessor and if i scroll
through this time you'll see that the ad is only brought in once even if i've included the file multiple times here or if i've included it in other files it's only brought in one time into our project so that's what we want to do with the preprocessor and a common error that we have with multiple definitions okay now that we've talked about the preprocessor a little bit and the preprocessor is quite powerful but the most important thing i want to show you is just this dash e option so you can see exactly what's going on
and in fact things can get quite heavy here when you include some of the standard libraries so let's just go ahead and include something like i o stream so that we could do output in our main file do the output and if i scroll through this you're going to see a whole bunch of other stuff because i've got all the input output stream library here if you actually search through this you'll find your functions like c out cn and so on okay so again that's the preprocessor step okay so now let's talk about the compiler
step and for this step i want to talk a little bit about what your compiler is actually doing with your code here so that's this step here and again the goal is for most compilers is to transform your program so if i just have some simple expression over here for example two plus two somewhere in your code say it's part of your code somewhere int x equals two plus two uh what this is really doing is transforming this to some internal representation in your program so it's going to take this assignment here perhaps from the
x equals and it's going to say okay we have x here it's equal to some expression and it's essentially building a tree and depending on you can dive a little bit into a compiler's book here and you'll get either an abstract syntax tree or concrete syntax tree that's what it's called but you'll get some sort of tree here that is then showing okay we have some plus here and then a two and then a two and then i'm essentially walking through this tree um and sort of doing a traversal here in this direction here and
i'm getting things like x equals this is the next thing i hit and then i go down here as far as i can 2 and then i traverse back up here to the plus and then back down here to the two and i get this expression here and of course we have our assignment here um so this tree sort of continues here right this is part of some integer here that we're traversing to and these trees can be quite large we usually don't have to worry about them but this is what your program's doing it's
building this internal tree uh walking through this tree and this is also how you're finding your errors so for example if i had already redefined x for instance and it walks down this tree and says hey you've already done x equals something then it would say well x is not valid in this scope and it would sort of catch it here maybe there's more line information you know this is on line one that's how it tells you syntax error in line one and so on so you can actually dump out the syntax trees so let
me go ahead and just again in showing you what exactly is going on this compilation stage show you a little bit of this so depending on the compiler you're going to use there's going to be different ways to do it but let me go ahead and just show how to do it with g plus plus so you can see what this syntax tree or internal representation is and this isn't something you have to memorize but just something that i want to show you so f dump tree all graph i'm going to do it with dash
g so you get the debugging information and let's see main.cpp and our source.cpp so however we are building the program and when i type this in what you're going to notice is next time i look at my contents here's i have a ton of files here and what i actually want to look at is these dot files here and i can visualize them so different tools like graphis or on linux x dot can let you look at some of these files here so if i look through these um there's a main.cpp and then there's some
with a dot here again i just want to look at the ones with the dot dot here and again there's all sorts of different um versions of these and for specific functions that we might use i'm just going to pick one here that i doubt but you'd have to sort of look through most of them to see what's going on but again i just want to show you what's going on here and see if you see anything that looks familiar so if i see this main function for instance well that's something and we enter into
our function and within this block of code here you'll see this add two comma three well that's one of the functions that we called here and this returns you know some value from it in some location underscore three and then we exit so again this isn't really for us to read here but this is you know more for a compiler person to understand what's going on at each stage and you might be interested in using this as part of your analysis or just understanding what's going on but the basic idea is this is how your
code's parsed it builds these trees for you to look through and this could be one way to visualize it and it's it's pretty neat um okay so that's the uh compilation uh stage and there's many stages and that's more sort of on the front end side of parsing things and checking or verifying in the language's grammar that these are legal statements but the other things that would take place too is the cogeneration step so that gets us to this source step here which i want to take us to and what this is doing is again
it's walking through this tree but it's very simple in a way right we can see int and then equals and then x you know these are very primitive sort of operations and we can break those down into the corresponding assembly instructions in our assembly instructions is just a textual representation so textual representation of machine code that our systems understand okay so this is the idea of what's going on in the compilation stage so let's go ahead and look at how do we get the assembly out of our compiler and typically this is a tool that's
bundled with g plus plus it's actually the the gas assembler that's the default one that it uses to my knowledge and there could be other assemblers that could be used but let's just go ahead and look at how do we get that assembly code out so in order to do this we just do g plus plus dash s and then where our file is let's just work with the main file here uh and when i do that it's just going to uh if i list out here it'll generate a uh dot s file for us
okay and this s file is the assembly file so let's go ahead and open that up here okay so here it is here's the file and some of this we can understand we can see things like the file name uh the dot text section is where we have our actual source code here's uh something called a label here and again this is something that we could read or write we usually don't have to because we're using a higher level language c plus plus versus assembly which would be considered much lower level and here's the different
kinds of instructions and you can see there's actually a call to something that looks like an add function that takes in two integers that's why there's two i's here underscore z3 um means that this function is returning an integer so there is some sort of mapping again luckily we don't usually have to understand what this is but it's very simple one thing or one sort of operations happening per line and this can be translated into the machine code that your machine ultimately understands okay we can understand this but if we open up the program that
we compiled we can't understand this right this is all binary code but we can't understand the assembly when we look at it in that fashion okay so that's really what our compiler is doing it's getting us to the the separate assembly representation after parsing and making sure that we have a valid uh piece of code and then we can assemble um something called a o file okay so let's actually do that um in a step here um and we can um we can actually just build our program um and export out this this dot o
file here using uh g plus plus there's other tools to do it you can use a linker here but i just want to show you how to compile directly to that dot o file and investigate it just a little bit for example if we want to compile out our main file the dot oh file here before it's executable we could try something like this let's see what happens if we try to do this now this is still going to fail to compile because it needs that source file so we're still doing something similar here where
we want to build out maybe some object file here that's all the machine code needed here so again our compiler stage needs to pass and we still need to have available all of our machine code otherwise it's going to complain about some of this so i can just do um this compilation here with the two cpp files okay so i just do that and then if i list out here i'll have my o file here okay and i can try you know to execute it it doesn't really um do anything here um at at this
point here but i've just output it as a dotto file and then i could uh take it in and say oh file output it again uh as our uh program here um but i would have to do this in sort of two separate stages and sort of glue everything together in the linking stage okay so how would i just compile one of these together and just sort of one step at a time because we can't really do this so it's it doesn't really make sense because we already have the executable here so what i do
instead is i just do g plus plus n do dash c to compile that file okay and this way it'll say you know is this file here and i'll go up to um our main file here is this a valid file here you know does it seem like it could work it doesn't matter if we have the implementation or all the information just matters that we know that this function's externally available somewhere and we'll worry about that later when we're building the final executable so if i do this step here then that will again just
make the o file but this isn't the executable here this is just some object file some collection of machine code and then i'm going to do the same thing here for our source file here our source.cpp and then i'll also get if i list out the source file um i just do this in one line here um oops list out uh source.oh um i do have it here okay i've got all the other control flow graph and all the stuff that we output for the visualization uh but here's the o file so now i can
actually just do g plus plus uh main.o source.o and then i'll put it as the program here okay and then this will run again it doesn't do anything interesting yet but it's taking the two object files and gluing them together and that step is actually being done by the linker which is gluing things together one step at a time okay so again at at this stage we're linking things together behind the scenes and i just want to show a little bit more um about what is going on here um and we could actually try to
um sort of take a peek at what else is being brought in with this program when we're compiling the object files here to prog because we'd expect at least main and source.o so a tool i like to use first and foremost is just to look at these object files and see what's inside of them so let's go ahead and see what's inside of source.o and this tool is called objdump and it's just going to dump out a bunch of information so here's the sort of arguments that can be brought out here and you can kind
of explore this there's similar tools on mac there's otool and windows has dll dependency walker to see some of the files so some of these things where you can just get a little peek here i'm going to use dash t and that's going to tell me about the different symbols that are in this source file and the one in particular that i'm interested in is i can see here on this last row here i have that little add function i know it's a function because i see dash f here that's how i was able to
quickly find it here it's part of the program and it just tells me where it lives in this binary file because again if i if i look at the files that are created source.oh they're not really human-readable right they're just binary blobs of data so i can just see inside of them with this object tool which knows how to parse those blobs of data to something that we can read here um so anyway um that's one way to look at what's going and then what we're doing again is we're gluing together um our files so
if i look at object t and i try to look at um our program here let's see if i can recompile it here and see if i can get a look here so here's our full program that we compiled here and depending on if you compiled with the bug symbols you might be able to see a little bit better into it we can see that there is source.cpp is part of it main.cpp is part of it and so on so you can see some of these details and peek into your binaries just to see that
those two files were indeed glued together during the compilation process so again that's that's helpful to see what's happening and again behind the scenes what's happening is the linker is gluing together all of these o files here so we've got our source.o and in our example here are main.o as well so any number of files here are coming into the linker whether they're um in your operating system or some library or ones that were compiling okay into this linking stage now we can have other libraries also dynamically linkedin so for example let's make our executable
a little bit more interesting and let's finally print out some value here so we'll use the standard c out function here to finally print out our result here and maybe end here and let's just compile um this again from scratch here so i'll recompile it i'll run it to make sure it's working here and let's see it should be printing out uh the result of our function here uh five and uh look oh let me make sure i am uh compiling uh not our object files but our cpp files just to do this all in
one step here and then i'll run our program here and it's indeed printing out five here so beautiful so now that we use this function though where does this come from because we've included that the header file here if i look up you know have i o stream which is a standard c plus plus library here that we've included so where does that come from um you know where is the implementation well there's a little tool here i can use ldd that'll tell me where that comes from so if i run ldd and then the
program here it tells me all the other libraries that it's bringing in or linking in at run time so when i start running my program here so i see that one of these libraries is the standard c plus library i can see where it's located and this is what's being brought in and there's some other libraries here looks like libsy the math library and some of these are by default here okay that are being brought into our program and that's this sort of dynamic uh linking stage files that end in dot so in other operating
systems they would end in you know dll for our uh windows users that die lib for our mac users okay um and there could be you know arbitrary extensions but that's the um convention okay so that's the idea and then once everything's linked in here then again we get our final uh source executable so um let me sort of summarize all that we've talked about again this is a long video on compilation and how things work but i think valuable to just understanding what's going on at each different stage here and then we'll talk about
some of these flags here and i'll actually do an example that i'm like working on and download a library for us to try an example so we can see some different errors and debug a little bit so we started with our source code um that we had here that's our files that we've just opened here a really simple little project here where we've written one library with a little add function we've run with our g plus plus in our preprocessor with dash so we can see what's going on in each of these files when we
include them and that that's just doing a copy and paste essentially of the contents of things that are included or handling other conditional compilation things and then we see that our compiler finally runs internally it's building this tree of our source code so that we can detect syntax errors and then finally validate that we have a valid program and you can again read a little bit more about these things and that it's a valid uh grammar in the language and so on but ultimately it's just trying to generate this assembly code okay and we could
get to the assembly by doing uh the g plus plus the file that we want to run and then that's s here and that will give us the assembly output okay and then finally we looked at the linking stage um where we were linking in uh either object files that we had compiled with you know dash c to compile these uh one at a time if we wanted um and then we could uh glue them together so the actual object files so let me just do that here so that was one way to glue things
together and the program works just the same and then we looked at what was also happening at the dynamic linking stage with prog here okay and some other handy tools like object just to see you know what's going on in some of these files here and again um compiling with little debugging information uh can be helpful right so if i instead compile this with batch g for instance and then run our object tool dash t for the symbol table information so i can see all the symbols here you'll see what some of these functions are
and where they come from and so on okay so that's that's for you to explore a little bit later okay so that's the sort of full process so what i want to do now though is actually take a look at a library and then talk about how we um include that library into our code because we kind of got away with things easy here when i was running prog here you can you can see that these were just default libraries that were included i didn't have to tell it hey bring in the iostream library it
just knew how to do that so that was actually really nice that it was able to do that so let's go ahead and explore that and what i'm going to do is i'm going to open up a browser and just go to a library that i like using this is the sfml graphics library where you have a nice sort of game development and graphics framework here they have a little tutorial for getting set up on linux so i'll just briefly i've already installed it but i'll just run through it again here so let me close
these files out here so what you would do is using your package manager if you're on linux or if you're on mac maybe brew or windows you just can download it and get things set up here i've already got it here but that's all you need to do for the install and essentially what this has done is installed some shared object files somewhere in our system okay and what we would have to do so just scrolling through this is let's just take a little project here and let's just try to run it here okay so
i'm just going to call this one sfml that's cpp i'll just paste it in here this is just a sort of hello world program here if you want to take a peek at that so let me go ahead and just save that and then within this directory i'm going to just try to compile it so like what we've been doing let's do dash g just to get some debugging information in the file and just output it as prog and you're going to see i'm in a little bit of a world of pain here because there
are lots of errors here okay syntactically that i can tell you the tutorial is correct there aren't any syntax errors i don't see anything here warning me that i made a you know error after i did this compile but rather it says in function main undefined reference undefined reference undefined reference undefined reference and so on and basically it's just saying you know we can't find where these um files are or or the implementations rather okay uh it tried its best to make a program but we just can't execute it because we can't find the appropriate
files or the implementations of these different functions so the trick is we have to actually link in these libraries and i do that with the dash l flag and whatever the library name is in this case they are sfml dash system uh and if we can if we have multiple ones which we do uh sfml dash window dash l sfml graphics okay and i'll put this on on one line just so you can see it at the bottom here and then if i hit enter now it compiles and now i run their sort of hello
world program here where i get a little circle here which is pretty cool so what i've done here is i've told the linker which is running as part of g plus plus when i compile it i say hey linker bring in all these libraries okay and make sure that we link them in right so i can run this ldd command on our program again and you're going to notice this time a whole bunch of other libraries here on the right hand side of the screen here have been brought in so i can even scroll up
here let's see if we can find some of those ones that we included like lib sfml system window is here graphics in here and we can see the actual location of where this is coming from okay our package manager made it a little bit easier for us on linux so i want to show this in one more step what you might do if you can't find that library so for instance if i just list that location here all these libraries here and let's see if i can find sfml here i think it is lib uh
that's fml here sfml here so here's all the uh lib sfl libraries they were installed in this location so you might have to hunt for it or or sort of query your package manager where these weren't installed if you're on windows or mac chances are you have all your die lib dll.sl whatever files installed somewhere but you can see these so in linux it happens to be that i didn't have to specify this path but let me go ahead and just do it anyway just to be explicit here when we compile because it's enough to
just on my system here and i'll show you why in a moment to just say lincoln and find this library but where is it actually so that's where i can pass in another command line argument uh or to this compiler another uh flag dash capital l and then this path to this file here and it says hey look in this file dash capital l for libraries that match this name sfml system um and by default you don't have to type lib it'll look it'll assume you've named them lib so just looking for sfml dash audio
or sfml-graphics that the dash l is sort of shorthand for that okay so if i hit enter here this is still going to work and again why didn't have to type this name out here is because um the compiler by default will look in a special variable on linux called path so if i echo out path here you'll see that there are some default locations like slash user let's see if i can find it here actually there's a couple of them but path is one of the locations where i'll default look in all these folders
here until it finds the first match for you know sfml system or whatever it is it's looking at all these locations that are separated by a colon okay windows has something similar it has environmental uh path variables that i'll look in by default to try to find libraries that you specify in your compiler i believe mac has something very similar it has like a frameworks folder that you can look in by default so that's the idea here with what's going on now the second thing you might also be wondering because i had one other flag
here dash i and that's the include path okay so for this sfml you might have noticed that hey we didn't specify where this was okay if you remember in our other um programs here and let me open up one of them here i'll just split the window and put in the source we just specified with the quotations look you know include do the copy and paste of source.hpp okay and it knew just within this directory it was in source.hpp so this might have been in dot source the current directory i could have specified the whole
name uh whatever it is you know this is on my um home folder in the compile folder you know this would also be valid but typically we like the relative path um but again with when we include something if we use the left the lesser than and greater than sign here or these these wickets here it says hey look in one of these system paths for a folder called sfml and then within that look for graphics.hpp so that's the include path okay and again i just want to be super explicit and say okay what if
we didn't have this path and this was giving an error message how would we compile this on the command line and all sort of one go so let's let's go ahead and do that as well so this time we have g plus plus the source file we want to compile how we want to output it the different libraries that we're linking in where to find those libraries and then again we need to know about where these functions are okay so let me go ahead and just um i'm actually going to open up another terminal window
here just so you can see here the actual location of where i would find this um and i just sort of have a hunch of where these things are so if i cd into my user drive and ls there is an include folder this is usually where it's putting them you can use tools like find and try to find um you know graphics.hpp for example on your system maybe from your home folder but but i know that they're usually in user uh and then there's an include folder here so if i ls here there's a
bunch of stuff and then i can add find i can probably search through and find it but i believe sfml is here uh so if i scroll up here it is so cd into the sfml directory and there i can see the graphics.hpp okay so if i wanted i could specify this whole path let's go ahead and do it just just for fun to see that it works here so let me go ahead and just close that and then i'll just paste it here because i just want to show you uh how this works um
just again so you know exactly what's going on here so it's in the sfml and then graphics.hbp so i could do that and if i hit enter you know it still works i'm just putting in the whole name to this thing uh but again it is looking on these system paths in user include that was on my uh path directory i believe here so if i look through the here i've got user games um user local bin user slash ben i think i've got just slash user in here or one of these uh paths here
i think there's another one but that's the idea so again you know what if i just wanted to specify this with graphics for instance so let me just compile this here and says okay we can't find the library so in this case i would just specify with dash capital i and then this path here and then it would say okay compile with g plus plus debugging symbols the source file we want i'll put it as a program link in these libraries find those libraries in this folder and any header files that we include well if
you can't find them in the current directory start looking in here start looking in slash user slash include slash so again if i look in slash user slash include sfml i can see that oh my compiler would be happy it would then find graphics.hpp this is now on the include path you can think of it as almost a pre-pending it or putting it in front of graphics.hbp and anything that against not in the directory would look inside there and try to find things okay so that's how you include uh files here so for our flags
the the dash include and i'll just annotate these include our library so include directory library directory i'll put this in and uh library uh files here uh dynamically library files okay so that's what's all over here okay um and i want to show this just in one more example because i'm showing this on linux maybe you're on windows or something but when you're using ides and stuff these details get hidden from you it's the reason i like doing things on the command line so much but you'll have these dialogues where you're going into the linker
the general settings and then you're setting additional library directories well that is that dash uppercase l here wherever you installed it okay uh and then in the linker setting for input these are your sfml graphics in windows they just end in dot lib um and um same thing um for the uh include directories here let's see i didn't see a option here oh here it is on this first one so the c plus plus the general you know additional include directories this is just you know it's it's hiding that capital dash uh i option but
it is putting it there um so i'll bring myself back on here uh for a moment since you haven't seen me in a while uh to say that you know i really think it is important to be able to do bike lane but then just also understand uh in tools like visual studio what they're actually doing for you here okay so uh let's go ahead and just look at the uh xcode one because i think it's doing um pretty much the same thing here on mac here again just so you understand uh you're setting up
those exact same things here they might give you a nicer template here but you can actually um dispersify things on the command line if you know where they they live these these exact libraries that you have here okay mac might be a little bit weird sometimes they give you a framework thing so you're doing dash framework uh sfml window instead but that's the idea okay so with that said um i wanna just go ahead and wrap us up here i know it's a lot of stuff here but this is the full compilation process and that's
something i know i see uh folks really struggle with when they're just getting started it's important to understand what's going on in c plus here these same skills will also apply in java for instance when you're compiling big projects together and things are going to bytecode well it's not assembly but it's a similar idea and then you're sort of linking or gluing together lots of different pieces of source code whether they're in source or binary so it's just important to understand what these different steps are so thanks for joining me for this lesson uh folks
i hope it was really valuable for you and just understanding once and for all how to compile code with cnc plus plus you got to see the process got to walk through some helpful tools at least on linux and exploring some other platforms and then even with a practical example of using the sfml library which might be a great one to practice on if you're just getting used to compiling code so hope you enjoyed this and we'll see in the next one
Copyright © 2024. Made with ♥ in London by YTScribe.com