0

I'm a python developer new to C and developing C code on Windows that needs to work on Windows and Linux.

To that end, I downloaded MSYS2 and used pacman to install gcc and bz2.

My question is: How do I use bzip2 in my C code.

When I try to compile this C code:

#include <bzlib.h>

using the command gcc test.c -lbzip2 -o test.out I get the following error:

test.c:1:10: fatal error: bzlib.h: No such file or directory

Am I including the correct header file? Am I linking it correctly?

When not using 3rd party libraries a simple "hello world" program compiles and executes fine.

CSStudent7782
  • 618
  • 1
  • 5
  • 21

2 Answers2

1

Short version: assuming you are using the MSYS target, pacman -S libbz2-devel.


Long version: In MSYS2 you can find which package contains a file using:

pacman -F bzlib.h

to which the answer is:

mingw32/mingw-w64-i686-bzip2 1.0.8-1 [installed]
    mingw32/include/bzlib.h
mingw64/mingw-w64-x86_64-bzip2 1.0.8-1 [installed]
    mingw64/include/bzlib.h
msys/libbz2-devel 1.0.8-1 (development)
    usr/include/bzlib.h

To interpret this output, first understand that an MSYS2 installation supports three different development targets:

  • mingw32 (builds native Win32 applications using mingw-w64)
  • mingw64 (builds native Win64 applications using mingw-w64)
  • msys (builds Win32 or Win64 applications that depend on MSYS DLLs and runtime environment, using a custom GCC port and runtime library, and supports a lot of POSIX functionality).

When you install MSYS2 you will get three startup scripts in the Start Menu , one for each of those environments.

The output of pacman -F above told us that for targets mingw32 and mingw64, the package bzip2 contains the files required to do development with bzip. However, on the msys target, the package libbz2-devel is required.

This is a common package layout in msys and in the various *nix package managers (MSYS2 pacman is a port of ArchLinux pacman):

  • bzip2 is the binaries for using bzip2 in your shell
  • libbz2 is a shared object binary (DLL)
  • libbz2-devel is the header files and static libraries that you need to link bzip2 into your program.

You can list the files for each package with pacman -F --list libbz2-devel etc.

The mingw32/mingw64 targets typically have single packages that include all of those three things in the one package, e.g. pacman -F --list mingw64/mingw-w64-x86_64-bzip2.

I assume you are using msys target as otherwise this question would not have arisen .

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Thank you this was an excellent answer giving me the knowledge to find the correct packages on my own next time. – CSStudent7782 Jun 05 '20 at 23:40
  • I'm running into trouble since installing, when I link `gcc test.c -lbzip2` I get the error `usr/../gcc/x86_64-pc-msys/../bin/ld: cannot find -lbzip2, ld returned 1 exit status`. When I compile without linking `gcc test.c` I am able to call `#include ` and initialize one of it's stucts and compile no problem. But when I try to use a function, `BZ2_bzDecompressInit()` I get the compile error: `relocation trucated to fit: RX86_64_PC32 against undefined symbol BZ2_bzDecompressInit, ld returned 1 exit status`. Any idea what's going on there? – CSStudent7782 Jun 05 '20 at 23:47
  • @CSStudent7782 it is `-lbz2` . You can see the file list with `pacman -F --list libbz2-devel` – M.M Jun 06 '20 at 12:03
  • thank you, that command was very useful. I've also installed `msys2-runtime-devel` so I can use `byteswap.h`, but I'm getting the error `byteswap.h: No such file or directory`. There are over 10 libraries listed when I call `pacman -F --list msys2-runtime-devel`, is there a way to find out which of those 10+ libraries contain `byteswap.h`? And why is it that `#include ` fails to compile without linking libraries, but `#include ` worked fine without any linking? – CSStudent7782 Jun 06 '20 at 15:31
  • @CSStudent7782 that one should be installed by default, you should see `msys/msys2-runtime-devel 3.0.7-6 (msys2-devel) [installed]` from `pacman -F byteswap.h` . And it shows that the path is /usr/include/byteswap.h – M.M Jun 07 '20 at 00:06
  • Not sure what you mean by "#include worked fine without any linking?" since you said in your previous comment that you got a linking error – M.M Jun 07 '20 at 00:07
  • btw in case you missed this step when installing MSYS2, check for system upgrades with `pacman -Syuu` – M.M Jun 07 '20 at 00:08
  • I only got the error before I installed the library mentioned in this answer. But interestingly, once it installed I didn't need to link the library in the compiler command to compile the include statement. It was only when I wanted to use the function that I got a linking error without using a -l option. When you say the path is: `/usr/include/byteswap.h`, I see that too, but how do I use that information? I thought library linking dealt with `.a` files. Will `gcc test.c -l/usr/include/byteswap.h` work? – CSStudent7782 Jun 07 '20 at 00:45
  • @CSStudent7782 I would recommend reading about header files and libraries, you seem confused on the difference – M.M Jun 07 '20 at 02:28
  • You were right I needed a quick education. The problem was that the byteswap library and headers got installed in msys64/usr, but the target for my gcc was the directory msys64/ming64, so when I copied the header files from the installed location into ming64, it could read the header file. And then in my gcc command I have to be sure to add the usr directory when looking for libraries. Not sure what the difference between `mingw64` and `msys` packages, or if I should be worried about combining the mingw64 gcc with msys libraries. Thanks for your help. – CSStudent7782 Jun 07 '20 at 13:01
  • @CSStudent7782 I explained the different targets in my answer . You should NOT be adding usr directories to your include path. If you want to use headers from /usr/include, then use the msys target compiler (not the mingw64 one). – M.M Jun 07 '20 at 21:08
  • I'm not sure how to change my target compiler. Should I change the PATH variable? – CSStudent7782 Jun 08 '20 at 02:17
  • @CSStudent7782 you should have 3 start menu options for the 3 targets – M.M Jun 08 '20 at 03:35
  • I call gcc from terminal, perhaps its not possible to change the target without uninstalling one. – CSStudent7782 Jun 08 '20 at 19:15
  • @CSStudent7782 You have 3 possible terminals you can open (mingw32, mingw64 and msys). Can go in via start menu or taskbar pin or whatever. You can have them all open at once (three different windows), you do not need to uninstall anything. They have separate trees – M.M Jun 08 '20 at 22:29
0

Installing all the binary packages listed here and changing the header filename to bzlib.h fixed the problem.

CSStudent7782
  • 618
  • 1
  • 5
  • 21