-1

I'm trying to compile a simple C program on an M1 Mac that includes gmp.h. For whatever reason, however, it continuously says that it can't find the library. I checked to see if it exists via locate libgmp.a to which it says it is located in /opt/local/lib/libgmp.a. I also attempted to install it via brew to no avail. I really don't understand what I'm doing wrong here. I also checked the PATH environment variable to make sure this path was included, which it is.

The output of find /opt/local -type f -name "gmp.h" is /opt/local/include/gmp.h, and the output of find /opt/local -type f -name "libgmp*" is

/opt/local/libgmp.a
/opt/local/lib/libgmpxx.4.dylib
/opt/local/lib/libgmp.a
/opt/local/lib/libgmpxx.a
/opt/local/lib/libgmp.10.dylib

I compiled by linking via -L/opt/local/lib -lgmp does not fix the issue.

Command used: gcc main.c -o main.o -L/opt/local/lib -lgmp

  • How do you build your program? You either need to list the .a file when you link your program, or tell the compiler the search directory and library you want to link with -L/opt/local/lib -lgmp (this is gcc syntax, you didn't say what compiler you are using). – Allan Wind Oct 16 '22 at 03:00
  • What does `find /opt/local -type f -name "gmp.h"` report? (add result to question) along with result of `find /opt/local -type f -name "libgmp*"` – David C. Rankin Oct 16 '22 at 03:16
  • 1
    @AllanWind I added the command I used to the post. Linking with these flags (which I already tried) does not work. – Joshua Crotts Oct 16 '22 at 03:22
  • Did you also add `-I/opt/local/include` to allow the compiler to find the header? (and ... you have `#include ` in your code?) The rest of your compile string looks correct. – David C. Rankin Oct 16 '22 at 03:24
  • 1
    @DavidC.Rankin Yes, I do include the header. Adding that flag/arg made it work. I'm not entirely sure why, though. I thought all that was necessary was linking via -lgmp? – Joshua Crotts Oct 16 '22 at 03:26
  • Any time you have things in non-standard locations `-I/path/to/header` adds `/path/to/header` to your *Include Search Path* (allowing the header to be found), and `-L/path/to/lib` adds `/path/to/lib` to your *Library Search Path* (allowing the library to be found). You can have multiple entries for each (one for every place you need to tell the compiler to look) – David C. Rankin Oct 16 '22 at 03:28
  • If you compile main.c you usually do it with -c, and if you build it then the output is not usually a .o file (i.e. gcc main.c -o program -L/opt/local/lib -lgmp). What's the exact error message? You get that when you build or when you try to run the program? – Allan Wind Oct 16 '22 at 03:29
  • As @AllanWind indicates, I'd just use `gcc main.c -o main -I/opt/local/incude -L/opt/local/lib -lgmp` and compile to `main` as the executable. (actually I'd do `gcc main.c -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast -o main -I/opt/local/incude -L/opt/local/lib -lgmp` to enable *Full Warnings*. (never accept code until it compiles without warning) – David C. Rankin Oct 16 '22 at 03:31
  • 1
    Oh... so the error was that it could not find the header file. Yeah, -I/opt/local/include will fix that. Still please add the exact error message for future reference. Good job on updating the question with the data requested. – Allan Wind Oct 16 '22 at 03:36
  • @AllanWind it appears he was missing the `-I` for the Include Search Path. If you want to write up an answer explaining how to tell `gcc` where to find both the libraries and includes, I'll leave it to you. (and happily vote for a good answer) – David C. Rankin Oct 16 '22 at 03:40
  • @DavidC.Rankin Done. I thought you would be a -Werror kind of guy :-) – Allan Wind Oct 16 '22 at 03:48
  • 1
    @AllanWind -- I am, but if you are honest about resolving all warnings -- you can dispense with `-Werror`, on the other hand, if you need ti to ensure you don't bend the corners a bit -- it is a good way to keep you honest `;)` – David C. Rankin Oct 16 '22 at 04:21
  • highly recommend cmake to automatically generate makefiles which you build useing make instead of writing compiler commands by hand. https://cliutils.gitlab.io/modern-cmake/ – Richard Bamford Oct 16 '22 at 10:19

1 Answers1

1

To compile a program that relies on a header file:

#include <gmp.h>

located in a non-standard location /usr/local/include/gmp.h you need to tell the compiler where to find it by setting the directory where to find the header file:

gcc -c main.c -I/usr/local/include

Note: gpp -x c -v

To link the program, you need to tell the compiler which library to use (-l) and where to find that library (-L) which in this case /usr/local/lib/gmp.a:

gcc main.o -o main -L/usr/local/lib -lgmp

Note: gcc -print-search-dirs | grep ^libraries

If you are using a dynamic library (.so), you may also need to tell the linker where to find the library at run-time:

export LD_LIBRARY_PATH=/usr/local/lib
./main
Allan Wind
  • 23,068
  • 5
  • 28
  • 38
  • Good job. You can also pass the runtime information to the linker to include `-rpath` to the library with `-Wl,-rpath=/path/to/your/lib` (avoids the export to the environment) – David C. Rankin Oct 16 '22 at 04:13
  • AFAIK, -rpath is considered evil (you are encoding something about the target environment that you may not control). – Allan Wind Oct 16 '22 at 04:14
  • It all depends on what you are building for. If you are building for you personal project learning on your system with a library stuck in `/opt/local` -- well, it's less evil than if your were coding for your employer for a production system. Good to know both are available. – David C. Rankin Oct 16 '22 at 04:17