C: How to include the squash compression library? - c

I'm fairly new to programming with c and i am having a hard time including the squash library into my program.
I cloned the repository and ran ./configure and make sudo make install.
That installed the files:
/usr/local/lib/pkgconfig/squash-0.8.pc
/usr/local/lib/libsquash0.8.so.0.8
/usr/local/lib/libsquash0.8.so.0.8.0
/usr/local/lib/libsquash0.8.so
/usr/local/lib/cmake/Squash-0.8.0/SquashConfig.cmake
/usr/local/bin/squash
And some more files in this directories:
/usr/local/include/squash-0.8/
/usr/local/lib/squash/0.8/plugins/
In the squash examples the library is included by #include <squash/squash.h> but when i am trying to compile it i get fatal error: squash/squash.h: No such file or directory
Also #include <squash-0.8/squash.h> doesnt work because then i get fatal error: hedley/hedley.h: No such file or directory That file is located at
/usr/local/include/squash-0.8/squash/hedley/hedley.h
I guess the solution is pretty simple for an experienced c programmer but i am failing here..
Do i need to set some sort of environment variable to let the compiler find the library?
And how do i link the library to the compiler anyway?
I found something like:
-rdynamic ../squash/libsquash0.8.so.0.8 but could not test it yet because of the error above.

Try to change
#include <squash/squash.h>
to
#include "squash/hedley/hedley.h"
or
#include "<squash-0.8/squash/hedley/hedley.h>"
easier and faster solution would be adding the path to your includes during compilation:
-I/usr/local/include/squash-0.8/squash/

Related

Linking md5.h library for HTTP Digest sample implementation

I am struggling to compile a simple C program from RFC 2617. The program is digtest.c and it uses digcalc.c, another file from the sample implementation. The latter one depends on two files that my compiler doesn't know about:
#include <global.h>
#include <md5.h>
At first I got this error:
digcalc.c:5:20: fatal error: global.h: No such file or directory
I resolved that by changing <global.h> to <stddef.h>, it seems. But I still get this error:
digcalc.c:7:17: fatal error: md5.h: No such file or directory
Now, md5.h seems to refer to the file found in libbsd. So I installed libbsd-dev and tried to compile the files like this:
gcc digcalc.c digtest.c -o digtest -L/usr/lib/x86_64-linux-gnu -lbsd
where /usr/lib/x86_64-linux-gnu is the location of libbsd.so and libbsd.a files. However, this does not resolve the last compilation error.
Could anyone point out what am I missing here?
Figured it out. Had to change <md5.h> to <bsd/md5.h>, as noted on libbsd page.
So instead of the original headers in digcalc.c:
#include <global.h>
#include <md5.h>
I used:
#include <stddef.h>
#include <bsd/md5.h>
Also had to change function stricmp to strcasecmp, its POSIX equivalent. After that the sample code compiled seamlessly.

"undefined reference" error after adding function to a C project

I've added a new function wiringPiVersion() to wiringPi, but after I build and install the shared library, when I attempt to compile a small C program around it, I get:
wpi_ver.c:(.text+0xc): undefined reference to `wiringPiVersion'
However, when I include it in an XS based Perl module, all works well. I don't know enough about C to figure out what's going wrong here, and I've been searching for the better part of two hours trying different things to no avail.
Here's my small C program to test the new function:
#include <stdio.h>
#include <wiringPi.h>
int main (){
char * ver = wiringPiVersion();
printf("wiringPi version: %s\n", ver);
return 0;
}
Compilation that throws the error:
gcc -o ver wpi_ver.c -lwiringPi
The addition to wiringPi's header file:
extern char * wiringPiVersion(void);
The wiringPi's .c file addition:
#define WPI_VERSION "2.36"
char * wiringPiVersion(void){
return WPI_VERSION;
}
In my Perl module's XS file, I have:
char *
wiringPiVersion()
...and my Perl module's Makefile.PL
LIBS => ['-lwiringPi'],
...and after re-installing the Perl module, I can access the function without any issues in a test script.
I'm hoping this is something simple I'm overlooking which someone may be able to point out. My question is, how do I rectify this?
So it turned out that there were two .so files generated when I rebuilt wiringPi... one in the wiringPi's build directory way under my home directory, and the other in /usr/local/lib.
After a tip in comments, I added the library path explicitly:
gcc -o ver wpi_ver.c -L/usr/local/lib -lwiringPi
...and it all fell together and works as expected:
$ ./ver
wiringPi version: 2.36
Note: I have sent Gordon the patch in hopes it gets included in the next wiringPi cut.
Update: I received an email back from Gordon and he stated that currently, only the gpio application has the ability to report the version, so he advised that he's going to add something similar to my patch in a future release.
Although already solved, I added this answer to show what gave me the hint.
Error message "undefined reference" points to a linker error (cf. answer on SO), so its about checking if the correct library is drawn.

Compilation error on include with ljpeg library in C

I have a project for college, where i need to use libjpeg (C language), to complete 2 codes the teacher gave to us. It's a about transforming a pic into ASCII symbols (like the ASCII draws, you know)
We have a code for reading a jpg and a code for writing a jpg.
The problem is i had to install the libjpeg, i THINK the installation went well but i'm not sure so i have 2 questions
How can i verify libjpeg is correctly installed ? i didn't link it to gcc so i have to use the option for saying to gcc where is jpeg-6b (the folder which contains ljpeg) so i tried this :
Typing "gcc -L/jpeg-6b" the folder is jpeg-6b and it's right on the location where i do the command. i only get an error message about the fact the input is empty (normal ok), i think if the lib was not correctly installed, i should get an error for saying me i can't use the libjpeg version, right ?
In the 2 codes i said the teacher gave to us, she puts #include <libjpeg> on the beginning of it. But i saw on the internet that people use #include <jpeglib.h>, but both of them DON'T work and i get a message telling me :
test.c:1:21: fatal error: jpeglib.h: no such file or directory
#include <jpeglib.h>
is my include bad? or is the libjpeg bad installed ? (i read the doc and i did ./configure then make like it's said)
Just as you add -L/jpeg-6b you need -I/jpeg-6b/path/to/jpeg/headers too. I would recommend a Makefile to automate this.

How do I generate included files using cmake?

I've got a tool that generates files that contain definitions and declarations. These files need to be included from other source files or headers - they aren't usable standalone.
The obvious thing to do is have a custom command to generate them. My CMakeLists.txt that does this is as follows. I'm currently using this with the GNU makefile generator.
project(test_didl)
cmake_minimum_required(VERSION 3.0)
add_custom_command(
OUTPUT test_didl_structs.h test_didl_structs.c
COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/didl.py --decls=test_didl_structs.h --defs=test_didl_structs.c ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/didl.py ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py)
add_executable(test_didl test_didl.c)
target_include_directories(test_didl PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(test_didl shared_lib)
test_didl.c is very simple:
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "test_didl_structs.h"
#include "test_didl_structs.c"
int main(void) {
}
But on the first build, make tries to build test_didl.c, which of course fails, because test_didl_structs.* haven't been generated yet. Naturally, before the first successful build of test_didl.c, the dependency information isn't known, so make doesn't know to run the python command first.
I tried a custom target, but that's no good, because custom targets are assumed to be always dirty. This means the C file is recompiled on every build and the EXE is linked. This approach won't scale.
My eventual solution was to make the output .h file an input to the executable:
add_executable(test_didl test_didl.c test_didl_structs.h)
.h file inputs are treated as dependencies, but don't otherwise do anything interesting for makefile generators. (I am not currently interested in other generators.)
So that works, but it feels a bit ugly. It doesn't actually state explicitly that the custom commands need to be run first, though in practice this seems to happen. I'm not quite sure how, though (but I'm not up to speed on reading the CMake-generated Makefiles just yet).
Is this how it's supposed to work? Or is there something neater I'm supposed to be doing instead?
(What I'm imagining, I suppose, is something like a Visual Studio pre-build step, in that it's considered for running on every build, before the normal dependency checking. But I want this pre-build step to have dependency checking, so that it's skipped if its inputs are older than its outputs.)
My eventual solution was to make the output .h file an input to the executable.
This way is correct.
It actually states, that building executable depends on given file, and, if that file is OUTPUT for some add_custom_command(), this command will be executed before building executable.
Another way is to generate needed headers at configuration stage using execute_process(). In that case there is no need to add header files as sources for add_executable(): CMake has notion of autodetecting dependencies for compiling, so test_didl will be rebuilt after regeneration of test_didl_structs.h.
execute_process(COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/didl.py --decls=test_didl_structs.h --defs=test_didl_structs.c ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py)
# ...
add_executable(test_didl test_didl.c)
Drawback of this approach is that you need manually rerun configuration stage after changing your .py files. See also that question and answer to it.
Another problem is that header file will be updated every time configuration is run.
You can try tell cmake that you are using an external source, see docs about set_source_files_properties, see this past post

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.)

Resources