How do I install a c++ library so I can use it? - c++

I have this library called BASS which is an audio library which I'm going to use to record with the microphone. I have all the files needed to use it, but I don't know how to install the library. I tried taking the example files and putting them in the same directory as the bass.h file. But I got a bunch of errors saying there are function calls that doesn't exist.
So my question is, how do I install it to be able to use it?

Installing a C++ library means specifying to interested software (eg. a compiler) the location of two kinds of files: headers (typical extensions *.h or .hpp) and compiled objects (.dll or *.lib for instance).
The headers will contain the declarations exposed to the developer by the library authors, and your program will #include them in its source code, the dll will contain the compiled code which will be or linked together and used by your program, and they will be found by the linker (or loaded dynamically, but this is another step).
So you need to
Put the header files in a location which your compiler is aware of (typically IDE allows to set so-called include directories, otherwise you specify a flag like -I<path-to-headers> when invoking the compiler)
Put the dll files in a location which your linker is aware of (surely your IDE will allow that, otherwise you speficy a flag like -L<path-to-libraries> -l<name-of-libraries>
Last but not least, since I see that BASS library is a commercial product, probably they will have made available some installation instructions?

Run this command in a terminal or console.
cpp -v
Notice at the end of the output, you'll see a line like this:
#include<...> search starts here:
There will be a list of directories below that line.
Move the package folder to one of those directories.
Then try importing the module with <>.

See the code below code and don not forget to put bass.dll in the directory of your exe file and include the file bass.lib with your project and don not forget also to include the path to bass.h and bass.lib in the default include and lib path of your project.
#include <iostream>
#include "bass.h"
using namespace std;
int main(int argc, const char **argv)
{
if (!BASS_Init(-1, 44100, 0, NULL ,NULL))
{
cout<<"Can't initialize device";
return -1;
}
int stream = BASS_StreamCreateFile(false, "D:\\mypro\\Trans_Langs\\germ\\quran_amma\\Translations\\Sound_aya\\Sora1\\Hafs\\basfar\\a7.mp3", 0L, 0L, 0);
if (stream != 0)
{
// play the stream channel
BASS_ChannelPlay(stream, false);
}
else
{
// error creating the stream
cout<<"Stream error: {0}", BASS_ErrorGetCode();
}
getchar();
BASS_StreamFree(stream);
// free BASS
BASS_Free();
return 0;
}

If there are files named configure, Makefile or install you can try running them in that order. After that, any program that wants to link with this library must use a command like this:
c++ <your_program.cpp> -l<library_name> -L<path_where_library_is_installed>
The library path is usually the original library folder itself, unless you explicitly change it or the library itself puts its files in global locations like /usr/local or something like that.

Related

How to handle library's function files (not header files) in autotools?

So recently I've been trying out autotools to build a C++ Library. Originally I was just working on pure custom classes, which is quite easy to just #include and then compile with g++. But when I want to write some custom functions for the library, I've learnt that it's a bad practice to write functions within header file, but rather I should declare it in header then wrote it in a separate .cpp file. Which later I've tried and successfully compiled with g++ ./lib/**/*.cpp src/main.cpp.
So basically my project structure is that codes are put under src/, headers are under include/ and functions are put under lib/. And following is my src/Makefile.am
AUTOMAKE_OPTIONS = subdir-objects foreign
bin_PROGRAMS = main
include_HEADERS = -I../include/**/*.hpp
main_SOURCES = -I../lib/**/*.cpp main.cpp
And for the endpoints' directory (under lib/) I have something like following
main_SOURCES = stdout.cpp
But it gave me error that no program named main, so I figured maybe all those function files has to be compiled first, so I changed them into
noinst_PROGRAMS = stdout
stdout_SOURCES = stdout.cpp
But then they gave me the following error
/usr/sbin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
I know that the error meant that there's no main() written in the file, but since it's a library function file, it doesn't meant to have a main(), it's meant to be called by other file (like main.cpp). And to here I'm stuck.
I've tried to find documentation online, but it seems that most of them are targeted at C programs instead of C++, which I'm not sure if those steps are compatible. And I remember C++ libraries are compiled into .so or .o file while most tutorials seems to be using .la files.
MWE
src/main.cpp
#include"../include/conn/bash/stdout.hpp"
#include<string>
#include<iostream>
int main() {
std::string o=d::conn::bash::exec("ls");
std::cout << o << std::endl;
return 0;
}
include/conn/bash/stdout.hpp
#ifndef __CONN_BASH_O__
#define __CONN_BASH_O__
#include<string>
namespace d { namespace conn { namespace bash {
std::string exec(const char*);
}}}
#endif
lib/conn/bash/stdout.cpp
#include"../../../include/conn/bash/stdout.hpp"
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>
std::string d::conn::bash::exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
// https://stackoverflow.com/a/478960/8460574
Compiled and tested with g++ ./lib/**/*.cpp src/main.cpp
I've tried to find documentation online, but it seems that most of
them are targeted at C programs instead of C++,
"Most of them" suggests that you are searching out tutorials. Documentation would be the Automake manual, which you would be well advised to read. It covers these topics and many more that you will want to know about as you continue with the Autotools, and with Automake in particular. At minimum, you should know how to find the manual so as to consult it at need. Tutorials and guides can be helpful, but they should be regarded as supplements to the manual, not primary sources.
which I'm not sure if
those steps are compatible.
They mostly are. The main thing to be aware of is that command-line options for the C compiler are specified via a CFLAGS primary (see below), whereas those for the C++ compiler are specified via a CXXFLAGS primary.
And I remember C++ libraries are compiled
into .so or .o file while most tutorials seems to be using .la files.
You seem to be confused. The formats associated with those extensions are not language-specific, and .o does not designate a library at all.
.o is the conventional extension for the object file arising from compiling a single source file. These can be linked into an executable, or they can be gathered together into a library, but they are not libraries themselves.
Conventional UNIX library extensions are .a for static libraries and .so for shared libraries. This applies to any language that can be used to build general-purpose link libraries, including C, C++, Fortran, and a variety of others.
The .la extension is something else. It designates a libtool library. Libtool is another of the autotools, focused on abstracting system-specific details of building and using libraries. This is again language independent. Building a libtool library will cause either a corresponding static library, a corresponding shared library, or both to be built and installed, depending the options specified in the Autotooling and / or on the configure command line.
You should use libtool if you are building shared libraries with the Autotools. You may also use it if you are building only static libraries (.a), but it is a bit simpler in that case to leave libtool out of the picture.
As for the specific question posed, you write:
And for the endpoints' directory (under lib/) I have something like
following
main_SOURCES = stdout.cpp
But it gave me error that no program named main,
Always present the actual text of the error message (as text), rather than a paraphrase. If you have to ask a question about it here, then there is a significant risk that your understanding of the message is incomplete or wrong, and therefore that your paraphrase is misleading.
In this case, I am relatively confident that Automake's complaint was that there is no target named "main". The line you've given specifies a source list for such a target, but Automake does not find that target defined in that Makefile.am file. The difference between "program" and "target" is a bit subtle, but significant.
Supposing that you are trying to build a convenience library -- that is, one that groups functions for compile-time use in building other targets, but is not intended to be installed as a standalone library* -- you could get it with something like:
noinst_LIBRARIES = libendpoints.a
That consists of thee main pieces:
LIBRARIES is the "primary", specifying what kind of definition is being given. In this case, it is the definition of a list of static library targets included in the project.
libendpoints.a specifies the name of a (static library) target. This is an external name: the build will generate a file by this name in the build tree. Do make a habit of using standard naming conventions for this, such as I demonstrate.
noinst specifies where the built target will be installed by make install. This particular value is a special one indicating that the target will not be installed at all. If you wanted it installed in the configured libdir then you would instead say lib.
The properties of that target must be given by other definitions, based on a munged form of its name. For instance, its source list might look like this:
libendpoints_a_SOURCES = stdout.cpp
That again consists of three pieces:
SOURCES is again the primary. In this case, it says that the definition provides a source list for some target.
libendpoints_a identifies the target whose source list is being given. It is a munged form of the target name, with characters that cannot appear in variable names replaced by '_' characters.
stdout.cpp is the (single-element) source list.
To use that, the main program's properties would also need to specify that the library should be linked. That would mean something along these lines in the Makefile.am in which the main program target is defined:
main_LDADD = lib/endpoints/libendpoints.a
That is again a three-part definition, whose interpretation I leave as an exercise.
*And if you wanted a static library that does get installed to the system then you would swap out the "noinst" for a prefix that identifies the installation location, such as "lib". And there is a slightly different form for libtool-mediated libraries, including shared libaries.
If you're just defining a convenience target for you library, you should be able to do so by declaring it as noinst_LIBRARIES = libmine.a and then declaring it as a stdout_LIBADD.
But most likely, if you don't want this as an installed library, you just want to list the sources directly in a single, non-recursive Makefile.am file, see https://autotools.io/automake/nonrecursive.html
If you do want your library to be installable, then you want to use libtool: https://autotools.io/libtool/index.html

How to include a "custom" library in Code::Blocks? (Windows 7)

Ok, I've never did this before and I'm having problems to understand how it works (Especially the "include" part). Here's my code:
#include <joypp1.02/app.h>
#include <joypp1.02/objects.h>
void event_plot()
{
if (App::event_type() == ALLEGRO_EVENT_DISPLAY_CLOSE)
{
App::shut_down();
}
if (App::event_type() == ALLEGRO_EVENT_KEY_DOWN)
{
if (App::event().keyboard.keycode == ALLEGRO_KEY_ESCAPE)
{
App::shut_down();
}
if (App::event().keyboard.keycode == ALLEGRO_KEY_ENTER)
{
cout << "Whatever! ";
}
}
}
void visual_plot()
{
static Image x("sample.png");
x.draw();
}
int main(int argc, char **argv)
{
App app(800, 600);
app.set_background_color(200, 0, 0);
app.add_event_scene(Scene("Event Plot", event_plot));
app.add_visual_scene(Scene("Visual Plot", visual_plot));
app.run();
return 0;
}
joypp1.02 is the dynamic-link library I've compiled, and it's in its own "output" folder (Together with the import file):
joypp1.02 has only two headers: app.h e objects.h. How do I import them? The library is in the linker (I want to keep it in the output folder of the library, because It's in constant development. BUT, I want to compile it only as a DLL, so I have a separate project that uses the DLL).
And the folder with the joypp1.02.dll is in the Search Directories of the compiler.
And if I try to include like this:
#include "joypp1.02.h"
I get:
fatal error: joypp1.02.h: No such file or directory
So, I'm lost. How to include a "custom" library in Code::Blocks in Windows? How do I know the include name? Why it's a header like "joypp1.02.h" if it's a .a file?
Disclaimer: I've used the word "custom" to emphasize that it was written and compiled by me (So, probably more problems than just importing some "official" and "pro" one).
Well, I've solved it. I was missing the point of the actual function of a dynamic-link library. I was forgetting to include the header files (And I've remembered from other libraries that, indeed, I include their .h files apart from the .a or .lib import library files, and the binary .dll(s) (I thought they were inside the import library file or something, and that only the import library and .dll were required)).
So you, possible reader from the future, in face of the same problem: Hear me! You must make the header files of your library visible to the compiler (Include in the "search directories", in the compiler tab in Code::Blocks), and at the same time, link the import library .a or .lib file, AND, if no search directory is specified under the linker tab, have the .dll binary in the folder of your application.
If by any means, you're still lost, read this:
http://wiki.codeblocks.org/index.php?title=FAQ-Compiling_(errors)#Q:_What_do_I_need_to_know_when_using_3rd_party_libs.3F

How to return the directory of the cpp file?

I am trying to return the path of the cpp file I am running. Does anyone know a method or a way to implement this? For example lets say I have this file test.cpp at the path in my computer "C:\Programming\Visual Studio\Test\Test\test.cpp".
Is there a way to get this path without manually typing it? I am trying to determine a method of using c++ to return this path.
For my ftp program I need to get the list of .txt, .pdf, .etc files, which are located at the same path as the .cpp file. This is why I want the .cpp path and not the .exe path.
Any suggestions?
What about this??
#include<iostream>
#include <string>
using namespace std;
int main()
{
string file_path = __FILE__;
string dir_path = file_path.substr(0, file_path.rfind("\\"));
cout<<dir_path<<endl;
return 0;
}
As you state in comments:
"... but for my ftp program I need to get the list of .txt, .pdf, etc. files, which are located at the same path as the .cpp file."
You should have a kind of resource directory defined, that is created when your application is installed, and where your .txt, .pdf, etc. files will be copied by the installation process.
This way implies you have an installation process (which could be the simplest form, by just creating and extracting a .zip archive), that bundles the executable .exe file along these resource files, to be installed on the target machine. Usually, you won't include the source files there.
It's actually a bad idea, to refer to the location of your source .cpp file in this case, since the finally installed program usually doesn't have a notion of the source it was compiled from. Also the program may be installed on a machine with a different environment (especially development environment) from yours.
A better entry point for a generic installation path, is to refer relative to the path that's given you with the argv[0] argument of your main() program entry. It provides you with the full path of your installed executable file.
For the rest, use the operations available from e.g. the boost::filesystem library to manipulate path and file names in a portable way, as mentioned in comments.
Linux:
#include <string>
#include <iostream>
int main()
{
std::string file {__FILE__};
std::string directory {file.substr(0, file.rfind("/"))};
std::cout << directory << std::endl;
return 0;
}
This would give you the directory containing the source file, relative to where its being built.

segfault because of missing header files

I had forgotten to put a 3rd party "header only" library header (.h) files into the correct path when building a shared object. It built fine - retrospectively surprising.
When run a segfault occurred exactly at the line when that 3rd party lib was used in my shared object.
The part I do not understand is when I copied those header files to the path specified with #include, I could not cause a segfault. I did not even re-build the object. The very strange thing is that when I mv the dir the header files are in, it still worked - no segfault. However, when I completely rm the dir, it crashed. Does it look for header files the current dir and subdirs? I've also got that header-only library in the standard(?) /usr/local/include
I've not worked with shared objects before. I usually create static objects and include them in the build. The flags I used to create the shared object in question are -shared -fPIC
I'd like to understand this behavior. It's interesting because of deployment. Do I need to include those header files when deploying on the production machine? Essentially I don't want to have that as a dependency as it is a "header-only" lib.
edit
Code:
#include <rapidjson/document.h>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
void MyClass::myFunction()
{
rapidjson::StringBuffer string;
rapidjson::Writer<rapidjson::StringBuffer> jsonWriter(string);
}
Here is a link to the debug session:
http://pastebin.com/a0FaQwf1
You never need to supply header files to the user in order to run the program.
Your library probably just refines defaults,
that is the reason why it do not fail when missing at compile time
An explanation for the strange move/remove behavior could be that the shared object was still loaded into memory during the move and kept an open file handle to something in the include dir.
You know, under ext2/3/4 open files are connected to inodes and not to dir paths. Thus moving an open file won't harm. On the other hand IIRC also removing won't harm. The freeing of the inode will be delayed until all processes have closed the file. Maybe this just happened between your mv and rm.

C++ include libraries

Ok, so it's been a while, and i'm having problems with #includes
So I'm doing
#include "someheader.h"
but it's giving me
fatal error: someheader.h: No such file or directory
It's a system wide library I guess you could say.
I'm running arch linux and I installed the library from the repo, and I think the .h files are in /usr/include.
I could just copy all the header files into the folder my code is in but that would be a hack.
What is the "right" way to do this?
Edit: I wasn't correct by saying the .h files were in /usr/include, what I meant was that the library folder was in there
So, Emile Cormier's answer worked to a certain extent.
The problem now is that there are some include in the header file and it seems from the methods I'm trying to access that those includes are not happening
it's giving my the error
undefined reference to Namespace::Class::method()
Edit:
Ok so the final answer is:
#include <library_name/someheader.h>
And compile with
g++ code.cpp -llibrary_name
Sometimes, header files for a library are installed in /usr/include/library_name, so you have to include like this:
#include <library_name/someheader.h>
Use your file manager (or console commands) to locate the header file on your system and see if you should prefix the header's filename with a directory name.
The undefined reference error you're getting is a linker error. You're getting this error because you're not linking in libsynaptics along with your program, thus the linker cannot find the "implementation" of the libsynaptics functions you're using.
If you're compiling from the command-line with GCC, you must add the -lsynaptics option to link in the libsynaptics library. If you're using an IDE, you must find the place where you can specify libraries to link to and add synaptics. If you're using a makefile, you have to modify your list of linker flags so that it adds -lsynaptics.
Also the -L <path_to_library> flag for the search path needs to be added, so the linker can find the library, unless it's installed in one of the standard linker search paths.
See this tutorial on linking to libraries with GCC.
You'd use #include <someheader.h> for header files in system locations.
#include "someheader.h" would try to include the file someheader.h in the directory of your .c file.
In addition to including the header file, you also need to link in the library, which is done with the -l argument:
g++ -Wall youprogram.cpp -lname_of_library
Not doing so is the reason for the "undefined reference .. " linker errors.
The quick fix is to do use:
#include <someheader.h>
assuming that someheader.h is in the standard include locations (to find it use the command locate someheader.h in a shell. If it is in /usr/include it is in a standard location. If it is in a subdirectory of /usr/include you only need to add the part of the directory up to /usr/include in the #include directive (e.g. #include <fancy_lib/someheader.h>)
However, this is only half of the story. You also will need to set up your build system in a way that locates the given library and adds its include path (the path under which it's header files are stored) to the compiler command (for gcc that is -I/path/to/header). That way you can also build with different versions by configuring them in your build system. If the library is not header-only you will also have to add it to the linker dependencies. How this is achieved in your build system is best found out by consulting its documentation.