Using zlib under windows mingw - c

I can't seem to get zlib to do anything on mingw under windows.
I downloaded zlib # http://sourceforge.net/projects/mingw/files_beta/MinGW/zlib/zlib-1.2.3-1-mingw32/ and put the header and lib files in the right place.
Simple code like:
#include <stdlib.h>
#include <stdio.h>
#include "zlib.h"
int main(int argc, char *argv[])
{
long a;
char buffer[1024];
a = 1024;
compress(buffer,&a,"testing",7);
return 0;
}
compiled:
gcc test.c -lzlib -Wall -o test.exe
Compiles fine.
However the exe crashes at the compress function.
Any ideas?

I recommend using MSYS2 for this kind of thing. These instructions assume you want to compile a 64-bit program, but they can easily be modified for 32-bit.
After installing MSYS2, run the "MinGW-w64 Win64 Shell" shortcut in your Start Menu. Install the 64-bit toolchain by running:
pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-zlib
Then compile your code by running something like this:
gcc test.c -lz -o test
I did not check your code carefully, but I was able to run your code without any crashing, so your code might be OK. Your code also gives no output so it's hard to tell if it really worked.

Looking at the zlib manual it says:
ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
Compresses the source buffer into the
destination buffer. sourceLen is the
byte length of the source buffer. Upon
entry, destLen is the total size of
the destination buffer, which must be
at least the value returned by
compressBound(sourceLen). Upon exit,
destLen is the actual size of the
compressed buffer.
Maybe a=1024 isn't big enough? I think you need to call compressBound to get a suitable value.

I tried to use the zlib from MSYS (accessible with mingw-get) and got the same problem as described below.
The solution is to do a static link instead of using the shared library.
Just remove or rename the import library libz.dll.a to avoid the linker to do a link with the msys-z.dll.
Recompile and it will be working.
Another way is to install zlib yourself from the zlib.net website.
Remove the one from mingw-get.

Using zlib in your code is extremely simple, something that the documentation ( or the various answers on stackoverflow I found ) don't make obvious.
The following technique works for any compiler and IDE. I tested it in windows mingw using code:blocks, which is why I am posting it as an answer to this question.
Download the zlib source code from http://www.zlib.net/
Copy all the .c and .h files from the root folder of the zlib source to a folder in your compiler search path.
Add the zlib source files to the IDE project.
Add #include "zlib.h" to your source code
Call compress or uncompress
That's it. It could hardly be simpler.
All you have to be careful about is memory management, since this is c code.
To make things even simpler for myself, I have put together a c++ wrapper which you are welcome to use, like this:
/** ZLIB C++ wrapper
Usage:
<pre>
#include "cZLIB.h"
{
// compress data in bigbuffer
raven::set::cZLIB ZLIB;
ZLIB.Compress( bigbuffer, sizebigbuffer );
// use compressed buffer, before ZLIB goes out of scope
use( ZLIB.Buffer(), ZLIB.Length() );
}
...
{
// decompress data in smallbuffer
raven::set::cZLIB ZLIB;
ZLIB.Inflate( smallbuffer, sizesmallbuffer )
// use decompressed data, before ZLIB goes out of scope
use( ZLIB.Buffer(), ZLIB.Length() );
}
</pre>
Build:
Download this code ( cZLIB.h and cZLIB.cpp ) from
https://github.com/JamesBremner/raven-set
and install somewhere in your compiler search path.
Let's assume you install it in folder .../src.
Download the zlib source code from http://www.zlib.net/
Copy all the .c and .h files from the root folder of the zlib source
to a new folder .../src/zlib
Add the files cZLIB.h, cZLIB.cpp and all the files in .../src/zlib
to the IDE project.
Build.
*/
class cZLIB
...

Related

MinGW/GCC GLFW linker issue - undefined reference to "glfwInit"

TL;DR - I have tried all solutions I could find, nothing has worked so far.
Hello, I have searched far and wide but I cannot find an answer to my problem. When I try to compile my C program with GCC, I get an undefined reference to glfwInit(). First, I tried putting the glfw .dll in the same location as the program, which did seemingly nothing. After this I tried removing the glfw libraries from MinGW's "lib" directory and replacing them with the .dll, and adding #define GLFW_DLL to the top of my .c file (same error). I also tried changing the linking order around, adding -lopengl32 and -lgdi32, renaming one of the static libraries just in case the compiler was confused, etc. Nothing seems to be working here, but I have previously installed and developed with SDL2 in the same fashion.
main.c:
#include<stdio.h>
#include<GLFW/glfw3.h>
int main(int argc, char **argv) {
if(!glfwInit()) {
printf("Failed!");
return -1;
}
printf("Success!");
getch();
return 0;
}
Instructions to the compiler:
gcc -std=c99 -o project.exe main.c -lglfw3 -lglfw3dll
Alright, I have finally solved the problem. I followed the instructions in this video: https://www.youtube.com/watch?v=bIK95aWk-Bo. The gist of the video is that you need to download CMake as well as the GLFW version found here: https://www.glfw.org/
Then, you need to hit "Configure" after setting the source and build paths. After this, hit "Generate." Then, you need to open a command prompt and locate the newly created MakeFile. I am using Windows, which means I needed to use the command mingw32-make. The library files then built successfully!
After doing this, I put the created .dll and .a files in the MinGW "lib" folder. Then, I copied the .dll and placed it in the same directory as my executable.

Problems with linking a library with a c program in linux

I want to run serial commands from a Bealgebone to a 4Dsystems display. Therefore I copied the c library found here into a directory and created a test program main.c:
#include "Picaso_const4D.h"
#include "Picaso_Serial_4DLibrary.h"
int main(int argc,char *argv[])
{
OpenComm("/dev/ttyUSB0", B115200); // Matches with the display "Comms" rate
gfx_BGcolour(0xFFFF);
gfx_Cls();
gfx_CircleFilled(120,160,80,BLUE);
while (1) {}
}
Now when I do gcc -o main main.c its says
main.c:2:37: fatal error: Picaso_Serial_4DLibrary.h: No such file or
directory
So I try linking it:
gcc main.c -L. -lPICASO_SERIAL_4DLIBRARY
which gives me the same error. Then I tried to create a static library:
gcc -Wall -g -c -o PICASO_SERIAL_4DLIBRARY PICASO_SERIAL_4DLIBRARY.C
which gives me this:
PICASO_SERIAL_4DLIBRARY.C:1:21: fatal error: windows.h: No such file
or directory compilation terminated.
What am I doing wrong? the git page clearly says this library is created for people who do not run windows.
Thanks in advance!
You're not getting a linker error; you're getting a preprocessor error. Specifically, your preprocessor can't find Picaso_Serial_4DLibrary.h. Make sure that it's in your include path; you can add directories to your include path using the -I argument to gcc.
You've had two problems. First was the picaso_whatever.h file that couldn't be found. You fixed that with the -I you added. But, now, the picaso.h wants windows.h
What are you building on? WinX or BSD/Linux?
If you're compiling on WinX, you need to install the "platform sdk" for visual studio.
If you're using mingw or cygwin, you need to do something else.
If on WinX, cd to the C: directory. Do find . -type f -name windows.h and add a -I for the containing directory.
If under Linux, repeat the find at the source tree top level. Otherwise, there is probably some compatibility cross-build library that you need to install.
Or, you'll have to find WinX that has it as Picaso clearly includes it. You could try commenting out one or more of the #include's for it and see if things are better or worse.
If you can't find a real one, create an empty windows.h and add -I to it and see how bad [or good] things are.
You may need the mingw cross-compiler. See https://forums.wxwidgets.org/viewtopic.php?t=7729
UPDATE:
Okay ... Wow ... You are on the right track and close, but this is, IMO, ugly WinX stuff.
The primary need of Picaso is getting a serial comm port connection, so the need from within windows.h is [thankfully] minimal. It needs basic boilerplate definitions for WORD, DWORD, etc.
mingw or cygwin will provide their own copies of windows.h. These are "clean room" reimplementations, so no copyright issues.
mingw is a collection of compile/build tools that let you use gcc/ld/make build utilities.
cygwin is more like: I'd like a complete shell-like environment similar to BSD/Linux. You get bash, ls, gcc, tar, and just about any GNU utility you want.
Caveat: I use cygwin, but have never used mingw. The mingw version of windows.h [and a suite of .h files that it includes underneath], being open source, can be reused by other projects (e.g. cygwin, wine).
Under Linux, wine (windows emulator) is a program/suite that attempts to allow you to run WinX binaries under Linux (e.g. wine mywinpgm).
I git cloned the Picaso library and after some fiddling, I was able to get it to compile after pointing it to wine's version of windows.h
Picaso's OpenComm is doing CreateFile [a win32 API call]. So, you'll probably need cygwin. You're opening /dev/ttyUSB0. /dev/* implies cygwin. But, /dev/ttyUSB0 is a Linux-like name. You may need some WinX-style name like "COM:" or whatever. Under the cygwin terminal [which gives you a bash prompt], do ls /dev and see what's available.
You can get cygwin from: http://cygwin.com/ If you have a 64 bit system, be sure to use the 64 bit version of the installer: setup-x86_64.exe It's semi-graphical and will want two directories, one for the "root" FS and one to store packages. On my system, I use C:\cygwin64 and C:\cygwin64_packages--YMMV.
Note that the installer won't install gcc by default. You can [graphically] select which packages to install. You may also need some "devel" packages. They have libraries and .h files that a non-developer wouldn't need. As, docs mention, you can rerun the installer as often as you need. You can add packages that you forgot to specify or even remove ones that you installed that you don't need anymore.
Remember that you'll need to adjust makefile -I and/or -L option appropriately. Also, when building the picaso library, gcc generated a ton of warnings about overflow of a "large integer". The code was doing:
#define control_code -279
unsigned char buf[2];
buf[0] = control_code >> 8;
buf[1] = control_code;
The code is okay, and the warning is correct [because the code is sloppy]. If the code had done:
#define control_code -279
unsigned char buf[2];
buf[0] = (unsigned) control_code >> 8;
buf[1] = (unsigned) control_code;
it probably would have been silent. Use -Wno-overflow in your Makefile to get rid of the warnings rather that edit 50 or so lines

How to include libssh to my project

I've installed libssh following the instructions and even though everything seems to be OK my compiler still returns the error "file not found" in the line "#include ". I guess it has something to do with directories or links (I have "make install" in the same folder where I downloaded it) but I don't know where should I put it so I can #include it in any project.
This is how I installed it:
I downloaded it and unzip it into the folder "libssh" on my Desktop (Mac).
Then I did
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
make
and finally:
sudo make install
Then in my program I have:
#include <libssh/sftp.h>
And XCode returns: "libssh/sftp.h file not found". I tried adding the libssh folder in the Desktop to the project, but I still have similar problems.
I guess I should install it (somehow) to the /usr/include folder, so that any project can use it (like pthread or many others), but I don't know how to do this.
If I include any other file in /usr/include it works fine (like ) but when I #include it returns file not found, even though if I cd to /usr/include/libssh the file libssh.h does exist.
This is the very simple sample code:
#include <stdio.h>
#include <pthread.h> //OK
#include <libssh/libssh.h> //Not OK, file not found.
int main(int argc, const char * argv[])
{
printf("Hello World!");
return 0;
}
In the tutorial is described how you have to link the library
You have two possibilities here:
As described you have to add those two lines to your code
#define LIBSSH_STATIC 1
#include <libssh/libssh.h>
You compile your code with the LIBSSH_STATIC flag.
gcc -DLIBSSH_STATIC test.c -o test.o
I thought that if you have the library in /usr/include the compiler will automatically link it. For instance, the pthread.h file is included properly without doing anything.
This is a system library which gets linked automatically most of the time. libssh is not. Thats why you have to be more specific on how to compile/link it.
Ive had a very similar problem several times and I have solved it by removing the ā‰¤ ā‰„ symbols from around my header files and using ""s and the absolute path to the header file you're including. Now this doesn't solve your libssh install problems but it will allow you to compile just the way you have it as long as you know the absolute path of your header file and all of your header's dependencies are in the respective locations that they were inteded to look for them in. Hope this helps.

Installing a new library in Linux, and accessing it from my C code

I am working on a project which requires me to download and use this. Inside the downloaded folder, when extracted I am presented with three things:
A folder called "include"
A folder called "src"
A file called "Makefile"
After some research, I found out that I have to navigate to the directory which contains these files, and just type in the command make.
It seemed to install the library in my system. So I tried a sample bit of code which should use the library:
csp_conn_t * conn;
csp_packet_t * packet;
csp_socket_t * socket = csp_socket(0);
csp_bind(socket, PORT_4);
csp_listen(socket, MAX_CONNS_IN_Q);
while(1) {
conn = csp_accept(socket, TIMEOUT_MAX);
packet = csp_read(conn, TIMEOUT_NONE);
printf(ā€œ%S\r\nā€, packet->data);
csp_buffer_free(packet);
csp_close(conn);
}
That's all that was given for the sample server end of the code. So I decided to add these to the top:
#include <csp.h>
#include <csp_buffer.h>
#include <csp_config.h>
#include <csp_endian.h>
#include <csp_interface.h>
#include <csp_platorm.h>
Thinking I was on the right track, I tried to compile the code with gcc, but I was given this error:
csptest_server.c:1: fatal error: csp.h: No such file or directory
compilation terminated.
I thought I may not have installed the library correctly after all, but to make sure, I found out I could check by running this command, and getting this result:
find /usr -iname csp.h
/usr/src/linux-headers-2.6.35-28-generic/include/config/snd/sb16/csp.h
/usr/src/linux-headers-2.6.35-22-generic/include/config/snd/sb16/csp.h
So it seems like the csp.h is installed, maybe I am referencing it incorrectly in the header include line? Any insight? Thanks a lot.
The make command is probably only building the library, but not installing it. You could try sudo make install. This is the "common" method, but I recommend you to check the library's documentation, if any.
The sudo command is only necessary if you have no permissions to write the system's include and library directories, which may be your case.
Another possibility (instead of installing the library) is telling GCC the location of the library's source code and generated binaries (by means of the -I and -L options of the gcc command.
That Makefile will not install anything, just translate the source into a binary format.
The csp.h in the Linux kernel has nothing to do with your project, it's just a naming collision, likely to happen with three letter names.
In your case, I would presume you need to add the include directory to the compilation flags for your server, like gcc -I/path/to/csp/include/csp csptest_server.c.
(Next, you'll run into linker errors because you'll also want to specify -L/path/to/csp -lcsp so that the linker can find the binary code to link to.)

run c program - stdio.h where do i get it?

Looking into learning C. As I understand it when I say #include <stdio.h> it grabs stdio.h from the default location...usually a directory inside your working directory called include. How do I actually get the file stdio.h? Do I need to download a bunch of .h files and move them from project to project inside the include directory? I did the following in a test.c file. I then ran make test and it outputted a binary. When I ran ./test I did not see hello print onto my screen. I thought I wasn't seeing output maybe because it doesn't find the stdio.h library. But then again if I remove the greater than or less than signs in stdio the compiler gives me an error. Any ideas?
I'm on a Mac running this from the command line. I am using: GNU Make 3.81. This program built for i386-apple-darwin10.0
#include <stdio.h>
main()
{
printf("hello");
}
Edit: I have updated my code to include a datatype for the main function and to return 0. I still get the same result...compiles without error and when I run the file ./test it doesn't print anything on screen.
#include <stdio.h>
int main()
{
printf("hello");
return 0;
}
Update:
If I add a \n inside of the printf it works! so this will work:
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}
Your code should have preferably
printf("hello\n");
or
puts("hello");
If you want to know where does the standard header file <stdio.h> comes from, you could run your compiler with appropriate flags. If it is gcc, try compiling with
gcc -H -v -Wall hello.c -o hello
Pedantically, a standard header file is even not required to exist as a file; the standard permits an implementation which would process the #include <stdio.h> without accessing the file system (but e.g. by retrieving internal resources inside the compiler, or from a database...). Few compilers behave that way, most really access something in the file system.
If you didn't have the file, you'd get a compilation error.
My guess is the text was printed, but the console closed before you got the chance to see it.
Also, main returns an int, and you should return 0; to signal successful completion.
#include <header.h>, with angle brackets, searches in standard system locations, known to the compiler-- not in your project's subdirectories. In Unix systems (including your Mac, I believe), stdio.h is typically in /usr/include. If you use #include "header.h", you're searching subdirectories first and then the same places as with <header.h>.
But you don't need to find or copy the header to run your program. It is read at compilation time, so your ./test doesn't need it at all. Your program looks like it should have worked. Is it possible that you just typed "test", not "./test", and got the system command "test"? (Suggestion: Don't name your programs "test".)
Just going to leave this here : STILL! in 2018, December... Linux Mint 18.3
has no support for C development.
innocent / # cc ThoseSorts.c
ThoseSorts.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.
innocent / # gcc ThoseSorts.c
ThoseSorts.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.
innocent / # apt show libc6
(Abbreviated)::
Package: libc6
Version: 2.23-0ubuntu10
Priority: required
Section: libs
Source: glibc
Origin: Ubuntu
Installed-Size: 11.2 MB
Depends: libgcc1
Homepage: http://www.gnu.org/software/libc/libc.html
Description: GNU C Library: Shared libraries
Contains the standard libraries that are used by nearly all programs on
the system. This package includes shared versions of the standard C library
and the standard math library, as well as many others.
innocent / # apt-get install libc6-dev libc-dev
So, magic... and a minute later they are all installed on the
computer and then things work as they should.
Not all distros bundle up all the C support libs in each ISO.
Hunh.
hardlyinnocent / # gcc ThoseSorts.c
hardlyinnocent / # ./a.out
20
18
17
16
... ... ...

Resources