third party libs
-
I sucessfully compiled a third party lib on ubuntu using make. The example file "HelloWorld" ran fine. Now I try to link it into a simple qt 6 dialog after adding a single button. the cmake seems to stall because I start with SysManager myMgr; saying there is a fix. I click and Qt 6 Creator adds sFnd::SysManager myMgr; but it's still broken saying I am calling a private constructor of sFnd::SysManager? Is it possible that make and cmake are compiling the library differently? Any help will be greatly appreciated. (p.s. the libsFoundation20.so makefile dosen't seem to work with Qt6 cmake?)
-
@CharlesHuff, I think it would help if you show us the source code (CMakeLists.txt file, .cpp/.h file) that you are using.
Is it possible that make and cmake are compiling the library differently?
CMake is a metafile generator; you can generate a Makefile (to be processed by make) out of a CMakeLists.txt file. So in the sense you are comparing apples with oranges.
Anyhow, what can happen is that the compiler line that CMake ultimately generates, and that your custom Makefile (?) has, differ. So if you have the same .cpp file that is compiling in one setup, and not in another, you should start comparing the compiler call.
-
make:
Example Project Makefile
HelloWorld
Creates an executable in this directory called HelloWorld
EXEC_NAME := "HelloWorld"
INCLUDE_DIR := "../../inc/inc-pub"
LIBS := -lsFoundation20 -lpthread
CC := g++
OPTIMIZATION := -O3
DEBUG_OPTIMIZATION := -O0
CXXFLAGS := -I$(INCLUDE_DIR) $(OPTIMIZATION)
DEBUG_CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -pedantic -g3 $(DEBUG_OPTIMIZATION)Specify source files here
ALL_SRC_FILES := $(wildcard *.cpp)
ALL_OBJS := $(patsubst %.cpp,%.o,$(ALL_SRC_FILES))Default target
all: HelloWorld
Generic rule to compile a CPP file into an object
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) -o "$@" $<HelloWorld: $(ALL_OBJS)
ifneq ($(RPATH),)
$(CC) -L$(RPATH) -Wl,-rpath=$(RPATH) -o $(EXEC_NAME) $(ALL_OBJS) $(LIBS)
else
$(CC) -o $(EXEC_NAME) $(ALL_OBJS) $(LIBS)
endifRemove all object files
.PHONY: clean
clean:
-find . -type f -name "*.o" -deleteSayonara. Viciously destroys all build artifacts, including the executable.
.PHONY: real_clean
real_clean: clean
-rm $(EXEC_NAME) -
Alright, but what's the compiler line if you use CMake? It is usually printed along the compiler error...
-
CMAKE:
cmake_minimum_required(VERSION 3.5)project(DialogWidgets VERSION 0.1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)add_library(sFoundation20.so.1)
#add_library("-lsFoundation20 -lpthread")
#cmake_path("../../inc/inc-pub")
#CC = g++
#OPTIMIZATION = -O3
#DEBUG_OPTIMIZATION = -O0
#CXXFLAGS = -I$(INCLUDE_DIR) $(OPTIMIZATION)
#DEBUG_CXXFLAGS = $(CXXFLAGS) -Wall -Wextra -pedantic -g3 $(DEBUG_OPTIMIZATION)Specify source files here
#SOURCES += $(wildcard *.cpp)
#OBJECT_DEPENDS += $(patsubst %.cpp,%.o,$(ALL_SRC_FILES))Default target
#all: HelloWorld
Generic rule to compile a CPP file into an object
#%.o: %.cpp
$(CXX) -c $(CXXFLAGS) -o "$@" $<
#HelloWorld: $(ALL_OBJS)
ifneq ($(RPATH),)
$(CC) -L$(RPATH) -Wl,-rpath=$(RPATH) -o $(EXEC_NAME) $(ALL_OBJS) $(LIBS)
else
$(CC) -o $(EXEC_NAME) $(ALL_OBJS) $(LIBS)
endif
set(PROJECT_SOURCES
main.cpp
dialog.cpp
dialog.h
dialog.ui
HelloWorld.cpp
)if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(DialogWidgets
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)Define target properties for Android with Qt 6 as:
set_property(TARGET DialogWidgets APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/android)
For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
if(ANDROID)
add_library(DialogWidgets SHARED
${PROJECT_SOURCES}
)Define properties for Android with Qt 5 after find_package() calls as:
set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else() add_executable(DialogWidgets ${PROJECT_SOURCES} ) endif()
endif()
target_link_libraries(DialogWidgets PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(DialogWidgets PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(DialogWidgets)
endif()```
#include "dialog.h"
#include <QApplication>
#include <QProcess>
#include <QThread>
#include <QTime>
#include <QMessageBox>
#include <QDebug>
#include <stdio.h>
#include <ctime>
#include <string>
#include <iostream>
#include "../../inc/inc-pub/pubSysCls.h"#include <chrono>
//std::string CONFIG_FILES [] = { "/home/pi/Travis1.mtr" };
std::vectorstd::string comHubPorts;
size_t portCount;
QString myStr;
QString myStr2;
QString myStr3;
bool myEStop;
char alertList[256];
double timeout;
double speed;
double commPosn;/*bad code
class sFnd {
public:
myMgr;
}
*/
//sFnd::SysManager myMgr;
//SysManager myMgr;sFnd::IPort *iPort;
sFnd::INode *theNode;int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();size_t portCount = 1; std::vector<std::string> comHubPorts; //sFnd::SysManager myMgr; //SysManager* myMgr = SysManager::Instance(); return a.exec();
}
I get SysManager was not declaired in this scope when I use the line SysManager myMgr; and I get calling a private constructor when I use sFnd::SysManager myMgr; instead. if I remove both lines every thing compiles and runs.
-
@CharlesHuff Please format your code properly - it is almost impossible to read!
What is SysManager and how is it declared?
"I get calling a private constructor when I use sFnd::SysManager myMgr" - sounds like default constructor in SysManager is private - did you check that? -
sFnd::SysManager Class Reference
Detailed DescriptionThis class defines the manager object whose framework implements system level functions including:
Functions to open, close, and restart ports in the system
A thread safe system dwell
The system timestamp
Direct access to ports and nodes within the system
Only one instance of this object should be used in any application.Coding Example
// Create instance of sFoundation
SysManager myMgr;
// Define a port SC4-HUB attached to
myMgr.ComHubPort(0, 13);
// Tell system to open this one port
myMgr.PortsOpen(1);
// Access Node objects through the port
myMgr.Ports(0).Nodes(0); -
Indeed, please consider using ``` around code so that it is easier to parse.
add_library(sFoundation20.so.1)
This looks wrong. What add_library() does is letting you define how a library target is being compiled. That is, you use add_library to create an .so file, not, to make use of it in an executable.
Does
sFoundation20.so
have native CMake support, by e.g. providing aFindsFoundation20.cmake
file? Then you should be able to look it up withfind_package
, like you do e.g. for Qt, this also then usually takes care of setting include directories etc.If not, you can also 'manually' link the
sFoundation20.so
library with theDialogWidgets
target by using target_link_libraries(). Then you need to take care e.g. of include directories manually...target_include_directories(DialogWidgets ../../inc/inc-pub) target_link_libraries(DialogWidgets sFoundation20.so)
(provided that ../../inc/inc-pub is actually containing the headers defining the API for sFoundation20)
Hope that helps...
-
The instructions with the library specify "make" and don't mention cmake. A year or two ago I got this working on the Raspberry Pi (not supported) with Qt 4. I used SysManager myMgr; liberally knowing this was bad coding, but it was the only way I got it to work. Now I have Ubuntu on a machine and I am retired, so more time to play (and learn). I CAN compile the library with qmake and assume I can then link it with the same or similar statements that I used with Qt 4? I am not sure this would work. I wanted to try with CMake but have no understanding of how to translate the make flags and parameters into CMake equivalents. Thank you so very much for the tip on using target_link_libraries(). I can't wait to try it out... There are about 6 or 7 very small program examples that compile and run from the g++ terminal and my hope is to learn how to correctly use the library with Qt 6 CMake. Have a great day. I will try to mark this solved (I am sure your answer is correct) even if my understanding is flawed.... Charles
-
@kkoehne said in third party libs:
target_include_directories(DialogWidgets ../../inc/inc-pub)
target_link_libraries(DialogWidgets sFoundation20.so)I get two errors, both related to the so library:
/CMakeLists.txt:17: error: Cannot specify include directories for target "DialogWidgets" which is not built by this project.
/CMakeLists.txt:18: error: Cannot specify link libraries for target "DialogWidgets" which is not built by this project.Do I really have to compile the sFoundation20.so inside my own Project? It seems like this would be a big reason to not use Qt... anyway I didn't expect to get these results.
Charles -
@CharlesHuff
oops...I noticed another line with target_link_libraries and moved the above two lines to just below that! now it links just fine. I am finally on the path....
Charles