How to integrate Third party libraries into a Portable Custom Library - c++

I have been trying to figure out how to link in CMake and it is making me go crazy. So far I have successfully been able to run my library as an executable(add_executable), but when changing it to a library(add_library) and trying to include it in another project it falls short. The issue is including the third party libraries in my library. The third party libraries are not found and therefore are failed to be included in executable project which results missing libraries. I have tried doing it by statically compiling, but I got lost and fell back to shared libraries.
Basically I am trying to figure out how to compile a library so that its dependencies are portable with the library.
Example Header
#ifndef APP_H
#define APP_H
#include <iostream>
#include <vector>
#include <cstdint>
#include <SDL.h>
#include <SDL_ttf.h>
#include <Box2D/Box2D.h>
#include "Class.h"
#include "Vec2.h"
#include "Vec4.h"
using namespace std;
class App{
/*contents*/
};
#endif
Here is my main CMakeList.txt
add_subdirectory(extern)
cmake_minimum_required(VERSION 3.7)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
set(PROJECT_NAME Project)
project(${PROJECT_NAME} VERSION 0.1.0)
add_subdirectory(src)
Here is my source CMakeList.txt
file(GLOB HEADER_FILES "${CMAKE_SOURCE_DIR}/include/*.h")
file(GLOB SOURCES "*.cpp")
file(GLOB EXTERN_SOURCES "${CMAKE_SOURCE_DIR}/extern/stb/include/*.h" "${CMAKE_SOURCE_DIR}/extern/stb/src/*.cpp" )
include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_SOURCE_DIR}/include/Chassis2D" PUBLIC "${CMAKE_SOURCE_DIR}/extern/SDL2/include/" PUBLIC "${CMAKE_SOURCE_DIR}/extern/SDL2_ttf" PUBLIC "${CMAKE_SOURCE_DIR}/extern/stb/include/")
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADER_FILES} ${EXTERN_SOURCES})
target_link_libraries(${PROJECT_NAME} PUBLIC SDL2 PUBLIC SDL2_ttf PUBLIC box2d)
set_target_properties( ${PROJECT_NAME}
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin"
)
Thanks in advance!

Related

How to use glog in third party (C++ program)? I have added it in CMakeLists.txt but there still be file not found

CMakeLists.txt in the project source path:
The fatal error (fatal error: glog/logging.h: No such file or directory):
How to correctly include it as header file? Thanks for helping.
I have not used GLOG but I guess it is similiar to Boost:
set(find_package(Boost REQUIRED))
find_package(Boost 1.75.0 COMPONENTS program_options filesystem REQUIRED)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIR})
target_link_libraries( PhysGeo_lib PUBLIC ${Boost_LIBRARIES} )
else()
message("'Boost' can not be located on this machine!")
endif()
and then just include proper header files:
// Boost
#include <boost/program_options/option.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/filesystem/path.hpp>

How To Include External Libraries in CMake Project

I am confused on how to statically include the source code of SDL2. I am trying to do this to make a library I am working on more portable.
When I was setting this up as executable the library was compiled with it fine, but when I changed it to a library it wouldn't include the library.
Currently, when I try to include my library in another project it says "Cannot open include file: 'SDL2/SDL.h': No such file or directory". So it leads me to think that the cause of the error is that the include directories aren't exported with the static library.
My Filesystem:
include
--Header Files
src
--Source Files
extern
--SDL2
build
Here is an example of the file causing the error:
#include <iostream>
#include <SDL.h> //Error
using namespace std;
/* The code */
Here is an example of my main CMakeLists.txt:
cmake_minimum_required(VERSION 3.7)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
project(MyProject VERSION 1.0.0)
set(SDL2_SOURCE_DIR “${CMAKE_SOURCE_DIR}/extern/SDL2”)
add_subdirectory(extern/SDL2)
add_subdirectory(src)
Here is an example of my src CMakeLists.txt:
set(PROJECT_NAME MyProject)
file(GLOB HEADER_FILES "${CMAKE_SOURCE_DIR}/include/*.h")
file(GLOB SOURCES "*.cpp")
add_library(${PROJECT_NAME} ${SOURCES} ${HEADER_FILES})
target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_SOURCE_DIR}/include" PUBLIC "${CMAKE_SOURCE_DIR}/extern/SDL2/include")
target_link_libraries(${PROJECT_NAME} PRIVATE SDL2main SDL2-static)
set_target_properties( ${PROJECT_NAME}
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin"
)
From sdl2 CMakeLists.txt try:
set(SDL_STATIC 1)
add_subdirectory(extern/SDL2) # And I recommend EXCLUDE_FROM_ALL
Also to be sure add a check:
foreach(i IN ITEMS SDL2main SDL2-static)
if(NOT TARGET ${i})
message(FATAL_ERROR "${i} is not a target")
endif()
endif()
target_link_libraries(${PROJECT_NAME} PRIVATE SDL2main SDL2-static)

DLL Made with CMake makes the program crash

I'm struggling to use a DLL generated using CMAKE and C++. I'm able to build the library, include it and build the target project, the problem is that when I run the target build it crashes immediately.
My code is super easy and I don't know what I'm missing.
The DLL is built using CMAKE in a separate project. Here's the code
DLL PROJECT:
CMakeLists
cmake_minimum_required(VERSION 3.5)
project(LibProj LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_definitions("-DBUILD_LIB")
file(GLOB
INCLUDE_FILES
baselibraryclass.h
)
file(GLOB
SOURCE_FILES
baselibraryclass.cpp
)
add_library(yourlib SHARED ${INCLUDE_FILES} ${SOURCE_FILES} )
baselibraryclass.h
#ifndef BASELIBRARYCLASS_H
#define BASELIBRARYCLASS_H
#ifdef BUILD_LIB
#define EXT_DLL __declspec(dllexport)
#else
#define EXT_DLL __declspec(dllimport)
#endif
#include <string>
class EXT_DLL BaseLibraryClass
{
public:
BaseLibraryClass();
};
#endif // BASELIBRARYCLASS_H
baselibraryclass.cpp
#include "baselibraryclass.h"
#include <iostream>
EXT_DLL BaseLibraryClass::BaseLibraryClass()
{
std::cout << "Hi from the library Class Object " << std::endl;
}
Target project
CMakeLists
cmake_minimum_required(VERSION 3.5)
project(TargetProject LANGUAGES CXX)
#Including the path of the library header
include_directories(D:/TestingDLLNativeCpp/Library/include)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(TargetProject main.cpp)
#The path of the built library is D:/TestingDLLNativeCpp/Library/Debug/yourlib.lib
target_link_libraries(TargetProject PRIVATE D:/TestingDLLNativeCpp/Library/Debug/yourlib.lib)
Target project main.cpp
#include <iostream>
#include <baselibraryclass.h>
using namespace std;
int main()
{
BaseLibraryClass testObk;
return 0;
}
As I wrote above, cmake configures properly and the compiler is able to build for both projects, however the target executables crashes immediately.
What am I doing wrong o.O??
Thanks for the attention
The issue of the dll not being included in the build directory might be solved by setting the CMAKE_RUNTIME_OUTPUT_DIRECTORY. However, a better practice would be to set the output directory of the .dll on a target basis. This will ensure that you have no unwanted side-effects in the long run.
set_target_property(yourlib PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")

Using cmake to compile glfw on windows

I didn't know how to title this, it's quite unaccurate. Anyway here is the question:
I want to create a CMake project in Visual Studio that has to use glfw. However, I don't want to use the precompiled binaries, I want to compile glfw along with my application using the CMakeLists.txt file.
Here's my CMake file:
# CMakeList.txt : CMake project for BasicMandelbrotAnimation, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.8)
project(BasicMandelbrotAnimation)
# Set the main file to main.cpp
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:mainCRTStartup")
# Include our different directories
include_directories(include)
include_directories(source)
# Include all source files in source directory
file(GLOB SOURCE source/*)
# Compile GLFW
add_subdirectory(extlibs/GLFW)
# CMake GLFW Settings
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
# Add source to this project's executable.
add_executable (${PROJECT_NAME} ${SOURCE})
target_link_libraries(${PROJECT_NAME} glfw)
find_package(OpenGL REQUIRED)
target_include_directories(${PROJECT_NAME} PUBLIC ${OPENGL_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${OPENGL_gl_LIBRARY})
target_link_libraries(${PROJECT_NAME} ${OPENGL_glu_LIBRARY})
# TODO: Add tests and install targets if needed.
The error I get is "Cannot open include file: 'unistd.h': No such file or directory" which is bugging me out because this is a UNIX file so how can I adapt the files to compile in windows?
Thank you.
EDIT:
This questions seemed like a duplicate, but isn't really. unistd.h is only the first problem, let's have a look at the problematic file:
#ifndef _glfw3_x11_platform_h_
#define _glfw3_x11_platform_h_
#include <unistd.h>
#include <signal.h>
#include <stdint.h>
#include <dlfcn.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xcursor/Xcursor.h>
// The XRandR extension provides mode setting and gamma control
#include <X11/extensions/Xrandr.h>
// The Xkb extension provides improved keyboard support
#include <X11/XKBlib.h>
// The Xinerama extension provides legacy monitor indices
#include <X11/extensions/Xinerama.h>
#if defined(_GLFW_HAS_XF86VM)
// The Xf86VidMode extension provides fallback gamma control
#include <X11/extensions/xf86vmode.h>
#endif
Here it is, first of all, unistdh is missing, I replace it with what was proposed in another post, but now it's the others that are missing, specifically dlfcn.h and X11 files and I don't know how to fix that.
Thank you.
EDIT2:
Forget what's inside x11_platform.h. The problem is in this line:
target_link_libraries(${PROJECT_NAME} glfw)
when doing this, cmake need x11_platform.h, that does not exist on windows. Does someone know how to skip this file or link another way?
Thank you.

Why does Clion not detect standard library headers when using Cmake?

I have a project in Clion using CMake and C++14. The project compiles but all standard library includes are marked as:
"Cannot find string", "Cannot find stdexcept", etc.
Additionally the symbols from the dll I included are not being detected. So they are all marked as:
"Cannot resolve ..."
I've included the header and cmakelist.txt. This is only happening in this project and I have almost identical cmakelist.txt files for all my projects. I have tried restarting CLion's cache. I also tried moving all the files to a new project which worked momentarily but with an hour CLion was flagging these lines again.
cmakelists.txt
cmake_minimum_required(VERSION 3.6)
project(BCI)
set(CMAKE_CXX_STANDARD 14)
#create dlls and executables in the root directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
include_directories(
${CMAKE_SOURCE_DIR}
)
set(SOURCE_FILES
NeuralInterface.hpp
)
add_library(BCI SHARED ${SOURCE_FILES})
set_target_properties(BCI PROPERTIES LINKER_LANGUAGE CXX)
NeuralInterface.hpp
#ifndef NEURALINTERFACE_HPP
#define NEURALINTERFACE_HPP
//c++ includes
#include <stdexcept> //these are the includes which cannnot be resolved
#include <string>
//project includes
#include "okFrontPanelDLL.h"
extern std::string IntanAcquire; //this says cannot resolve container std
...
#endif
What else can I do to CMake so it finds these headers?