How to maintain self-made libraries? - c++

I'm using Qt Creator 2.7.0 on ubuntu 13.04.
I've just recently ran into the idea of using libraries, and they're a whole new thing for me.
I've just figured that I need to have the following in my application's .pro file to use a library of my own:
LIBS += -L<lib's dir> -l<lib's name>
INCLUDEPATH += <headers' dir>
// for example:
LIBS += -L$$PWD/../MyLib/release/ -lMyLib
INCLUDEPATH += $$PWD/../MyLib/src/
As you see, I have all my projects in a folder called Programming (the .. in this case)
Each of my project have .pro and .pro.user files in the root, source files in a sub folder /src and the release in an other sub folder /release.
So, this is what my Programming folder looks like:
Programming
MyLib
MyLib.pro
MyLib.pro.user
src
myclass.h
myclass.cpp
release
libMyLib.a
Makefile
myclass.o
MyApp
MyApp.pro
MyApp.pro.user
src
main.cpp
release
main.o
Makefile
MyApp
However, I figured that I could create a folder Programming/libs/, and add libMyLib.a and myclass.h files inside that libs folder.
I would do the same for all of my libraries, and then I could always include them like this:
LIBS += -L$$PWD/../lib/ -lMyLib
INCLUDEPATH += $$PWD/../lib/
The problem is, I'd get include path for every library stored on my computer and the libs folder would become a mess, especially if there are two headers with same name on different libraries.
I'm really new to using libraries, is there a general solution on how they should be located on your computer, and how to include them into your projects?

You could mimic libraries like Boost and have a directory tree like this:
MyLib
build
Makefile, .pro or .sln file here
lib
MyLib
// your .so / .a here
include
MyLib
// your .h here
src
// your .cpp here
CMake or qmake file here
This way you have an out-of-source build tree (in build/) so that your binary files are not mixed up with your source files.
The lib/ and include/ directories are handy because you can then define an install build target. If you then type
make install
it will copy everything to usr/local/lib and user/local/include so that your App can simply do #include <MyLib/some_header.h> and you can link directly against your library binaries (because you copied everything to a location in your system wide path). There is also no danger of name clashes because you wrapped it inside your own MyLib subdirectory.

Related

Linking libtensorflow_cc.so file to QT project

I want to use tensorflow_cc library in QT creater
I tried linking the libtensorflow_cc.so in .pro file but I'm still unable to access the header files.
test.pro file:
LIBS += -L/usr/local/lib/ -ltensorflow_cc
INCLUDEPATH += /usr/local/lib/
test.cpp file:
#include <tensorflow/core/platform/env.h>
error :
tensorflow/core/platform/env.h: No such file or Directory
I have added the path of the .so file to LD_LIBRARY_PATH. Is there anyway to include the tensorflow library and use the header files in QT.
This is a similar question but it didn't quite help me.
Thanks!
Add this to the .pro file:
LIBS += /usr/lib/libtensorflow_cc.so

CMake: target_include_directories() can't find header files

At the top of my main.cpp file, No such file or directory is thrown at #include <sqlite3.h>.
Building the code manually by g++ -I"C:\Libraries\64_bit\SQLite3\include\" -L"C:\Libraries\64_bit\SQLite3\bin\" -lsqlite3 main.cpp Class1.cpp Class1.h Class2.cpp Class2.h -o main throws no errors.
CMake cannot seem to find the header, even though I've explicitly described where it is located in my file-system. According to the documentation for target_include_directories(), that should be enough:
Specified include directories may be absolute paths or relative paths. Repeated calls for the same append items in the order called.
Why is the target_include_directories() function not finding the headers, even though I've provided the exact absolute path?
I'm developing on a 64-bit Windows 10 machine, and CLion is set-up to compile with the MinGW-w64 g++ compiler.
I've downloaded the 64-bit Windows pre-compiled binary, sqlite3.dll and stored it locally in C:\Libraries\64_bit\SQLite3\bin\.
In order to access SQLite C++ functions I've also downloaded SQLite3's amalgamated source code and stored all source files in C:\Libraries\64_bit\SQLite3\include\.
I built my project in CLion, which is essentially a fancy GUI-wrapper for CMake. In my CMakeLists.txt, I've included SQLite3's headers and linked sqlite3 as follows:
cmake_minimum_required(VERSION 3.7)
project(My_Project)
set(CMAKE_CXX_STANDARD 11)
set(INCLUDE_DIRS C:\\Libraries\\64_bit\\SQLite3\\include\\)
set(LIBRARIES sqlite3.dll)
# My project's source code
set(SOURCE_FILES main.cpp Class1.cpp Class1.h Class2.cpp Class2.h)
add_executable(My_Project ${SOURCE_FILES})
# For compiler warnings
target_compile_options(My_Project PRIVATE -Wall)
# Including SQLite3's headers
target_include_directories(My_Project PRIVATE ${INCLUDE_DIRS})
# Linking against sqlite3.dll
target_link_libraries(My_Project ${LIBRARIES})
You can run into problems if you don't put paths between quotes.
Thus it is a good idea to write:
set(INCLUDE_DIRS "C:\\Libraries\\64_bit\\SQLite3\\include\\")
or, rather:
set(INCLUDE_DIRS "C:/Libraries/64_bit/SQLite3/include/")
Additionally, the CMakeLists.txt as it currently stands won't be able to find -lsqlite3. Thankfully, CMake makes finding libraries easy:
# Optionally, add 'PATHS "C:/Libraries/64_bit/SQLite3/bin/"'
find_library(SQLITE3_LIBRARY NAMES sqlite3)
If the library is discover-able on your system, the above command will return the path to the library and store that path in SQLITE3_LIBRARY. All that remains to do is link the project against the SQLite3 library:
# Link project to the SQLite3 library
target_link_libraries(MSP_Tool ${SQLITE3_LIBRARY})

cmake: how to install the include/ and lib/ directories as autotool does

I have an old project and I want to make use of cMake instead of the old autotools.
What the old program does is that, after type make, it will make libtest.a, libtest.la, libtest.so.1.0.0 etc. inside a hidden folder called .libs, then after I type make install, it will intall all libraries to a target folder $TEST_ROOT/lib (environment variable), it will also install all .h files into $TEST_ROOT/include folder.
in the Makefile.am:
source_list=test1.cpp test2.cpp
include_HEADERS=test1.h test2.h
AM_LDFLAGS="-pthread -lm -lrt"
lib_LTLIBRARIES=libtest.la
libtest_la_SOURCES=$(source_list)
libtest_la_LDFLAGS=$(AM_LDFLAGS) -static-libgcc
in configure.ac, I only see one relevant line,
if test -n "${TEST_ROOT}"; then
ac_default_prefix=${TEST_ROOT}
includedir=${ac_default_prefix}/include
fi
Frankly I don't really understand why the above codes will make .a, .la, .so etc. libraries all together, and then install them into the curresponding folder. Probably autotools can recognize the "ac_default_prefix" and "includeddir"?
Anyway, I want to do the same thing with cmake, the following is my attempt, but not a complete solution.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/.libs)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY $(CMAKE_BINARY_DIR}/.libs)
set(CMAKE_CXX_FLAGS "-O3 -Wall")
set(CMAKE_EXE_LINKER_FLAGS "-pthread -lm -lrt")
file(GLOB SOURCES "*.cpp")
add_library(test STATIC ${SOURCES})
The above code will compile libtest.a in the build folder, not in the .libs folder inside build folder (meaning that CMAKE_RUNTIME_OUTPUT_DIRECTORY etc doesn't work).
Secondly, it will only build libtest.a, there is no libtest.la, no libtest.so.1.0.0 etc.
Thirdly, I am still not sure how let make install work like the auto tools. Can I just set the target include directory and target lib directory, then make install will install all .h files and .so, .a, .la files into the target directory?
Please help.
Thanks.
You have to go to the coreesponding CMakeLists.txt and add e.g.
INSTALL(TARGETS test DESTINATION lib)
In your root CMakeLists.txt you can determine the standard installation path:
SET(CMAKE_INSTALL_PREFIX ".")
In a similar way you can install your header files:
FILE(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx")
INSTALL(FILES ${files} DESTINATION include)
You can find even more examples at: https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/Install-Commands
You can then install the files and libs with make (https://cmake.org/cmake/help/v3.1/variable/CMAKE_INSTALL_PREFIX.html):
make DESTDIR=/home/mistapink install
You might need to set CMAKE_ARCHIVE_OUTPUT_DIRECTORY too.
Aside from that, be aware that CMake doesn't work like autotools. If you want multiple libraries you need multiple add_library calls.

Path not found in .pro file in Qt

In my .pro file in Qt project, I have used these two lines for adding necessary LIBS.
LIBS += -L "../../lib/bin/libname.a"
LIBS += -L "../../rfm2g/winver/libname.lib"
error: ../../rfm2g/winver/libname.lib: No such file or directory
The compiler found the file libname.a, but could not find the libname.lib, although the relative path for both files is correct. Does anybody have an idea?
The -L option wants a directory for -l to search, not the path to the actual library.
So you should either write e.g.
LIBS += -L../../lib/bin -lname
LIBS += -L../../rfm2g/winver -lothername
Or link with them directly
LIBS += ../../lib/libname.a
LIBS += ../../rfm2g/winver/libname.lib
Also make sure that the paths actually are correct. If you change to the build directory, and try to list the files (using ls or dir depending on platform) using the paths you have, can you list both files?

Add static .a library in QtCreator

I want to use functionality of a math library ALGLIB and it's offered in .h and .cpp files. So I build it and added all the .o files to alglib.a. I copied it to my source directory and added these lines to my .pro file:
INCLUDEPATH += /path/to/ALGLIB/cpp/src
LIBS += -Lalglib
Well - I still get those "undefined reference to ..." errors when trying to build.
-L sets a directory in which the linker should search for libraries.
-l sets a library file to link in the following way: -lalglib will look for a file named libalglib.a in all directories that are set with -L
Adding a file to LIBS without anything will link that exact file.
So either:
LIBS += alglib.a
or, provided that the alglib file name is libalglib.a:
LIBS += -Lalglib-directory -lalglib