CMake linking error (undefined reference to function) - c++

I'm working on C/C++ cross platform application. I'm using CMake for build process.
The project structure below is simplified, narrowing to the issue.
├── CMakeLists.txt
├── Common_libs
│ ├── CMakeLists.txt
│ └── File_Process_... (.cc/.h, 4 each)
└── MAIN
├── CMakeLists.txt
└── (Other subdirs and sources/headers)
./CMakeLists.txt:(Common_libs)
# CMakeLists.txt : CMake project, include source and define
# project specific logic here.
#
set(PKG_NAME File_Process)
add_library(${PKG_NAME} STATIC
include/File_Process_Interface.h
include/File_Process_Types.h
include/FP_Directory.h
include/FP_File.h
include/FP_FileLP.h
include/FP_Includes.h
include/Filestruct.h
../../MAIN/error.h
source/File_Process_Factory.cpp
source/FP_Directory.cpp
source/FP_File.cpp
source/FP_FileLP.cpp)
target_include_directories(${PKG_NAME} PUBLIC include)
target_include_directories(${PKG_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/Common/Resources/3RD_PARTYLibrary/include)
if (WIN32)
target_include_directories(${PKG_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/Common/Resources/Windows/Includes)
install(TARGETS ${PKG_NAME} ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/Common_libs/dist/${CMAKE_BUILD_TYPE}/Win/)
else()
SET(CMAKE_CXX_FLAGS "-std=c++11")
install(TARGETS ${PKG_NAME} ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/Common_libs/dist/${CMAKE_BUILD_TYPE}/Linux/)
endif(WIN32)
target_include_directories(${PKG_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
File_Process_Interface.h
namespace AppExecutable{
namespace Common {
class File_Process_Factory {
public:
enum File_ProcessObjectType {
FP_File, FP_Directory, FP_FileLP, Automatic_Detection
};
static IFile_Process* Create(File_ProcessObjectType type = FP_File, std::string source = "");
};
}
}
File_Process_Factory.cpp
namespace AppExecutable{
namespace Common {
IFile_Process* File_Process_Factory::Create(File_ProcessObjectType type, std::string source) {
switch (type) {
case File_Process_Factory::Automatic_Detection:
struct stat st;
if (stat(source.c_str(), &st) == -1) {
return NULL;
}
else {
if (S_ISDIR(st.st_mode)) {
return (IFile_Process*) (new Common::FP_Directory());
}
else {
if (source.rfind(".xyz") == (source.length() - 4)) {
return (IFile_Process*) (new Common::FP_FileLP());
}
else {
return (IFile_Process*) (new Common::FP_File());
}
}
}
//return (IFile_Process*)new Common::Automatic_Detection();
break;
case File_Process_Factory::FP_File:
return (IFile_Process*) (new Common::FP_File());
break;
case File_Process_Factory::FP_Directory:
return (IFile_Process*) (new Common::FP_Directory());
break;
case File_Process_Factory::FP_FileList:
return (IFile_Process*) (new Common::FP_FileLP());
break;
default:
throw ("Unknown File_ProcessObjectType");
}
}
./CMakeLists.txt:(MAIN)
cmake_minimum_required (VERSION 3.8)
project(AppExecutable C CXX)
cmake_policy(SET CMP0015 NEW)
if (WIN32)
include_directories(MAIN
MAIN/shared)
link_directories(../Common_libs/dist/${CMAKE_BUILD_TYPE}/Win/)
else()
include_directories(MAIN
MAIN/shared)
endif(WIN32)
file(GLOB SOURCES
*.cpp
shared/*.cpp
shared/*.c)
# Add source to this project's executable.
if (WIN32)
add_executable (AppExecutable ${SOURCES})
install(TARGETS AppExecutable DESTINATION ${CMAKE_SOURCE_DIR}/Application/Windows/)
target_link_libraries(AppExecutable File_Process)
else()
add_executable (AppExecutable ${SOURCES})
install(TARGETS AppExecutable DESTINATION ${CMAKE_SOURCE_DIR}/Application/Linux/)
target_link_libraries(AppExecutable File_Process)
endif(WIN32)
SET_TARGET_PROPERTIES(AppExecutable PROPERTIES DEBUG_POSTFIX "_debug")
Finally, when I do make, the following error is generated:
[ 33%] Built target Common_libs
[ 38%] Linking CXX executable AppExecutable
CMakeFiles/AppExecutable.dir/MAIN/FileEntry.cpp.o: In function `AppExecutable::Common::FileEntry::FileSimulation(int, char**)':
FileEntry.cpp:(.text+0xaa9): undefined reference to `AppExecutable::Common::File_Process_Factory::Create(AppExecutable::Common::File_Process_Factory::File_ProcessObjectType, std::string)'
collect2: error: ld returned 1 exit status
make[2]: *** [AppExecutable/AppExecutable] Error 1
make[1]: *** [AppExecutable/CMakeFiles/AppExecutable.dir/all] Error 2
make: *** [all] Error 2
link.txt
/opt/gcc54/bin/g++ -std=c++11 -O3 -DNDEBUG -static-libgcc -static-libstdc++ CMakeFiles/AppExecutable.dir/Output_App.cpp.o CMakeFiles/AppExecutable.dir/FileEntry.cpp.o CMakeFiles/AppExecutable.dir/AppExecutable.cpp.o CMakeFiles/AppExecutable.dir/ABCBaseClass.cpp.o CMakeFiles/AppExecutable.dir/ABCControl.cpp.o CMakeFiles/AppExecutable.dir/shared/CsvReader.c.o CMakeFiles/AppExecutable.dir/shared/OutputInterface.cpp.o CMakeFiles/AppExecutable.dir/shared/DataBlock.cpp.o CMakeFiles/AppExecutable.dir/shared/lElement.cpp.o CMakeFiles/AppExecutable.dir/shared/lParser.cpp.o CMakeFiles/AppExecutable.dir/shared/lParserCApi.cpp.o CMakeFiles/AppExecutable.dir/shared/ssupport.cpp.o CMakeFiles/AppExecutable.dir/shared/lVersionParser.c.o -o AppExecutable ../Common_libs/libFile_Process.a
I'm able to generate executable in Windows, I'm having issue on linux.
I've been trying to fix this for some time. Why it is showing errors if it has already been built before the linkage?

Related

C++: How to properly link compiled object using CMake in VSCode

OS
Windows 10
CMake: 3.16.3
Editor
VSCode: 1.48.1
Extensions
CMake Tools: 1.4.1
C/C++ 0.30.0-insiders3
Kit
Visual Studio Community 2019 Release - amd64
Project Repo
https://gitlab.com/NumeralRocket/kepler Removed, insufficient for minimal reproducible example
Tutorial
Introduction to Google Test and CMake
https://www.youtube.com/watch?v=Lp1ifh9TuFI
I'm attempting to build unit tests for one of my personal projects using CMake, and while I wholly admit I am quite new to CMake and a novice at C++, I am stumped on how to resolve this problem. When I go to build my project I get the following Linker error:
[main] Building folder: kepler
[build] Starting build
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build n:/Unreal_Engine/Magellan/kepler/build-vscode --config Debug --target ALL_BUILD -- /maxcpucount:14
[build] Microsoft (R) Build Engine version 16.6.0+5ff7b0c9e for .NET Framework
[build] Copyright (C) Microsoft Corporation. All rights reserved.
[build]
[build] gmock.vcxproj -> N:\Unreal_Engine\Magellan\kepler\build-vscode\lib\Debug\gmockd.lib
[build] gmock_main.vcxproj -> N:\Unreal_Engine\Magellan\kepler\build-vscode\lib\Debug\gmock_maind.lib
[build] kepler.vcxproj -> N:\Unreal_Engine\Magellan\kepler\build-vscode\Debug\kepler.lib
[build] gtest.vcxproj -> N:\Unreal_Engine\Magellan\kepler\build-vscode\lib\Debug\gtestd.lib
[build] gtest_main.vcxproj -> N:\Unreal_Engine\Magellan\kepler\build-vscode\lib\Debug\gtest_maind.lib
[build] LINK : fatal error LNK1104: cannot open file 'Quaternion.lib' [N:\Unreal_Engine\Magellan\kepler\build-vscode\test\QuaternionTests.vcxproj]
[cmakefileapi-parser] Code model version (2.1) of cmake-file-api is unexpected. Expecting (2.0). IntelliSense configuration may be incorrect.
[cmakefileapi-parser] Code model version (2.1) of cmake-file-api is unexpected. Expecting (2.0). IntelliSense configuration may be incorrect.
[build] Build finished with exit code 1
For context, the project is structured as follows:
${ProjectRoot}
├── CMakeLists.txt
├── Quaternion.cpp
├── Quaternion.hpp
├── googletest
└── test
├── CMakeLists.txt
└── QuaternionTest.cpp
${ProjectRoot}/CMakeLists.txt
cmake_minimum_required(VERSION 3.16) # version can be different
set(CMAKE_VERBOSE_MAKEFILE ON)
set(This kepler)
get_filename_component(CODE_ROOT ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
project(${This}) #name of your project
project(${This} C CXX)
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
enable_testing()
add_subdirectory(googletest)
add_subdirectory(test)
set(Headers
Quaternion.hpp
)
set(Sources
Quaternion.cpp
)
add_library(${This} STATIC ${Sources} ${Headers})
${ProjectRoot}/Quaternion.cpp
#include <iostream>
#include "Quaternion.hpp"
// Default Constructor
Quaternion::Quaternion() {}
// Specified Value Constructor
Quaternion::Quaternion(double qs, double qi, double qj, double qk) : q0(qs), q1(qi), q2(qj), q3(qk) {}
Quaternion operator + (Quaternion const &quatA, Quaternion const &quatB) // 1) § 5.3
{
Quaternion quatC;
quatC.q0 = quatA.q0 + quatB.q0;
quatC.q1 = quatA.q1 + quatB.q1;
quatC.q2 = quatA.q2 + quatB.q2;
quatC.q3 = quatA.q3 + quatB.q3;
return quatC;
}
Quaternion operator - (Quaternion const &quatA, Quaternion const &quatB) // 1) § 5.3
{
Quaternion quatC;
quatC.q0 = quatA.q0 - quatB.q0;
quatC.q1 = quatA.q1 - quatB.q1;
quatC.q2 = quatA.q2 - quatB.q2;
quatC.q3 = quatA.q3 - quatB.q3;
return quatC;
}
void QuaternionLog(Quaternion quat2log)
{
std::cout << "q0: " << quat2log.q0 << std::endl;
std::cout << "q1: " << quat2log.q1 << std::endl;
std::cout << "q2: " << quat2log.q2 << std::endl;
std::cout << "q3: " << quat2log.q3 << std::endl;
}
int main()
{
Quaternion quat1;
Quaternion quat2(1, 2, 3, 4);
Quaternion quat3 = quat1 + quat2;
Quaternion quat4 = quat1 - quat2;
QuaternionLog(quat1);
QuaternionLog(quat2);
QuaternionLog(quat3);
QuaternionLog(quat4);
}
${ProjectRoot}/Quaternion.hpp
#ifndef QUATERNION_H
#define QUATERNION_H
class Quaternion
{
public:
double q0{ 1.0 };
double q1{ 0.0 };
double q2{ 0.0 };
double q3{ 0.0 };
Quaternion();
Quaternion(double qs, double qi, double qj, double qk);
friend Quaternion operator + (Quaternion const &quatA, Quaternion const &quatB);
friend Quaternion operator - (Quaternion const &quatA, Quaternion const &quatB);
};
#endif /* QUATERNION_H */
${ProjectRoot}/test/CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
set(This QuaternionTests)
set(Sources
QuaternionTest.cpp
)
add_executable(${This} ${Sources})
target_link_libraries(${This} PUBLIC
gtest_main
Quaternion
)
add_test(
NAME ${This}
COMMAND ${This}
)
${ProjectRoot}/test/QuaternionTest.cpp
#include <gtest/gtest.h>
#include "../Quaternion.hpp"
TEST(Quaternion, QuaternionConstructors)
{
Quaternion test_quat_1;
ASSERT_EQ(test_quat_1.q0, 1);
ASSERT_EQ(test_quat_1.q1, 0);
ASSERT_EQ(test_quat_1.q2, 0);
ASSERT_EQ(test_quat_1.q3, 0);
ASSERT_EQ(1,1);
};
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
};
How can I:
Ensure and Inspect that objects are being built appropriately?
Properly instruct CMake such that the linker can find my Quaternion (source code) object?
Any insight would be appreciated.
My mistake was in adding my library incorrectly:
${ProjectRoot}/CMakeLists.txt
cmake_minimum_required(VERSION 3.16) # version can be different
set(CMAKE_VERBOSE_MAKEFILE ON)
set(This kepler)
get_filename_component(CODE_ROOT ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
project(${This}) #name of your project
project(${This} C CXX)
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
enable_testing()
add_subdirectory(googletest)
add_subdirectory(test)
set(Headers
Quaternion.hpp
)
set(Sources
Quaternion.cpp
)
add_library(${This} STATIC ${Sources} ${Headers})
I was adding a library named ${THIS} which was "kepler" instead of the expected "Quaternion", so:
add_library(Quaternion STATIC ${Sources} ${Headers})
correctly tells the linker what/where to expect my library
AND
Leaving a main function in Quaternion.cpp, which was removed
Solution Source: vector-of-bool

How to install IMageMagick and ImageWand on Mac OS? [duplicate]

I'm programming in C. I want use ImageMagick library but some fuction can't be resolved.
This is my cMakeList.txt file:
cmake_minimum_required(VERSION 3.3)
project(WebServer)
set(CMAKE_C_COMPILER "/usr/bin/gcc")
set(SOURCE_FILES io.c server.c lock_fcntl.c sig_handler.c thread_job.c msg_parser.c)
set(LIB http-parser-master/http_parser.c )
set(CMAKE_USE_PTHREADS_INIT true)
set(CMAKE_USE_PTHREADS_INIT ON)
find_package(Threads REQUIRED)
find_package(ImageMagick COMPONENTS ImageWand)
include_directories(header)
include_directories(http-parser-master)
#include_directories(/usr/local/include/ImageMagick-7/MagickWand)
include_directories(${ImageMagick_INCLUDE_DIRS})
add_executable(server ${SOURCE_FILES} ${LIB})
add_executable(client client.c io.c)
add_executable(main main.c io.c)
target_link_libraries(main ${ImageMagick_LIBRARIES})
target_link_libraries(server Threads::Threads)
and this is the source main.c:
#include <ImageMagick-7/MagickWand/MagickWand.h>
#include "basic.h"
void convert_image(char *path, float quality_factor, char *out) {
int width, height;
MagickWand *n_wand = NULL;
MagickWandGenesis();
m_wand = (struct MagickWand *) NewMagickWand();
MagickReadImage(m_wand,"logo:");
width = MagickGetImageWidth(m_wand);
height = MagickGetImageHeight(m_wand);
if((width /= 2) < 1)width = 1;
if((height /= 2) < 1)height = 1;
MagickResizeImage(m_wand,width,height,LanczosFilter,1);
MagickSetImageCompressionQuality(m_wand,95);
MagickWriteImage(m_wand,"logo_resize.jpg");
if(m_wand)m_wand = (struct MagickWand *) DestroyMagickWand(m_wand);
MagickWandTerminus();
}
Only MagickWandGenesis() and MagickWandTerminus() are resolved.
The installation of the library ends correctly. How to solve?
edit:
Running I get the error:
/usr/local/include/ImageMagick-7/MagickWand/MagickWand.h:29:40: fatal error: MagickCore/magick-config.h: File o directory non esistente
# include "MagickCore/magick-config.h"
^
compilation terminated.
make[3]: *** [CMakeFiles/main.dir/main.c.o] Errore 1
make[2]: *** [CMakeFiles/main.dir/all] Errore 2
make[1]: *** [CMakeFiles/main.dir/rule] Errore 2
make: *** [main] Errore 2
I tried the solution shown here but does not work:
ImageMagick No such file or directory
The library structure is that:
ImageMagick-7
├── MagickCore
│   ├── magick-config.h
|
└── MagickWand
├── MagickWand.h
MagickWand.h includes some header in MagickCore.
I fix replacing include_directories(${ImageMagick_INCLUDE_DIRS})
with include_directories(/usr/local/include/ImageMagick-7).
I don't know why but if i print ${ImageMagick_INCLUDE_DIRS} this is not set.

Cannot Open .png file with CImg on CLion (macOS)

I've tried including libpng16/png.h and #define cimg_use_png, but none of them solved the error. Also, I have main.cpp, lenna.jpg and CImg.h in the same directory.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.6)
project(HelloWorld)
set(CMAKE_CXX_STANDARD 17)
set(SOURCE_FILES main.cpp)
add_executable(HelloWorld ${SOURCE_FILES})
set(YOU_NEED_X11 1)
set(YOU_NEED_PNG 1)
if (${YOU_NEED_PNG} EQUAL 1)
message(STATUS "Looking for libpng...")
find_package(PNG REQUIRED)
include_directories(${PNG_INCLUDE_DIR})
target_link_libraries (HelloWorld ${PNG_LIBRARY})
target_compile_definitions(HelloWorld PRIVATE cimg_use_png=1)
endif()
if (${YOU_NEED_X11} EQUAL 1)
message(STATUS "Looking for X11...")
find_package(X11 REQUIRED)
include_directories(${X11_INCLUDE_DIR})
target_link_libraries(HelloWorld ${X11_LIBRARIES})
else()
target_compile_definitions(HelloWorld PRIVATE cimg_display=0)
endif()
main.cpp:
#include <iostream>
#include "CImg.h"
using namespace cimg_library;
int main() {
CImg<unsigned char> img("lenna.png");
int h = img.height();
int w = img.width();
int s = img.spectrum();
std::cout << "h: " << h << " w: " << w << " s: " << s << std::endl;
return 0;
}
The error:
[CImg] *** CImgIOException *** [instance(0,0,0,0,0x0,non-shared)] CImg<unsigned char>::load(): Failed to open file 'lenna.png'.
libc++abi.dylib: terminating with uncaught exception of type cimg_library::CImgIOException: [instance(0,0,0,0,0x0,non-shared)] CImg<unsigned char>::load(): Failed to open file 'lenna.png'.
Process finished with exit code 6
It looks like lenna.png is not being found. Relative paths are relative to the directory containing the executable. That means that if the executable is at cmake-build-debug/HelloWorld and you try to open lenna.png, the file at cmake-build-debug/lenna.png is opened. This means that you should either manually copy lenna.png into cmake-build-debug (I don't recommend this) or ask CMake to do it for you.
Add this to your CMakeLists.txt file.
add_custom_command(
TARGET HelloWorld POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_SOURCE_DIR}/lenna.png
${CMAKE_BINARY_DIR}/lenna.png
)
This will cause lenna.png to be copied into the same directory as your executable every time the executable is compiled.

c++ Linker error with static library

I am trying to include a static library that I have created with a static method but getting the following error in runtime when trying to invoke the method:
[ INFO] [1528271039.635221775]: Initializing nodelet with 4 worker threads.
/opt/ros/kinetic/lib/nodelet/nodelet: symbol lookup error:/catkin_ws/devel/lib//libmission_manager_nodelet.so: undefined symbol: _ZN14my_commons10ConsoleLog6ROSLogEiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_
the static library has 2 files:
ConsoleLog.h:
#ifndef CONSOLE_LOG_H
#define CONSOLE_LOG_H
#include "ros/ros.h"
namespace my_commons
{
class ConsoleLog
{
public:
static void ROSLog(int type, std::string message,std::string taskName);
static void STDLog(int logType, std::string msg,std::string taskName);
};
} // namespace my_commons
#endif //CONSOLE_LOG_H
and ConsoleLog.cpp:
#include "ConsoleLog.h"
namespace my_commons
{
void ConsoleLog::ROSLog(int type, std::string message, std::string task)
{
switch (type)
{
case (0):
ROS_DEBUG_STREAM("########## " << task << " DEBUG: " << message << " ##########");
break;
case (1):
ROS_INFO_STREAM("########## " << task << " " << message << " ##########");
break;
case (2):
ROS_WARN_STREAM("########## " << task << " WARNNING: " << message << " ##########");
break;
case (3):
ROS_ERROR_STREAM("########## " << task << " ERROR: " << message << " ##########");
break;
}
}
void ConsoleLog::STDLog(int logType, std::string msg, std::string task)
{
std::cout << msg << std::endl;
}
} // namespace my_commons
the CMakelist.txt:
cmake_minimum_required(VERSION 2.8.3)
project(my_commons)
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
find_package(catkin REQUIRED COMPONENTS
roscpp
)
catkin_package(CATKIN_DEPENDS
INCLUDE_DIRS include)
include_directories(
${catkin_INCLUDE_DIRS}
include/
)
###########
## Build ##
###########
add_library(my_commons
src/ConsoleLog.cpp
)
## Specify libraries to link a library or executable target against
set_target_properties(my_commons PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(my_commons
${catkin_LIBRARIES}
${roscpp_LIBRARIES}
)
#add_dependencies(name_of_package_nodelet)
install(DIRECTORY include/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
FILES_MATCHING PATTERN "*.h"
PATTERN ".svn" EXCLUDE)
# Install library
install(TARGETS my_commons
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
Edit:
Here is the clients CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.3)
project(my_mission_manager)
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
find_package(catkin REQUIRED COMPONENTS
roscpp
nodelet
std_msgs
my_commons
message_runtime
std_srvs
)
catkin_package(
CATKIN_DEPENDS
message_runtime
std_msgs
my_commons
)
include_directories(
${catkin_INCLUDE_DIRS}
include/
)
###########
## Build ##
###########
add_library(my_mission_manager_nodelet
src/my_mission_manager_nodelet.cpp
)
## Specify libraries to link a library or executable target against
target_link_libraries( my_mission_manager_nodelet
${catkin_LIBRARIES}
${roscpp_LIBRARIES}
)
#add_dependencies(my_mission_manager_nodelet)
# Install library
install(TARGETS my_mission_manager_nodelet
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
# Install header files
install(DIRECTORY src/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
)
# Install launch files
install(DIRECTORY launch/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
)
# Install xml files
install(FILES nodelet_plugins.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)
What am I missing here?
By the way, I am able to use data from header files in my_commons (enums), the problem occurs when trying to add a cpp file an invoke a static method in it.
Thank you for your help!
Please find below a working example of correct CMake project:
Directory structure:
ROOT
|
+--inc
| +--ConsoleLog.hpp
+--src
| +--ConsoleLog.cpp
| +--main.cpp
+CMakeLists.txt
Your source and header files remains unchanged (I only changed *.h to *.hpp --> after all you write in C++, not C).
main.cpp:
#include "ConsoleLog.hpp"
int main() {
my_commons::ConsoleLog log;
log.ROSLog(1, "xxx", "yyy");
return 0;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.11)
project(my_commons)
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
find_package(catkin REQUIRED COMPONENTS roscpp)
add_library(my_commons STATIC src/ConsoleLog.cpp)
target_include_directories(my_commons PUBLIC inc ${roscpp_INCLUDE_DIRS})
target_link_libraries(my_commons ${catkin_LIBRARIES} ${roscpp_LIBRARIES})
add_executable(MyExec src/main.cpp)
target_link_libraries(MyExec my_commons)
Result of the execution:
./MyExec
[ INFO] [1528280295.971205050]: ########## yyy xxx ##########
I use newer CMake version to be able to use target_include_directories, because I like this feature. I changed your compiler flags to include C++11 standard, because apparently you use it. I also removed INSTALL CMake rules, because they are irrelevant to the question. Let me know if this answer is OK for you.
=============== EDIT(to answer OP comment)==============
Well, I don't have any problems with embedding this lib in another project structure. The error you got means that your directory structure is incorrect (my_commons dir doesn't exist). Your project tree should look like this:
ROOT
|
+--MyCommonsLib (this is the root of your my_commons library)
|
+--src
| +--main.cpp
+CMakeLists.txt
And your project's CMakeLists.txt might look like this:
cmake_minimum_required(VERSION 2.8.11)
project(SomeSimpleProjectUsingMyCommonsLib)
add_subdirectory(MyCommonsLib)
add_executable(MyExec src/main.cpp)
target_link_libraries(MyExec my_commons)
Just remember to remove the add_executable instruction from your MyCommonLib/CMakeLists.txt. Also main.cpp should be like this:
#include "ConsoleLog.hpp"
int main() {
my_commons::ConsoleLog::ROSLog(1, "xxx", "yyy");
return 0;
}
Sorry, before I didn't notice that ROSLog is declared as static.

CLion: undefined "_get_driver_instance"

The IDE : CLion
System: OS X
Error message:
Scanning dependencies of target librarySystem
[ 66%] Building CXX object CMakeFiles/librarySystem.dir/sqlConnection.cpp.o
[ 66%] Building CXX object CMakeFiles/librarySystem.dir/main.cpp.o
[100%] Linking CXX executable librarySystem
Undefined symbols for architecture x86_64:
"_get_driver_instance", referenced from:
sqlConnection::sqlConnection() in sqlConnection.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [librarySystem] Error 1
make[1]: *** [CMakeFiles/librarySystem.dir/all] Error 2
make: *** [all] Error 2
I write a class named sqlConnection to connect mysql.
sqlConection.h
#include "sqlConnection.h"
sqlConnection::sqlConnection() {
driver = get_driver_instance();
con = driver->connect("567aaffa1a70e.sh.cdb.myqcloud.com:xxxx", "xxxx", "xxxx");
con->setSchema("librarySys");
stmt = con->createStatement();
}
bool sqlConnection::ifConnected() {
bool isConnected = false;
if(!con->isClosed()){
std::cout << "Succeed to connect mysql";
isConnected = true;
}else{
std::cout << "fail to connect mysql";
}
return isConnected;
}
sqlConnection::~sqlConnection() {
delete stmt;
delete con;
}
The test in the main.cpp
main.cpp
#include <iostream>
#include "sqlConnection.h"
using namespace std;
int main() {
sqlConnection *sqlC = new sqlConnection();
sqlC->ifConnected();
return 0;
}
cmakeList:
cmake_minimum_required(VERSION 3.3)
project(librarySystem)
INCLUDE_DIRECTORIES(sqlFiles/include)
INCLUDE_DIRECTORIES(sqlFiles/lib)
INCLUDE_DIRECTORIES(sqlFiles/include/cppconn)
INCLUDE_DIRECTORIES(/usr/local/lib/libmysqlcppconn.so)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++0x")
set(SOURCE_FILES main.cpp sqlConnection.cpp sqlConnection.h)
add_executable(librarySystem ${SOURCE_FILES})
I used mysql connector-cpp to connect mysql.But the problem came.Have tried the solution on web,but they did't work.
Struggled with the same error and I got a small example to work with this CMakeLists.txt content. Maybe it's helpful for you even if its not same versions.
cmake_minimum_required(VERSION 3.5)
project(TestCPP)
#For mysql connector include..
INCLUDE_DIRECTORIES(/mypath/mysql-connector-c++-1.1.7-osx10.10-x86-64bit/include/)
#For Boost..
INCLUDE_DIRECTORIES(/opt/local/include/)
#For imported linking..
add_library(libmysqlcppconn STATIC IMPORTED)
set_property(TARGET libmysqlcppconn PROPERTY IMPORTED_LOCATION /mypath/mysql-connector-c++-1.1.7-osx10.10-x86-64bit/lib/libmysqlcppconn-static.a)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(TestCPP ${SOURCE_FILES})
target_link_libraries (TestCPP libmysqlcppconn)