Why add_library() creates a codeblocks project instead of a .a file? - c++

I'm trying to build a static library via CMake. I have this CMakeList.txt:
cmake_minimum_required(VERSION 3.12)
project(Test VERSION 1.0.0)
add_executable(Test main.cpp library.cpp)
add_library(MyLib STATIC library.cpp)
where library.cpp contains one function.
When I hit the build button, I find a Test.cbp file in one of build folders. Why isn't it a .a library? I'm using MacOS.

Related

Deplying a C++ application on Linux- linking everything statically to simplify deployment?

I am building a C++ project from Github and want to deploy the code to a remote Linux machine. This is all new to me.
The project has a main.cpp, which includes the various headers/sources like a library.
The CMake outputs an executable (to represent main.cpp) AND a separate static library. The project also uses OpenSSL, which I have linked statically.
I presume the OpenSSL functions are included within the static library? So when I deploy, I don't need to copy-over or install any OpenSSL on the remote machine?
Is it possible to modify the CMake so the application and the library are merged in to one file?
I am trying to make deployment as simple as copying over a single file, if this is possible.
Any additional advice/references are most-welcome.
UPDATE the CMake script:
cmake_minimum_required(VERSION 3.20)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
project(helloworld C CXX)
set (CMAKE_CXX_STANDARD 20)
set (CMAKE_BUILD_TYPE Release)
set (BUILD_MAIN TRUE)
set (BUILD_SHARED_LIBS FALSE)
set (OPENSSL_USE_STATIC_LIBS TRUE)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set( HELLOWORLD_HEADERS helloworld/File1.h helloworld/File2.h )
set( HELLOWORLD_SOURCES helloworld/File1.cpp helloworld/File2.cpp )
# Static library
add_library( helloworld ${HELLOWORLD_SOURCES} ${HELLOWORLD_HEADERS} )
# Rapidjson
include_directories(/tmp/rapidjson/include/)
# OpenSSL
if (NOT OPENSSL_FOUND)
find_package(OpenSSL REQUIRED)
endif()
add_definitions(${OPENSSL_DEFINITIONS})
target_include_directories(helloworld PUBLIC $<BUILD_INTERFACE:${OPENSSL_INCLUDE_DIR}>)
target_link_libraries(helloworld PRIVATE ${OPENSSL_LIBRARIES})
set( HELLOWORLD_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
include(GNUInstallDirs)
target_include_directories(helloworld PUBLIC
$<BUILD_INTERFACE:${HELLOWORLD_INCLUDE_DIRS}/>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/helloworld>
)
set_target_properties(helloworld PROPERTIES PUBLIC_HEADER "${HELLOWORLD_HEADERS}")
add_library(helloworld::helloworld ALIAS helloworld)
option(HELLOWORLD_INSTALL "Install HelloWorld" TRUE)
if (HELLOWORLD_INSTALL)
install(TARGETS helloworld
EXPORT helloworld
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/helloworld/
)
configure_file("${CMAKE_CURRENT_LIST_DIR}/helloworld-config.cmake.in" "${CMAKE_BINARY_DIR}/helloworld-config.cmake" #ONLY)
install(FILES "${CMAKE_BINARY_DIR}/helloworld-config.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/helloworld")
install(EXPORT helloworld
FILE helloworld-targets.cmake
NAMESPACE helloworld::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/helloworld
)
endif()
if (BUILD_MAIN)
add_executable(main main.cpp)
target_link_libraries(main helloworld)
endif()
ITNOA
I it is very helpful to make URL of your GitHub's project, but I write some public notes about that
In generally in CMake for static linking your library to your executable, you can write simple like below (from official CMake example)
add_library(archive archive.cpp zip.cpp lzma.cpp)
add_executable(zipapp zipapp.cpp)
target_link_libraries(zipapp archive)
In above example your executable file is just work without needing .a library file and you can simple copy single file.
if you want to make all of thing static, you make sure all dependencies make static link to your project, like CMake: how to produce binaries "as static as possible"
if you want to prevent library creation, Probably in your CMake file, you can find add_library command, and add_executable command. you can remove add_library command and add all sources to add_executable command.
for example add_executable(a.out main.cpp lib.cpp)

CLion configurate and test library project

Let's say I wanted to develop a simple library with the following structure:
My CMakeLists.txt then looks like this:
cmake_minimum_required(VERSION 3.17)
set(CMAKE_CXX_STANDARD 14)
set(INC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/")
set(SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/")
file(GLOB INCLUDES "${INC_DIR}/httplib/*.hpp")
file(GLOB SOURCES "${SRC_DIR}/*.cpp")
project(httplib)
add_library(httplib STATIC ${INCLUDES} ${SOURCES})
include_directories(${INC_DIR})
This works fine but what is the usual way to configure CLion projects and CMake in order to test a library effectively ?

How to "Link All" dynamic and/or static libraries, using a folder path and cmake?

In my test project I have a folder structure of the following
-Root/
-Lib_so/ //folder where it contains all of the .so file
-Lib_a/ //folder where it contains all of the .a file
-Lib_dll/ //folder where it contains all of the dll file
-Includes/ //folder where it contains all of the header files
-main.cpp
I want to write a CMakeLists.txt that generates a single executable that:
automatically link ALL of the .so , .a, and/or dll files just by the folder path shown above.
link installed binaries (such as the GLFW installed by brew on mac)
I have tried the following
cmake_minimum_required(VERSION 3.0)
project(FirstOpenGL)
set(SOURCE main.cpp)
add_executable(myapp ${SOURCE})
#Below Im trying to link ALL of the libs under the "project's local path"
include_directories(${CMAKE_SOURCE_DIR}/Includes)
link_directories(LinkPathSo ${CMAKE_SOURCE_DIR}/Lib_so)
link_directories(LinkPathA ${CMAKE_SOURCE_DIR}/Lib_a)
link_directories(LinkPathDll ${CMAKE_SOURCE_DIR}/Lib_dll)
target_link_libraries(myapp LinkPathSo)
target_link_libraries(myapp LinkPathA)
target_link_libraries(myapp LinkPathDll)
# Below: Im trying to link the installed binaries on mac
find_package(glfw3 3.2 REQUIRED)
find_package(OpenGL REQUIRED)
target_include_directories(myapp ${OPENGL_INCLUDE_DIR})
target_link_libraries(myapp ${OPENGL_gl_LIBRARY})
target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
Thank you all in advance

Using shared library created in a different directory

I've created a shared library with library.h and library.cpp. Then wrote a CMakeLists.txt file to build it as a shared library.
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(test_pro)
set(CMAKE_CXX_STANDARD 11)
add_library(test_pro SHARED library.cpp library.h)
after building the library, I was able to get a .so file as /home/user/projects/test_lib/bin/libtest_pro.so
Then I tried linking the created library to another project in /home/user/projects/testproject
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(testproject)
set(CMAKE_CXX_STANDARD 11)
link_directories(
/home/user/projects/test_lib/bin
)
add_executable(testproject main.cpp)
target_link_libraries (testproject test_pro)
It successfully builds the testproject (ldd command shows it has linked correctly), but I'm unable to use the library I've created in it.
In the main.cpp I've tried,
#include "library.h"
#include "test_pro"
#include <test_pro>
#include <test_pro/library.h>
But all the above gave build failures (fatal error: xxx: No such file or directory). How do I use this created library?
Just like you set link_directories() you have to specify include_directories(). And it is recommended not to use link_directories() at all, instead pass absolute path to the library into target_link_libraries().

Include Eigen library for Xcode project via CMake/CMakeLists.txt

I've got the following CMakeLists.txt (in my "project" folder) file for my project.
# define new project
PROJECT(SETUPMARKERTEST)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0 FATAL_ERROR)
if(UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif(UNIX)
# Set static build for GLFW
SET(BUILD_SHED_LIBS OFF)
ADD_SUBDIRECTORY(ext/glfw-3.1.1)
# Set shared lib build for the rest
SET(BUILD_SHARED_LIBS ON)
# Find dependencies
SET(EIGEN_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/ext/Eigen-3.1.2")
FIND_PACKAGE(OpenCV REQUIRED)
# Set header and source files
SET(MAR_Test_SOURCES
src/main.cpp
src/MarkerTracker.h src/MarkerTracker.cpp
src/PoseEstimation.h src/PoseEstimation.cpp
)
# define executable
ADD_EXECUTABLE(${PROJECT_NAME} ${MAR_Test_SOURCES})
# define additional include directories and linking targets
INCLUDE_DIRECTORIES("ext/glfw-3.1.1/include" ${EIGEN_INCLUDE_DIR} ${OpenCV_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS} glfw ${OPENGL_glu_LIBRARY} ${GLFW_LIBRARIES})
And my Eigen folder is in "project/ext/Eigen/3.1.2/Eigen/".
Somehow when I created my project for Xcode (in "project/buildXcode/" with Cmake .. -G "Xcode") and run it, Xcode throws me the error:
So I guess there is some error in my CMakeLists.txt, unfortunately I received that file and I'm new to CMake and thus didn't write it on my own nor am I very skilled with CMake.
Do you know what causes the error and can you fix the CMakeLists.txt that my project runs with the Eigen library?
Unfortunately it looks like windows is having no problem with this, whereas mac is bleating.
You just have to use
#include <Eigen/Dense>
instead of
#include <Eigen\Dense>
...pretty stupid error.