Error while linking libconfig with c++ using cmake? - c++

Here is the cmake file that i am using
cmake_minimum_required (VERSION 3.0)
project (midasd)
set (midas VERSION_MAJOR 0)
set (midas VERSION_MINOR 0)
set (midas VERSION_REVISION 1)
find_library(libconfig libconfig)
add_executable(midasd src/main.cpp)
target_link_libraries(midasd "${libconfig_LIBS}")
The problem i am facing is undefined reference for config_init. The main function is as follows
#include <libconfig.h>
int main(int argc, char *argv[])
{
midas::midasCtx *container = new midas::midasCtx(argc,argv);
config_t cfg;
config_init(&cfg);
return 0;
}
Where am i going wrong with CMAKE ?

Actually the libconfig is recognized as simply -lconfig not -llibconfigin linking argument. The CMakeLists.txt should contain
target_link_libraries(my_project config)
Source

This manual(https://hyperrealm.github.io/libconfig/libconfig_manual.html) says " To link with the library, specify ‘-lconfig++’ as an argument to the linker. "
So I fixed like following code and build was completed.
target_link_libraries(my_project config++)

Related

Cannot add library source to cmake project on QT

I need to resolve a simple issue with a test project. However despite my attempts to look at stack overflow I cannot resolve it. The toy project has one main CMakeLists and two sub-folders. One mathlib and one is a unittest.
CMakeLists.txt
├───QTMathLib
└───QTUnitTest
the sources:
testmathlib.cpp
#include "testmathlib.h"
#include <QDebug>
TestMathLib::TestMathLib()
{
qDebug() << __FILE__ <<" Created!";
}
int32_t TestMathLib::Add(int32_t a, int32_t b)
{
return a+b;
}
tst_testadd.cpp
void TestAdd::initTestCase()
{
TestMathLib testMathLib;
int32_t result = testMathLib.Add(10, 20);
qDebug() << "Result =" << result ;
QVERIFY(30 == result);
}
However I want the UnitTest project to include the mathlib sources as below:
Add library to Cmake project
I tried this:
set (sources2
../QTMathLib/testmathlib.cpp
)
add_executable(TestAdd
tst_testadd.cpp
)
add_library( mylib ${sources2} )
add_test(NAME TestAdd COMMAND TestAdd)
target_link_libraries(TestAdd PRIVATE Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Test
Qt${QT_VERSION_MAJOR}::Core
mylib)
But this always give me a building error since I cannot resolve QDebug.h header file. Notice that other includes may be added, so don't just patch for the QDebug.h, assume any QTCore header can be included in the future.
D:\gmmo\qt_qml\QTTest\QTMathLib\testmathlib.cpp:2: error: QDebug: No such file or directory
D:/gmmo/qt_qml/QTTest/QTMathLib/testmathlib.cpp:2:10: fatal error: QDebug: No such file or directory
2 | #include <QDebug>
| ^~~~~~~~
The fix should be on these files, not the source file itself.
└───QTUnitTest\CMakeLists.txt
├───QTMainApp\CMakeLists.txt
Any clues why it cannot file QT headers?
thank you #273K for the help, this worked:
target_link_libraries(mylib PRIVATE
Qt${QT_VERSION_MAJOR}::Core)
target_link_libraries(TestAdd PRIVATE
mylib
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Test)
Adding two target_link_libraries.

CMake not linking static libraries properly when using LLVM on Windows

I am using Windows 10 and CMake to build my project (using MinGW Makefiles as the generator), while choosing Clang/Clang++ (LLVM) as my compiler due to my Language Server Protocol also being for Clang.
However, when trying to link a static library I had created to my main executable, none of the definitions in the translation units were able to be resolved.
For a simple recreation:
File system
+ root/
+ main.cpp
+ foobar.cpp
+ foobar.hpp
+ CMakeLists.txt
// main.cpp
#include <iostream>
#include "foobar.hpp"
int main( int argc, char** argv ) {
foo();
std::cin.get();
return 0;
}
// foobar.cpp
#include "foobar.hpp"
void foo() {
std::cout << "bar" << std::endl;
}
// foobar.hpp
#pragma once
#ifndef FOOBAR_HEADER_H
#define FOOBAR_HEADER_H
#include <iostream>
void foo();
#endif
# CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(linker_fail
VERSION 1.0.0
LANGUAGES C CXX)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_library(foobar
foobar.cpp
foobar.hpp)
add_executable(${PROJECT_NAME}
main.cpp)
target_link_libraries(${PROJECT_NAME} PUBLIC
foobar)
Then for building:
root> cmake -S . -B bin -G "MinGW Makefiles"
root> cmake --build bin
lld-link: error: undefined symbol: void __cdecl foo(void)
Does anyone know how to fix this? Should I have passed some arguments to the compiler/linker? Or does Clang just not allow static linking?

"Undefined reference to " after linking with CMake

I want to build a simple application based on a .cpp and a .h file.
I couldn't make my project work so i started from a basic example but didn't succeed as i'm just starting creating project in Linux. From what i've seen, my CMakeLists should be like this :
My CMakeLists.txt :
cmake_minimum_required(VERSION 3.5)
set(CMAKE_CXX_STANDARD 11)
project(test C CXX)
add_executable(${PROJECT_NAME} main_new.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
My main_new.cpp :
#include <read.h>
int main(int argc, char* argv[])
{
int a, b, c, d, e = 0;
std::cout << "hello im example " << std::endl;
read_int(&a, &b, &c, &d, &e);*
return 0;
}
My read.h :
#ifdef __cplusplus
extern "C" {
#endif
int read_int(int *vectorA, int *vectorB, int *matrixA, int *matrixB, int *flags);
#ifdef __cplusplus
}
#endif
My .cpp and .h file are in the same folder. cmake . is giving me no error, but after using make i get
main_new.cpp:(.text+0x68) : undefined reference to « read_int »
I'm using the makefile created by the cmake command. Should i create a custom makefile ?
Edit : Added question :
I also have to implement .so files, but doing target_link_libraries(test ${CMAKE_SOURCE_DIR}/libA.so ${CMAKE_SOURCE_DIR}/libB.so) in my CMakeLists.txt file doesn't work. How can i link these libraries to my executable ?

Including C File/Linking with CMake isn't working with C++: cannot include function

This is my C++ code:
#include "stdlib.h"
#include "stdio.h"
#include <iostream>
int main(int argc, char *argv[] ) {
int width, height;
unsigned char *rgba;
FILE *fp = fopen("/home/pic.tif", "rb");
if(!fp)
std::cout<<"failed"<<std::endl;
rgba = floadtiff(fp, &width, &height);
fclose(fp);
if(rgba == 0)
printf("TIFF file unreadable\n");
}
I am using this library by #MalcolmMcLean, and that's what my loadtiff.c is.I have compiled it using gcc and am trying to link that library.
This is my CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.12.2)
project (test)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} cmake/)
add_executable(test tiffs.cpp)
target_link_libraries(test loadtiff)
and these are the errors I get when trying to make the program:
error: ‘floadtiff’ was not declared in this scope
Why can't I access this function, which is defined in loadtiff.c?
In tipps.cpp add:
extern "C" {
#include "loadtiff.h"
}
In CMakeLists.txt change to:
cmake_minimum_required(VERSION 2.8.12.2)
project(tiffs)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} cmake/)
add_library(loadtiff tiffloader/loadtiff.c)
target_include_directories(loadtiff PUBLIC tiffloader/loadtiff.h)
add_executable(tiffs tiffs.cpp)
target_link_libraries(tiffs loadtiff)
where "tiffloader/" is wherever you put the "loadtiff" files.
Do not name projects or targets after reserved words like "test", or you will get CMake warnings.
So you've got 2 problems.
1) your code is an abhorrent mixture of C and C++. For example, you're outputting text using C++
std::cout<<"failed"<<std::endl;
and C
printf("TIFF file unreadable\n");
Pick just one language and stick to it. Given it appears that floadtiff is expecting a FILE *, you'll probably be better off writing your code in C.
2) You're trying to use a library without telling the compiler anything about it. That's what header files are for. They tell the compiler you're using code from a different file and how the functions in that file are called. There should be a "loadtiff.h" file somewhere - you need to include that. That will contain definitions for the functions inside "loadtiff.c", such as floadtiff.
Without those definitions, your compiler has no idea if you're passing in the right number and/or type of parameters to those functions. It doesn't know what the return type of the function is or if it doesn't have one.
In C++ this information is especially important as you have function overloading, so it has to know exactly which function you're calling. In C, it's not quite so rigid and will make assumptions - which are often incorrect - about the function, but it will still warn you that it's done this.
If I use the following source
#include <cstdlib>
#include <cstdio>
#include <iostream>
extern "C" {
#include "loadtiff.h"
}
int main(int argc, char argv[] ) {
int width, height;
unsigned char* rgba;
FILE* fp = fopen("/home/user/pic.tif", "rb");
if(!fp)
std::cout << "failed" << std::endl;
rgba = floadtiff(fp, &width, &height);
fclose(fp);
if(rgba == 0)
printf("TIFF file unreadable\n");
return 0;
}
with the following CMakeLists.txt file under Visual Studio 14 and CMake 3.8.2
cmake_minimum_required(VERSION 2.8.12.2)
project (test)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} cmake/)
add_executable(test tiffs.cpp)
add_library(loadtiff STATIC loadtiff.c)
target_link_libraries(test loadtiff)
CMake generates a fully functional solution and Visual Studio is able to build it without errors.
Edit:
I assumed you have tiffs.cpp, loadtiff.c and loadtiff.h located in the same directory.

CMAKE LINKING ERROR with a user-defined shared library

I am a newcomer to the world of cmake. This question came up while I was experimenting with some basic cmake configurations in C++. To be precise, following is my directory structure :
/src----
|-> CMakeLists.txt
|-> main.cpp
|-> lib----
|-> libfsystem.so
|->filesystem----
|->CMakeLists.txt
|->listfiles.cpp
|->include-----
|->fsystem.h
Now, the /src/filesystem/CMakeLists.txt file is like this
cmake_minimum_required(VERSION 2.8)
project(fsystem)
set(CMAKE_BUILD_TYPE Release)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/build)
find_package(Boost REQUIRED system filesystem)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(fsystem SHARED listfiles.cpp)
While, the /src/CMakeLists.txt file is like this
cmake_minimum_required(VERSION 2.8)
project(vessel_detect)
add_subdirectory(filesystem)
add_executable(main main.cpp)
set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
find_library(libpath fsystem)
MESSAGE(${libpath})
target_link_libraries(main ${libpath})
The library libfsystem.so is successfully created.
The library libfsystem.so is also successfully found by /src/CMakeLists.txt
However when the linking of main.cpp is done, then it gives me several undefined reference errors which should not have happened as everything has already been defined. For greater completeness, following is the content of main.cpp file
Main.cpp
#include<iostream>
#include"filesystem/include/fsystem.h"
using namespace std;
int main(void)
{
string path ("~");
vector<string>* output;
output = listfiles(path);
return 0;
}
The contents of listfiles.cpp are
listfiles.cpp
#include"fsystem.h"
using namespace boost::filesystem;
vector<string>* listfiles(int argc, char* argv[])
{
if (argc<2)
{
std::cout<<"No file name provided"<<std::endl;
}
else
{
path p(argv[1]);
vector<string>* output;
if (exists(p))
{
if(is_directory(p))
{
std::cout<<"You specified a directory"<<std::endl;
std::cout<<"Its contents are as follows :-"<<std::endl;
typedef std::vector<path> vec;
vec v;
copy(directory_iterator(p),directory_iterator(),back_inserter(v));
sort(v.begin(),v.end());
for(vec::const_iterator it(v.begin());it!=v.end();++it)
output->push_back(it->filename().string());
// std::cout<<it->filename()<<std::endl;
}
else if (is_regular_file(p))
{
std::cout<<argv[1]<<" "<<file_size(p)<<std::endl;
}
else
{
std::cout<<"The file is neither a directory nor a regular file"<<std::endl;
}
}
else
{
std::cout<<"The speicified path does not exist"<<std::endl;
}
}
}
And finally, the fsystem.h contents are :
fsystem.h
#ifndef _fsystem_h
#define _fsystem_h
#include<iostream>
#include<string>
#include<vector>
#include"boost/filesystem.hpp"
using namespace std;
vector<string>* listfiles(string);
#endif
Could someone provide me a reason for the undefined reference errors I am getting during the linking of main.cpp ? I would also be grateful if you could provide me with a resolution of this issue.
Thanks
Your not linking boost. you need to add target_link_libraries(fsystem ${Boost_LIBRARIES}) to the end of /src/filesystem/CMakeLists.txt and include_directories(${Boost_INCLUDE_DIRS}) between the find_package and add_library.
cmake_minimum_required(VERSION 2.8)
project(fsystem)
set(CMAKE_BUILD_TYPE Release)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/build)
find_package(Boost REQUIRED system filesystem)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories(${Boost_INCLUDE_DIRS})
add_library(fsystem SHARED listfiles.cpp)
target_link_libraries(fsystem ${Boost_LIBRARIES})
(1) For TARGET_LINK_LIBRARIES you should put the name of the target, thus:
TARGET_LINK_LIBRARIES(main fsystem)
(2) You declare listfiles as vector<string>* listfiles(string) while you define it as vector<string>* listfiles(int,char**)
Additionally you need to link with Boost per the other reply.