i'm decided to build some calculator with CMake, but it failed for some reason, yet it looks correct. I got a set(CMAKE_AUTOMOC ON) rule and yet, what is vtable? I can't simply build it... There are all project files below
CMakeLists.txt
cmake_minimum_required(VERSION 3.1.0)
project(calculator)
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC_ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
include_directories("./include")
add_executable(${PROJECT_NAME} calculator.cpp main.cpp)
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Widgets)
calculator.hpp
#ifndef CALCULATOR_HPP
# define CALCULATOR_HPP
#include <QtWidgets/QWidget>
#include <QVector>
#include <QLCDNumber>
#include <QPushButton>
class Calculator : public QWidget {
Q_OBJECT
public:
Calculator(QWidget *pwgt = nullptr);
QPushButton *createButton(QString const &rhs);
void calculate();
private:
QLCDNumber *_plcd;
QString _strDisplay;
QVector<QString> _strVector;
public slots:
void buttonClicked();
};
#endif
calculator.cpp
#include <calculator.hpp>
#include <QGridLayout>
Calculator::Calculator(QWidget *pwgt) : QWidget(pwgt) {
QGridLayout *gridObj = new QGridLayout();
_plcd = new QLCDNumber(12);
_plcd->setMode(QLCDNumber::Dec);
_plcd->setSegmentStyle(QLCDNumber::Flat);
_plcd->setMinimumSize(150, 50);
//_wgtPtr = (!_pwgt) ? new QWidget() : pwgt;
QChar calcChars[4][4] = { {'7', '8', '9', '/'},
{'4', '5', '6', '*'},
{'1', '2', '3', '-'},
{'0', '.', '=', '+'}};
gridObj->addWidget(_plcd, 0, 0);
gridObj->addWidget(createButton("CE"), 1, 3);
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j)
gridObj->addWidget(createButton(calcChars[i][j]), i + 2, j);
}
setLayout(gridObj);
}
QPushButton *Calculator::createButton(QString const &rhs) {
QPushButton *calcButton = new QPushButton(rhs);
calcButton->setMinimumSize(40, 40);
connect(calcButton, SIGNAL(clicked()), SLOT(buttonClicked()));
return (new QPushButton(rhs));
}
void Calculator::buttonClicked() {
QString match = dynamic_cast<QPushButton *>(sender())->text();
QRegExp regMatch("[0-9]");
if (!match.compare("CE")) {
_strVector.clear();
_strDisplay.clear();
_plcd->display("0");
} else if (match.contains(regMatch)) {
_strDisplay.push_back(match);
_plcd->display(_strDisplay.toDouble());
} else if (!match.compare(".")) {
_strDisplay.push_back(match);
_plcd->display(_strDisplay.toDouble());
} else {
_strVector.push_back(_strDisplay);
if (_strVector.size() > 1) {
calculate();
_strVector.clear();
_strVector.push_back(_strDisplay);
if (match.compare("="))
_strVector.push_back(match);
} else {
_strVector.push_back(_strDisplay);
_strDisplay.clear();
_plcd->display("0");
}
}
}
void Calculator::calculate() {
double rValue = _strVector.back().toDouble();
_strVector.pop_back();
QString operCalc = _strVector.back();
_strVector.pop_back();
double lValue = _strVector.back().toDouble();
if (!operCalc.compare("+"))
rValue += lValue;
if (!operCalc.compare("-"))
rValue -= lValue;
if (!operCalc.compare("/"))
rValue /= lValue;
if (!operCalc.compare("*"))
rValue *= lValue;
_strDisplay.number(rValue);
_plcd->display(_strDisplay.toDouble());
}
and main.cpp
#include <calculator.hpp>
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
Calculator *obj = new Calculator;
obj->resize(230, 200);
obj->setWindowTitle("QtCalculator");
obj->show();
return (app.exec());
}
this is file hierarchy
|--> CMakeLists.txt
|
|--> calculator.cpp
|
|--> main.cpp
|
|--> include
|
|--> calculator.hpp
And this is a build output (in CLion IDE)
====================[ Build | all | Debug ]=====================================
/snap/clion/162/bin/cmake/linux/bin/cmake --build /home/lchantel/train_01Qt/cmake-build-debug --target all -- -j 3
[ 20%] Automatic MOC for target calculator
[ 20%] Built target calculator_autogen
Scanning dependencies of target calculator
[ 40%] Building CXX object CMakeFiles/calculator.dir/calculator_autogen/mocs_compilation.cpp.o
[ 60%] Building CXX object CMakeFiles/calculator.dir/calculator.cpp.o
[ 80%] Building CXX object CMakeFiles/calculator.dir/main.cpp.o
[100%] Linking CXX executable calculator
/usr/bin/ld: CMakeFiles/calculator.dir/calculator.cpp.o: in function `Calculator::Calculator(QWidget*)':
/home/lchantel/train_01Qt/calculator.cpp:4: undefined reference to `vtable for Calculator'
/usr/bin/ld: /home/lchantel/train_01Qt/calculator.cpp:4: undefined reference to `vtable for Calculator'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/calculator.dir/build.make:126: calculator] Error 1
make[1]: *** [CMakeFiles/Makefile2:84: CMakeFiles/calculator.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
Your CMake code needs some work:
Never use include_directories in CMake ever. Use target_include_directories instead.
Always use one of PRIVATE, PUBLIC or INTERFACE with target_link_libraries to avoid weird legacy behavior.
Defining targets in terms ${PROJECT_NAME} is weird, longer, and makes your code less readable for no benefit. There's no compelling reason to keep them coupled and the project name rarely changes.
Never set CMAKE_CXX_COMPILER in your CMakeLists.txt
Prefer compile features to setting CMAKE_CXX_STANDARD.
I seriously doubt you're using CMake 3.1.0. Never set a version lower than the one you're using / testing with.
You have a stray underscore in CMAKE_AUTOUIC_ON
Use this build instead:
cmake_minimum_required(VERSION 3.16)
project(calculator)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5 REQUIRED Core Widgets)
add_executable(calculator calculator.cpp main.cpp include/calculator.hpp)
target_link_libraries(calculator PRIVATE Qt5::Core Qt5::Widgets)
target_include_directories(calculator PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_compile_features(calculator PRIVATE cxx_std_11)
The reason you're seeing a vtable error is because moc doesn't see your include/calculator.hpp header because it isn't listed as one of the sources in add_executable.
Related
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
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?
I've been using PyQt for years now and had to recode a project in C++ using CLion. I have managed (after awhile) to get the code building on my MacBookPro, but when I move the project to Windows 10, all hell broke loose! I've reloaded mingw with the x86 version and gotten everything to work except MOC and AUTOUIC. The only lines I changed in the CMakeLists.txt file between Oses were the ones that pointed to the Qt install. As I said, I'm new to all this in C++ and may have some 'mistakes' in my makefile, but it works on OSX but not in Windows!
I am able to compile ui and resources files manually and get the build to compile, but I don't know how to resolve this issue.
Any help and guidance would be greatly appreciated!
====================[ Build | crapsStarter | Debug ]============================
C:\Users\a.fireheart.CLion2019.3\system\cygwin_cmake\bin\cmake.exe
--build /cygdrive/c/Users/a.fireheart/CLionProjects/crapsStarter/cmake-build-debug
--target crapsStarter -- -j 6 [ 14%] Automatic MOC for target crapsStarter
AutoMoc subprocess error
------------------------ The moc process failed to compile "/cygdrive/c/Users/a.fireheart/CLionProjects/crapsStarter/craps.h"
into
"/cygdrive/c/Users/a.fireheart/CLionProjects/crapsStarter/cmake-build-debug/crapsStarter_autogen/EWIEGA46WW/moc_craps.cpp".
Command
------- C:/Qt/5.14.1/winrt_x64_msvc2017/bin/moc.exe -I/cygdrive/c/Users/a.fireheart/CLionProjects/crapsStarter/cmake-build-debug
-I/cygdrive/c/Users/a.fireheart/CLionProjects/crapsStarter -I/cygdrive/c/Users/a.fireheart/CLionProjects/crapsStarter/cmake-build-debug/crapsStarter_autogen/include
-IC:/Qt/5.14.1/winrt_x64_msvc2017/include -IC:/Qt/5.14.1/winrt_x64_msvc2017/include/QtCore -IC:/Qt/5.14.1/winrt_x64_msvc2017/./mkspecs/winrt-x64-msvc2017 -IC:/Qt/5.14.1/winrt_x64_msvc2017/include/QtGui -IC:/Qt/5.14.1/winrt_x64_msvc2017/include/QtANGLE -IC:/Qt/5.14.1/winrt_x64_msvc2017/include/QtWidgets -I/usr/lib/gcc/x86_64-pc-cygwin/9.2.0/include/c++ -I/usr/lib/gcc/x86_64-pc-cygwin/9.2.0/include/c++/x86_64-pc-cygwin -I/usr/lib/gcc/x86_64-pc-cygwin/9.2.0/include/c++/backward -I/usr/lib/gcc/x86_64-pc-cygwin/9.2.0/include -I/usr/include -I/usr/include/w32api -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB --include /cygdrive/c/Users/a.fireheart/CLionProjects/crapsStarter/cmake-build-debug/crapsStarter_autogen/moc_predefs.h
-o /cygdrive/c/Users/a.fireheart/CLionProjects/crapsStarter/cmake-build-debug/crapsStarter_autogen/EWIEGA46WW/moc_craps.cpp
/cygdrive/c/Users/a.fireheart/CLionProjects/crapsStarter/craps.h
Output
make[3]: * [CMakeFiles/crapsStarter_autogen.dir/build.make:58:
CMakeFiles/crapsStarter_autogen] Error 1 make[2]:
[CMakeFiles/Makefile2:104: CMakeFiles/crapsStarter_autogen.dir/all]
Error 2 make[1]: [CMakeFiles/Makefile2:84:
CMakeFiles/crapsStarter.dir/rule] Error 2 make: * [Makefile:118:
crapsStarter] Error 2
***************** My CMakeLists.txt file content *******************************
cmake_minimum_required(VERSION 3.15)
project(crapsStarter)
set(CMAKE_CXX_STANDARD 17)
#set(RESOURCES crapsResources.qrc)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
#set(CMAKE_AUTOUIC ON)
include_directories(cmake-build-debug/crapsStarter_autogen/include)
# Tell cmake where Qt is located
set(Qt5_DIR "C:/Qt/5.14.1/winrt_x64_msvc2017/lib/cmake/Qt5")
set(QT_INCLUDES "C:/Qt/5.14.1/winrt_x64_msvc2017/include")
MESSAGE("QT_INCLUDES: ${QT_INCLUDES}")
# Include a library search using find_package()
# via REQUIRED, specify that libraries are required
set(Qt5 NEED)
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)
set(SOURCE_FILES craps.cpp die.cpp crapsGame.cpp crapsResources.cpp)
add_executable(crapsStarter ${SOURCE_FILES})
# specify which libraries to connect
target_link_libraries(${PROJECT_NAME} Qt5::Core)
target_link_libraries(${PROJECT_NAME} Qt5::Gui)
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)
craps.h
//
// Created by Arana Fireheart on 2/2/20.
//
#ifndef CRAPSSTARTER_CRAPS_H
#define CRAPSSTARTER_CRAPS_H
#include "ui_CrapsMainWindow.h"
#include "die.h"
#include <QMainWindow>
class CrapsMainWindow : public QMainWindow, private Ui::CrapsMainWindow {
Q_OBJECT
public:
CrapsMainWindow(QMainWindow *parent = nullptr);
void printStringRep();
void updateUI();
private:
Die die1, die2;
bool firstRoll = true;
int winsCount = 0;
public Q_SLOTS:
void rollButtonClickedHandler();
};
#include "moc_craps.cpp"
#endif //CRAPSSTARTER_CRAPS_H
craps.cpp
#include <iostream>
#include <stdio.h>
//#include <QApplication>
//#include <QWidget>
//#include <QGridLayout>
//#include <QPushButton>
//#include <QLabel>
//#include <QPixmap>
#include "die.h"
#include "craps.h"
#include "ui_CrapsMainWindow.h"
CrapsMainWindow :: CrapsMainWindow(QMainWindow *parent) {
// Build a GUI window with two dice.
setupUi(this);
Die die1, die2;
bool firstRoll = true;
int winsCount = 0;
QObject::connect(rollButton, SIGNAL(clicked()), this, SLOT(rollButtonClickedHandler()));
}
void CrapsMainWindow::printStringRep() {
// String representation for Craps.
char buffer[25];
int length = sprintf(buffer, "Die1: %i\nDie2: %i\n", die1.getValue(), die2.getValue());
printf("%s", buffer);
}
void CrapsMainWindow::updateUI() {
// printf("Inside updateUI()\n");
std::string die1ImageName = ":/dieImages/" + std::to_string(die1.getValue());
std::string die2ImageName = ":/dieImages/" + std::to_string(die2.getValue());
die1UI->setPixmap(QPixmap(QString::fromStdString(die1ImageName)));
die2UI->setPixmap(QPixmap(QString::fromStdString(die2ImageName)));
currentBankValueUI->setText(QString::fromStdString("100"));
}
// Player asked for another roll of the dice.
void CrapsMainWindow::rollButtonClickedHandler() {
//void Craps::rollButtonClickedHandler() {
printf("Roll button clicked\n");
die1.roll();
die2.roll();
printStringRep();
updateUI();
}
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)
I'm using Ubuntu 12 64 bit, installed fftw library version 2.1.5.
I have a c++ project with use CMake to build the make file. This is my cmakelist.text:
project(MP)
cmake_minimum_required(VERSION 2.8)
if(TYPE STREQUAL "Debug")
set(CMAKE_BUILD_TYPE "Debug")
else()
set(CMAKE_BUILD_TYPE "Release")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
add_definitions( -std=c++11 )
endif()
find_package(GLUT REQUIRED)
find_package(OpenGL REQUIRED)
find_library(GLUI libglui.a ./vendor/lib)
include_directories(${OPENGL_INCLUDE_DIR}
./vendor/include)
LINK_DIRECTORIES(/usr/local/lib)
LINK_DIRECTORIES(/usr/lib)
LINK_DIRECTORIES(/usr/bin)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} GL GLU glut ${GLUI})
When I tried running the make file create by Cmake, i got this problem:
CMakeFiles/SciVis.dir/Simulation.cc.o: In function `Simulation::init_simulation(unsigned long)':
Simulation.cc:(.text+0x2d5): undefined reference to `rfftw2d_create_plan'
Simulation.cc:(.text+0x2ee): undefined reference to `rfftw2d_create_plan'
CMakeFiles/SciVis.dir/Simulation.cc.o: In function `Simulation::solve()':
Simulation.cc:(.text+0x881): undefined reference to `rfftwnd_one_real_to_complex'
Simulation.cc:(.text+0x891): undefined reference to `rfftwnd_one_real_to_complex'
Simulation.cc:(.text+0xa7f): undefined reference to `rfftwnd_one_complex_to_real'
Simulation.cc:(.text+0xa8f): undefined reference to `rfftwnd_one_complex_to_real'
CMakeFiles/SciVis.dir/Simulation.cc.o: In function `Simulation::FFT(int, void*)':
Simulation.cc:(.text+0x390): undefined reference to `rfftwnd_one_complex_to_real'
Simulation.cc:(.text+0x3a0): undefined reference to `rfftwnd_one_real_to_complex'
collect2: error: ld returned 1 exit status
make[2]: *** [SciVis] Error 1
make[1]: *** [CMakeFiles/SciVis.dir/all] Error 2
make: *** [all] Error 2
In my Simulation.cc file:
#include <fftw.h>
void Simulation::init_simulation(size_t n)
{
//Allocate data structures
size_t dim = n * 2 * (n / 2 + 1);
vx = new fftw_real[dim];
vy = new fftw_real[dim];
vx0 = new fftw_real[dim];
vy0 = new fftw_real[dim];
fx = new fftw_real[n * n];
fy = new fftw_real[n * n];
rho = new fftw_real[n * n];
rho0 = new fftw_real[n * n];
plan_rc = rfftw2d_create_plan(n, n, FFTW_REAL_TO_COMPLEX, FFTW_IN_PLACE);
plan_cr = rfftw2d_create_plan(n, n, FFTW_COMPLEX_TO_REAL, FFTW_IN_PLACE);
// Initialize data structures to 0
for (size_t i = 0; i < n * n; i++)
{
vx[i] = vy[i] = vx0[i] = vy0[i] = fx[i] = fy[i] = rho[i] = rho0[i] = 0.0f;
}
}
void Simulation::FFT(int direction,void* vx)
{
if(direction==1) rfftwnd_one_real_to_complex(plan_rc,(fftw_real*)vx,(fftw_complex*)vx);
else rfftwnd_one_complex_to_real(plan_cr,(fftw_complex*)vx,(fftw_real*)vx);
}
I dont know where I were wrong, can someone please help me ?
Thank you very much.
You're not linking against FFTW, you need to make CMake find the library and link against it first, put this file in your project's directory under a new folder "CMakeModules".
FindFFTW.cmake
# - Find FFTW
# Find the native FFTW includes and library
#
# FFTW_INCLUDES - where to find fftw3.h
# FFTW_LIBRARIES - List of libraries when using FFTW.
# FFTW_FOUND - True if FFTW found.
if (FFTW_INCLUDES)
# Already in cache, be silent
set (FFTW_FIND_QUIETLY TRUE)
endif (FFTW_INCLUDES)
find_path (FFTW_INCLUDES fftw3.h)
find_library (FFTW_LIBRARIES NAMES fftw3)
# handle the QUIETLY and REQUIRED arguments and set FFTW_FOUND to TRUE if
# all listed variables are TRUE
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (FFTW DEFAULT_MSG FFTW_LIBRARIES FFTW_INCLUDES)
mark_as_advanced (FFTW_LIBRARIES FFTW_INCLUDES)
Next, add this line to the top of your CMakeLists.txt:
project(MP)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeModules" ${CMAKE_MODULE_PATH})
Now try this:
find_package(FFTW REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR} ${FFTW_INCLUDES}
./vendor/include)
...
target_link_libraries(${PROJECT_NAME} GL GLU glut ${GLUI} ${FFTW_LIBRARIES})