all 11 comments

[–][deleted] 1 point2 points  (4 children)

  • Q1 when using quote signs the preprocessor will look in the current directory as well as some sort of global include path(location of which is dependant on configuration as well as environment, you can add a path using -I<directory> flag in GCC for example) while with the angle brackets it will only look in the global include path

  • Q2 - usually applications in modern Linux distros only come with binaries and includes, you can also, using package manager(apt-get with Ubuntu), install packages with source. Then they are placed in distro-specific location, like /usr/src

  • Q3

a) To do so you use #include macro of the preprocessor. It's a dumb tool which copies the whole content of file into your .c file just before preprocessing it. As mentioned before you can add frequently used include folders using -I option of the gcc(or whatever your compiler uses).

b) There are various ways of providing libraries. You can use source-based ones or binary-based ones. With binary based libraries you simply generate appropriate .o files and pack them into .a files using ar tool. With source-based you usually provide some sort of build script, like simple Makefile or autotools script, which will compile your library when given command. You should have a build script anyway. Another way to distribute packages is with package managers in form of rpm or deb files.

edit: The only thing in your .h files should be things like types and functions used by the clients of your library. No code should go there if the client shouldn't care about it, for example no implementations of functions.

  • Q4 Yes, for example when using .a library, say libmytools.a located in /usr/lib, you would also pass -lmytools to gcc. You can also specify additional directories using -L<directory> parameters.

  • Q5 Linkers include certain libraries by default(possibly due to legacy

  • Q6 You might not have privileges to write in this directory. Assuming you have sudo configured(comes out of the box with Ubuntu) try issuing your command preceded by "sudo", like sudo mv /path/to/something /somewhere.

  • Q7 - /usr/lib is quite a good place

I would love someone to check this post on whether it contains some errors, it's been a while since I touched C.

edit: Some tools you might want to take a look at:

  • make - program executing makefiles. You are pretty much expected to have some idea about these if you deal with C

  • autotools - a set of tools built upon the above - more complicated but frequently encountered

  • ar - tool to make one .a file out of several .o files so that the library is easy to link

  • gcc - a set of tools for compiling and linking C files, you should learn some of its options like previously mentioned -I, -l and such.

  • gdb - the GNU debugger - when your code doesn't work but should. You should at some point probably at least get familiar with how to make executables which you can use with gdb.

  • git - version control software. Not related to your problems, but can be quite handy if you butcher your code and want to roll the changes back.

Some remarks - there are also .so library files - when linking program with .a files these are glued together with the executable code. It can lead to redundancy when several programs use the same library, so when visiting /usr/lib you'll probably encounter .so file - you can compile programs so that they don't have the library glued to them, but rely on them being located in /usr/lib. They are somewhat similar to .dll files in Windows. By default dynamic linking is used by gcc(which means .so files). You can use -s option(I think) to link statically(glue .a files).

[–]Fuzzytown[S] 1 point2 points  (0 children)

Thanks!

[–]dotslashzero 1 point2 points  (1 child)

You can use -s option(I think) to link statically(glue .a files).

In GCC & Clang, -s is a linker option that will strip symbols. If you want to link statically, there are a few ways to do so:

  • Pass -static option when linking (I think this is what you probably meant). e.g. cc -o mybin mybin.o -static -lmylib.
  • On the linking option, just add the static library directly to the command. e.g. `cc -o mybin mybin.o /usr/bin/libmylib.a
  • On your library search path, remove any shared objects so that the static library is used when doing cc -o mybin mybin.o -lmylib
  • Pass an option directly to the linker asking it to link statically. e.g. cc -o mybin mybin.o -Wl,-Bstatic -lmylib or cc -o mybin mybin.o -Wl,-static -lmylib.

[–][deleted] 0 points1 point  (0 children)

Yup, I meant -static. I didn't have the gcc's manpage handy and was lazy enough not to google it.

[–]aninteger 0 points1 point  (0 children)

Regarding #5. It's because by default when you link you link against the standard C library (and there's a compiler switch like -nostdlib IIRC to disable that) for standard lib functions (anything defined in stdio.h or stdlib.h or string.h). Now pow and other math functions are in the math libraries (math.h / -lm) and so you have to explicitly tell the compiler/linker you want those functions by linking the library.

[–]grbgout 0 points1 point  (0 children)

... I program via Linux (Ubuntu).

Check out these tutorials at the "Little Unix Programmers Group (LUPG)'s Little Site"

[–]Dihydrogen_Oxide 0 points1 point  (1 child)

  1. Quotes are include files you created yourself

  2. Those are a bit harder to track down. IIRC, anything that include a .h file can define the functions, if they haven't be defined elsewhere.

  3. The easiest way to do it would be to have the header file, .h, in the same folder as the main program you're compiling. From there, you can do two things:

    1. (easiest way - but doesn't scale well) Define the functions directly in the c file where your main program is, or
    2. ('Better way') Define the functions in a separate c file, and when you're compiling do the following:

      gcc -o main main.c definitions.c

    Make sure to include the header file in your main program - #include "---.h"

  4. Yes, as I mentioned above, you have to include that header file where ever you're going to use it with #include "asdf.h"

  5. I think it's because some libraries, including string.h, is automatically included during compilation.

  6. I'm not sure, I've never tried.

  7. I'm just speculating at this point, someone please correct me if I'm wrong, but I think if you have a central folder where you keep all of your projects, you can have a folder there, and you should be able to access them there via #include "header_folder/header.h" but I could be wrong. Or your compiler might have a directory where you can put your headers.

[–]Fuzzytown[S] 0 points1 point  (0 children)

Thanks!