Including SO files without headers - c++

I have recently involved myself in making a basic game engine. I have decided to place all of my middleware into an Externals directory, where a bash script builds all my middleware into shared object files in the Binaries directory.
In my CmakeLists.txt file, I am able to link these libraries into my main executable, like so:
add_library (glfw SHARED IMPORTED)
set_target_properties (glfw PROPERTIES IMPORTED_LOCATION
${ENGINE_BINARIES_DIR}/Libraries/Shared/libglfw.so.3.2
)
...
target_link_libraries (Engine glfw)
However, when I try to include GLFW/glfw3.h in my main file, it fails to compile. This makes sense, because there is no glfw3.h file; however, all other attempts at including glfw into my project have failed.
TL ; DR
What is the best way to include headers from an existing shared object library? Is it possible to achieve this without an includes/glfw directory, or would one need to modify their code / project structure in order to load these functions?

I realize my mistake now.
I did a bit of research on shared objects / DLL's and building GLFW before posting this question; however, I believe I was still rather confused as to what a shared library was and how it worked.
I now realize that you do, in fact, need to include the header file; as it contains the declarations of the middleware code, while the libglfw.so.3.2 library contained the definitions of the code.
I have thus solved my issue by keeping the .so file in the Libraries/Shared directory and the GLFW header file in the External directory, and using CMake to point the compiler / linker to both.

Related

Where does target_link_libraries look for the required files?

I am building a project from source and am trying to understand what is happening in the CMakeLists.txt files.
Where exactly is target_link_libraries looking for the required library files?
The specific CMakeLists.txt file I have has:
target_link_libraries(MyApplication PRIVATE
Magnum::Application
Magnum::GL
Magnum::Magnum
Magnum::Shaders)
I found folders that have the names GL and Shaders in a directory called Magnum in the project, and they have a collection of header files in them. I believed that target_link_libraries is telling CMake to include the libraries in the GL and Shaders folder.
However, I cannot seem to find a corresponding folder for Application, hence my line of reasoning must be flawed.
I do know target_link_libraries is doing something related to allowing the finally-put-together program to be able to use a set of libraries.
What exactly does target_link_libraries do? Where does it look for the required files in order to be able to use the libraries it needs to?
target_link_libraries doesn't link anything automatically. You should have a target previously created via add_library (or add_executable), where all files are listed.
The way these targets added into your CMake project may differ. E.g. you may have a library source files with CMakeLists.txt configuration (where the said add_library command is) under some folder libs/mylib. Then in your CMakeLists.txt you may have the library added with add_subdirectory(libs/mylib). Another option is to add the library with find_package.
In your specific case, you pass targets to target_link_libraries(). Targets with a shape like Magnum::Application etc are either imported targets or ALIAS targets.
From what you say, it seems than Magnum is vendored into your project, so I guess your are linking ALIAS targets, like the one defined here https://github.com/mosra/magnum/blob/cfc02599e54e02337dd56bb61f70b2e61eb9ce8d/src/Magnum/CMakeLists.txt#L295
Targets defined by add_library() or add_executable() in CMake are an abstraction carrying several informations, including location of files.

cmake use library target in added executable

I have started a new c++ project which has several executables and a relatively large amount of shared code.
root
CMakeLists.txt
Common
Application1
Application2
....
So the multiple applications all get compiled with their unittests without issues. But since they depend on the shared code in Common I have the recompile the shared code for each project once I update something there.
So I am wondering if it would be possible to add the library target. And build that first. And then I link my code to that library.
This seems like a relatively normal thing to do but I can't find anything about it on google.
Any help is appreciated.
Yes this is possible.
You have to add a CMakeLists file to the Common folder and in it you compile it as a library
# Add required source files.
add_library(Common ...)
# Include required header files. They must be public to be recognized where they are needed.
target_include_directories(Common PUBLIC ...)
Then in the project's CMakeLists you use:
add_subdirectory(Common) // Will call the other CMakelists
...
# Link to the required libraries.
target_link_libraries(Application Common)

decoupling app and libraries in CMake project

I had a project that was configured to be:
CMake Project
static Lib A src (depends on B)
static Lib B src (depends on Qt)
App src (statically links with LibA)
Each of these folders had its own CMakeLists.txt but all were part of the same CMake project. Things were working fine.
Then for the purpose of more easily separating the library source and the app source into different source code repositories, I started to learn about the creation of CMake packages and performing find_package on LibA. I rearranged things so that now the libraries are their own CMake project, which requires I run "cmake --build . --target install" to put the packages in a common area (not in the build folder).
The app similarly became its own CMake package, and I thought I would only need to find_package(LibA). It turned out I also needed to find_package on LibB because there was one header that the App needed. But the unexpected part is that the App needed to find_package on Qt5Widgets, Qt5Core, and Qt5Gui just as LibB did. That's the part that I don't quite understand. When everything was one giant project, the App's CMakeLists.txt only needed to link against LibA. Was all of the other stuff just taken care of without me knowing? Am I naive to think that performing find_package on LibA and LibB would somehow cause the Qt libs to be linked in to the App as well?
This might be a lousy question, because I have things working again. I just want to make sure I understand the why.
Using static libraries in C++ does not pull in their dependencies, so they have to be specified explicitly while linking the executable (as compared to dynamic ones).
A static library is essentially a pre-compiled archive of functions (an object file), which get linked into your applications by your C++ linker in a similar way as any other object file would. As such, it does not include information about its dependencies.
A shared (dynamic) library is a more complex (and generic) thing, allowing to load and link code run-time. This is done by a dynamic linker, which will also bring it any dependencies of the loaded library recursively.
For this reason, if you want to avoid specifying the dependencies explicitly, a dynamic library might be a better choice (it might be a better choice for a variety of other reasons as well :) ).

creating a static library and linking using Cmake

I have a application which need to use two libraries (pugixml and lua) and need to be an multi-platform build capable. I am trying to use Cmake for this. Since I have three different solution (two for creating static libraries and one solution which actually uses that libraries). So far what I do is run Cmake for those two libraries and copy those static libraries manually to the lib folder into application and run cmake again.
I need to reduce the three step and make it as a single step so that I can handle the multi-platform build in a single shot.
I need to know, should we need to create a dynamic link library or shared library or static library for these kind of operation?
And need help on how to do it. I tried creating the source folder of pugixml and copy the cpp/hpp/h file and wrote a cmakelists file like
set(HEADERS pugixml.hpp pugiconfig.hpp)
set(SOURCES ${HEADERS} pugixml.cpp)
add_library(pugixmlLib STATIC ${SOURCES})
target_link_libraries(pugixmlLib pugixml)
On the solution I could see my application project and pugixml project, but on my application project linker property I could find pugixml library.

how to add library source in cmake

i can't seem to find in google/stackoverflow how do i add a library to my project using the library sources so that in make time it will compile the library and then my project and then link between them.
the library i'm trying to add is curlpp
as of now I've tried the following:
add_library(curlpp STATIC IMPORTED ./curlpp)
target_link_libraries(myExec curlpp)
link_directories(./curlpp/src/)
include_directories(./curlpp/includes)
but it has no effect
You first need to add the subdirectory to actually build the library, then you can add the actual library for linking.
If the library is not a CMake project you might need to add a simple CmakeLists.txt file in the library, that executes the actual configuration and building.
You might also use custom commands from the top-level CMakeLists.txt file to configure/build the library.
Basing off on Some programmer dude's response the following commands allowed me to statically link with curlpp:
add_subdirectory(./vendor/curlpp)
set_property(TARGET curlpp PROPERTY IMPORTED_LOCATION ./vendor/curlpp/libcurlpp.a)
target_link_libraries(my_target curlpp)