Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include an external library in C

Tags:

c

cs50

I'm attempting to use a C library for an opencourseware course from Harvard. The instructor's instructions for setting up the external lib can be found here.

I am following the instructions specific to ubuntu as I am trying to use this lib on my ubuntu box. I followed the instructions on the page to set it up, but when I run a simple helloWorld.c program using a cs50 library function, gcc doesn't want to play along.

Example:

helloWorld.c

#include <stdio.h>
#include <cs50.h>

int
main(void){
        printf("What do you want to say to the world?\n");
        string message = GetString();
        printf("%s!\n\n", message);
}

$ gcc helloWorld.c

/tmp/ccYilBgA.o: In function `main':
helloWorld.c:(.text+0x16): undefined reference to `GetString'
collect2: ld returned 1 exit status

I followed the instructions to the letter as stated in the instructions, but they didn't work for me. I'm runing ubuntu 12.04. Please let me know if I can clarify further my problem.

like image 566
ironicaldiction Avatar asked Jul 28 '12 05:07

ironicaldiction


4 Answers

First, as a beginner, you should always ask GCC to compile with all warnings and debugging information enabled, i.e. gcc -Wall -g. But at some time read How to invoke gcc. Use a good source code editor (such as GNU emacs or vim or gedit, etc...) to edit your C source code, but be able to compile your program on the command line (so don't always use a sophisticated IDE hiding important compilation details from you).

Then you are probably missing some Harvard specific library, some options like -L followed by a library directory, then -l glued to the library name. So you might need gcc -Wall -g -lcs50 (replace cs50 by the appropriate name) and you might need some -Lsome-dir

Notice that the order of program arguments to gcc is significant. As a general rule, if a depends upon b you should put a before b; more specifically I suggest

  1. Start with the gcc program name; add the C standard level eg -std=c99 if wanted
  2. Put compiler warning, debugging (or optimizing) options, eg -Wall -g (you may even want to add -Wextra to get even more warnings).
  3. Put the preprocessor's defines and include directory e.g. -DONE=1 and -Imy-include-dir/
  4. Put your C source file hello.c
  5. Put any object files with which you are linking i.e. bar.o
  6. Put the library directories -Lmy-lib-dir/ if relevant
  7. Pur the library names -laa and -lbb (when the libaa.so depends upon libbb.so, in that order)
  8. End with -o your-program-name to give the name of the produced binary. Don't use the default name a.out

Directory giving options -I (for preprocessor includes) and -L for libraries can be given several times, order is significant (search order).

Very quickly you'll want to use build automation tools like GNU make (perhaps with the help of remake on Linux)

Learn also to use the debugger gdb.

Get the habit to always ask for warnings from the compiler, and always improve your program till you get no warnings: the compiler is your friend, it is helping you!

Read also How to debug small programs and the famous SICP (which teaches very important concepts; you might want to use guile on Linux while reading it, see http://norvig.com/21-days.html for more). Be also aware of tools like valgrind

Have fun.

like image 197
Basile Starynkevitch Avatar answered Dec 30 '22 11:12

Basile Starynkevitch


I take this course and sometimes I need to practice offline while I am traveling or commuting. Under Windows using MinGW and Notepad++ as an IDE (because I love it and use it usually while codding python) I finally found a solution and some time to write it down.

Starting from scratch. Steps for setting up gcc C compiler, if already set please skip to 5

  1. Download Git and install. It includes Git Bash, which is MINGW64 linux terminal. I prefer to use Git as I need linux tools such as sed, awk, pull, push on my Windows and can replace Guthub's terminal.
  2. Once Git installed make sure that gcc packages are installed. You can use my configuration for reference...MinGW Installation Manager - gcc
  3. Make sure your compiler works. Throw it this simple code,

    • by saving it in your working directory Documents/Harvard_CS50/Week2/ hello.c
    #include <stdio.h>
    
    int main(void)
    {
     printf("Hello StackOverflow\n");
    }
    
    • start Git Bash -> navigate to working directory

    cd Documents/Harvard_CS50/Week2/

    • compile it in bash terminal

    gcc helloworld.c -o helloworld.exe

    • execute it using bash terminal

    ./helloworld.exe

    Hello StackOverflow

    1. If you see Hello StackOverflow, your compiler works and you can write C code.

Now to the important bit, installing CS50 library locally and using it offline. This should be applicable for any other libraries introduced later in the course.

  1. Download latest source code file cs50.c and header file cs50.h from https://github.com/cs50/libcs50/tree/develop/src and save them in Documents/Harvard_CS50/src

  2. Navigate into src directory and list the files to make sure you are on the right location using

    ls

    cs50.c cs50.h

  3. Cool, we are here. Now we need to compile object file for the library using

    gcc -c -ggdb -std=c99 cs50.c -o cs50.o

  4. Now using the generated cs50.o object file we can create our cs50 library archive file.

    ar rcs libcs50.a cs50.o

  5. After all this steps we ended with 2 additional files to our original files. We are interested in only 2 of them cs50.h libcs50.a

    ls

    cs50.c cs50.h cs50.o libcs50.a

  6. Copy Library and header files to their target locations. My MinGW is installed in C:\ so I copy them there

    cs50.h --> C:\MinGW\include

    libcs50.a --> C:\MinGW\lib

Testing the cs50 Library

To make sure our library works, we can throw one of the example scripts in the lecture and see if we can compile it using cs50.h header file for the get_string() method.

#include <stdio.h>
#include <cs50.h>

int main(void) 
{
    printf("Please input a string to count how long it is: ");
    string s = get_string();
    int n = 0;
    while (s[n] != '\0')
        {
            n++;
        }
    printf("Your string is %i chars long\n", n); 
}
  1. Compile cs50 code using gcc and cs50 library. I want to be explicit and use:

    gcc -ggdb -std=c99 -Wall -Werror test.c -lcs50 -o test.exe

    But you can simply point the source, output filename and cs50 library

    gcc test.c -o test.exe -lcs50

Here we go, program is compiled using header and methods can be used within.

If you want Notepad++ as an IDE you can follow this tip to set it up with gcc as a compiler and run your code from there. Just make sure your nppexec script includes the cs50 library

npp_save
gcc -ggdb -std=c99 -Wall -Werror "$(FULL_CURRENT_PATH)" -lcs50 -o "$(CURRENT_DIRECTORY)\$(NAME_PART).exe"
cmd /c "$(CURRENT_DIRECTORY)\$(NAME_PART).exe"

Run CS50 Code in Notepad++

like image 25
Gunay Anach Avatar answered Dec 30 '22 11:12

Gunay Anach


You need to link against the library during compilation. The library should end in .a or .so if you are on Ubuntu. To link against a library:

gcc -o myProgram myProgram.c -l(library name goes here but no parentheses)
like image 42
C0deH4cker Avatar answered Dec 30 '22 11:12

C0deH4cker


  1. Download the cs50 from: http://mirror.cs50.net/library50/c/library50-c-5.zip
  2. Extract it. (You will get two files cs50.c and cs50.h)
  3. Now copy both the files to your default library folder. (which includes your stdio.h file)
  4. Now while writing your program use: #include < cs50.c >
  5. You can also copy the files to the folder containing your helloWorld.c file.
  6. You have to use: #include " cs50.c ".

OR =====================================================================>

  1. Open cs50.c and cs50.h files in text editor.
  2. In cs50.h, just below #include < stdlib.h > add #include < stdio.h > and #include < string.h > both on new line.
  3. Now open cs50.c file, copy everything (from: /**Reads a line of text from standard input and returns the equivalent {from line 47 to last}) and paste it in cs50.h just above the #endif and save the files.
  4. Now you can copy the file cs50.h to either your default library folder or to your current working folder.
  5. If you copied the file to default folder then use: #include < cs50.h > and if you copied the files to current working folder then use: #include " cs50.h ".
like image 35
Faizan Rizvi Avatar answered Dec 30 '22 10:12

Faizan Rizvi