Catch unit test library linking error - c++

I am trying to use CATCH unit test suite linked below.
https://github.com/philsquared/Catch
However, I cannot succeed to make it right.
The main.cpp and test.cpp are as follows.
//main.cpp
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
//test.cpp
#include "catch.hpp"
TEST_CASE("TESTTest", "") {
CHECK(1 != 2 );
}
When this two files are located in the same folder, I could get a desired result.
However, I moved the test.cpp to the subdirectory named test. It does not work anymore as expected but generates linking errors.
My cmake setting is described below.
project(catchTest)
cmake_minimum_required(VERSION 2.8)
file(GLOB_RECURSE INCS "./*.cpp")
add_executable(${PROJECT_NAME} main.cpp ${INCS})
include_directories(.)
file(GLOB_RECURSE INCS "./*.cpp") was added to include every cpp source files located in the subdirectories. and include_directories(.) was included to let them know the definition of catch.hpp.
I am pretty shure I've done something wrong but I don't know how to fix it.
Please advise me to solve this problem.
It was run on Windows, compiled using mingw gcc-4.9.1 and generated by cmake ninja generator.
EDIT : I added the first few lines of error messages.
FAILED: cmd.exe /c cd . && C:\MinGW\bin\g++.exe CMakeFiles/catchTest.dir/main.cpp.obj CMakeFiles/catchTest.dir/main.cpp.obj CMakeFiles/catchTest.dir/test/testTest.cpp.obj -o catchTest.exe -Wl,--out-implib,libcatchTest.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd .
CMakeFiles/catchTest.dir/main.cpp.obj:main.cpp:(.text+0x0): multiple definition of `Catch::getResultCapture()'
CMakeFiles/catchTest.dir/main.cpp.obj:main.cpp:(.text+0x0): first defined here

Your CMakeLists.txt is wrong, it includes main twice. If you change the add_executable-statement like this it works for me:
add_executable(${PROJECT_NAME} main.cpp test.cpp )
Hope that helps.
Kim

You have to include the right catch.hpp. In the repository there are two different includes with the same name: One in include and one called single_include. Please ensure that you are using single_include.

When you see something like linking error from a header file library such as catch, it means you have set the include path incorrectly.
Use single_include not include.

Related

mingw cannot find my dependencies folder for GLFW

I'm trying to compile the code found in https://www.glfw.org/documentation. This code is in "main.cpp" and I have a folder in the same directory called "dependencies" containing: "glfw3.h", "glfw3.lib" and "libglfw3.a".
project directory
dependencies
I go to the directory in powershell and run:
g++ main.cpp -ldependencies .\dependencies\libglfw3.a -lopengl32 -lgdi32
and it returns:
c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -ldependencies: No such file or directory
collect2.exe: error: ld returned 1 exit status
What have I done wrong?
I've looked all the internet for solutions but none have worked even when I exactly do what is shown on the tutorial or solution, im quite stuck. I think its because im attempting to do this without an IDE (I used visual studio) and until recently i've only did C++ development with an IDE and i'm inexperienced with compiling and linking outside of IDE's.
g++ main.cpp -ldependencies .\dependencies\libglfw3.a -lopengl32 -lgdi32
should be
g++ main.cpp -Ldependencies -lglfw3 -lopengl32 -lgdi32
-L for a directory to search, -l for the name of the library to link with.

Including Pcap++ in a CMake project

I am building a Qt application (with CMake) that will capture and analyze some network packets. Since I am using C++ all over the project, it would be convenient for me to use Pcap++ in my application rather than using lower lever C APIs provided by libs such as libpcap or winpcap.
However I find it hard to use pre-built Pcap++ libraries in my CMakeLists.txt given that no much info was provided on how such an integration would look like.
The application is supposed to be cross-platform and I started with integrating Pcap++ on windows first. So I have downloaded pre-built pcapplusplus-22.05-windows-mingw32-gcc-9.2.0. And then tried to follow instructions from Readme and apply them to my CMake file.
I post here the relevant parts of CMakeLists to show how I have attempted to do it:
set(THIRD_PARTY_LIBS "")
set(THIRD_PARTY_INCLUDES "")
# Add Pcap++ headers
list(APPEND THIRD_PARTY_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/pcapplusplus-22.05-windows-mingw32-gcc-9.2.0/header)
# Pcap++ libs and dependencies according to their README
list(APPEND THIRD_PARTY_LIBS pthread ws2_32 iphlpapi)
list(APPEND THIRD_PARTY_LIBS ${CMAKE_CURRENT_LIST_DIR}/pcapplusplus-22.05-windows-mingw32-gcc-9.2.0/Common++.lib)
list(APPEND THIRD_PARTY_LIBS ${CMAKE_CURRENT_LIST_DIR}/pcapplusplus-22.05-windows-mingw32-gcc-9.2.0/Packet++.lib)
list(APPEND THIRD_PARTY_LIBS ${CMAKE_CURRENT_LIST_DIR}/pcapplusplus-22.05-windows-mingw32-gcc-9.2.0/Pcap++.lib)
# Add WinPcap libs
list(APPEND THIRD_PARTY_LIBS ${CMAKE_CURRENT_LIST_DIR}/WpdPack/Lib/Packet.lib ${CMAKE_CURRENT_LIST_DIR}/WpdPack/Lib/wpcap.lib)
# Add includes to project
include_directories(${THIRD_PARTY_INCLUDES})
# Add libs to project
target_link_libraries(${PROJECT_NAME} PRIVATE ${THIRD_PARTY_LIBS} Qt${QT_VERSION_MAJOR}::Core)
The relative locations are fine. Yet, when application is linking, the following error is occurring:
cmd.exe /C "cd . && C:\Qt\Tools\mingw1120_64\bin\c++.exe -g -mwindows CMakeFiles/MyProjectName.dir/MyProjectName_autogen/mocs_compilation.cpp.obj CMakeFiles/MyProjectName.dir/src/core/AppLogger.cpp.obj CMakeFiles/MyProjectName.dir/src/main.cpp.obj CMakeFiles/MyProjectName.dir/src/utils/utils.cpp.obj CMakeFiles/MyProjectName.dir/ui/mainwindow.cpp.obj CMakeFiles/MyProjectName.dir/res/win.rc.obj CMakeFiles/MyProjectName.dir/MyProjectName_autogen/PNK5WDWK6L/qrc_resources.cpp.obj -o MyProjectName.exe -Wl,--out-implib,libMyProjectName.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -L<proj_loc>/src/core -L<proj_loc>/src/utils -L<proj_loc>/ui thirdparty/spdlog/libspdlogd.a ../../thirdparty/WpdPack/Lib/Packet.lib ../../thirdparty/WpdPack/Lib/wpcap.lib -lpthread -lws2_32 -liphlpapi ../../thirdparty/pcapplusplus-22.05-windows-mingw32-gcc-9.2.0/Common++.lib ../../thirdparty/pcapplusplus-22.05-windows-mingw32-gcc-9.2.0/Packet++.lib ../../thirdparty/pcapplusplus-22.05-windows-mingw32-gcc-9.2.0/Pcap++.lib C:/Qt/6.3.1/mingw_64/lib/libQt6Network.a C:/Qt/6.3.1/mingw_64/lib/libQt6Widgets.a -lws2_32 C:/Qt/6.3.1/mingw_64/lib/libQt6Gui.a C:/Qt/6.3.1/mingw_64/lib/libQt6Core.a -lmpr -luserenv -lmingw32 C:/Qt/6.3.1/mingw_64/lib/libQt6EntryPoint.a -lshell32 -ld3d11 -ldxgi -ldxguid -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/MyProjectName.dir/ui/mainwindow.cpp.obj:<proj_loc>/thirdparty/pcapplusplus-22.05-windows-mingw32-gcc-9.2.0/header/pcappp/PcapLiveDeviceList.h:47: undefined reference to `pcpp::PcapLiveDeviceList::~PcapLiveDeviceList()'
C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/MyProjectName.dir/ui/mainwindow.cpp.obj: in function `MainWindow::on_pushButton_StartRecording_clicked()':
<proj_loc>/ui/mainwindow.cpp:36: undefined reference to `pcpp::PcapLiveDeviceList::getPcapLiveDeviceByIp(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'
C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/MyProjectName.dir/ui/mainwindow.cpp.obj: in function `pcpp::PcapLiveDeviceList::getInstance()':
<proj_loc>/thirdparty/pcapplusplus-22.05-windows-mingw32-gcc-9.2.0/header/pcappp/PcapLiveDeviceList.h:47: undefined reference to `pcpp::PcapLiveDeviceList::PcapLiveDeviceList()'
collect2.exe: error: ld returned 1 exit status
In my application I am executing this simple function to get a network adapter by it's IP address:
this->dev = = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp("1.2.3.4")
Seeing "undefined reference to" makes me think that my libs were not properly included. How do I properly do it?
Later edit: It seems my application is 64bit but the libraries are 32bit compiled. This is probably my issue. However I am wondering why no warnings are visible to indicate this
On their website it is clearly stated that they don't support MinGW 64-bit compilation:
"Please notice that x64 compilation is not supported (and will not work) on either MinGW32 nor MinGW-w64!"
Therefore there is no way to link it within my 64bit application that uses MinGW.

Compiling examples from GLFW?

I am trying to compile the file simple.c in glfw-3.2.1/examples on Ubuntu 18.04. I am using the following compilation command:
gcc -o simple simple.c glad.c -lglfw3 -lGL -lm -lXrandr -lXi -lX11 -lXxf86vm -lpthread -ldl -lXinerama -lXcursor
I have copied and pasted glad.c and glad.h into this examples folder, as well as the include folder that came with glad.zip
However, I when I try to compile the code I get the following:
glad.c:25:10: fatal error: glad/glad.h: No such file or directory
#include <glad/glad.h>
I don't understand why this is, since I am including glad.c in the compilation command.
I am following this tutorial to set up glad https://learnopengl.com/Getting-started/Creating-a-window. Unfortunaly, this opengl tutorial is geared towards MS Windows. Is there an easier way to set up glad on Ubuntu (sudo apt install ...)?
What am I missing here?
Thanks
Including glad.c in the compilation command will not bring the header in, it will compile glad.c and bring in the object from the generated file in (so it would be somewhat close to -lglad if you had installed some glad library)
Unfortunately there does not seem to be any ubuntu package for glad, the next simplest thing would be to simply compile the examples along with glfw (just run cmake and make in the glfw folder), but we can fix that anyway.
Understanding the error
glad.c:25:10: fatal error: glad/glad.h: No such file or directory
#include <glad/glad.h>
says "the file glad.c wants a header located in glad/glad.h, but I cannot find it"
This can either be a problem with include paths (gcc is not looking in the directories you intended it to look at), or the file really is not here.
Looking at glad.c and simple.c, they use this syntax:
#include <glad/glad.c
Includes can be of two kinds, either through double-quotes in which case they are called "local includes" and gcc will look for the headers in the current directory, or with angle brackets and they are usually "system includes"; you need to tell gcc where to look for them with the -I option
Fixing it
There are multiple ways to fix that.
We can use a command line/environment the c files expect.
First, respect the zip hierarchy, the post you linked to says there should be two include directories, so you need to put the headers where they were in the zip file (glad.h in the glad directory) ;
then tell gcc to look for include files in the current directory with -I. (. is the current directory)
The command line will then look like something like gcc -o simple simple.c glad.c -I. -lglfw3 -l...
or
change simple.c and glad.c to include "glad.h" instead of <glad/glad.h> ; the files will then look for the file where you had it automatically.
Having tried to compile simple.c the same way you did now, you will also need a linmath.h header; I am not sure if it comes with glad but glad and linmath.h are in the deps directory of glfw in the git tree, I would assume they also are in the tar.

Static-linking of SDL2 libraries

I am using Windows 7, Code::Blocks and MinGW. I have little to no experience when it comes to compiling/building anything, especially when Code::Blocks doesn't use makefiles.
I downloaded SDL2-devel-2.0.0-mingw.tar.gz (SDL Development Libraries) from http://www.libsdl.org/tmp/download-2.0.php, and I'd like to create a standalone executable using SDL2 libraries, but so far I've always had to bundle the SDL2.dll file with the executable to make it work.
I've heard that I can not static-link dynamic libraries, so my only option seems to be doing something with the source files using the file SDL2-2.0.0.tar.gz (Source Code) from the link I mentioned above. However, I do not know what I should do with those.
What I managed to try with the source files is importing the Visual Studio project to Code::Blocks and building it, but it tells me "sdl-config No such file or directory" (I do not know what triggered that). I'm also not sure if building merely gives me an executable, with which I do not know what I can do to link it to my own executable.
A fool proof idiot's step by step guide would be the best bet to solve this case.
EDIT:
I managed to compile the SDL libraries with the guide Jonas provided, and got a libSDL2.a file.
At first I only added the path of libSDL2.a to "Link libraries:" -section of Code::Blocks, but I got a bunch of errors such as "SDL_Init() not declared in this scope".
In addition to the libSDL2.a path, I also added the path of SDL2-2.0.0\include to the Compiler's search directory as well as the path of SDL2-2.0.0\build.libs to the Linker's search directory. I also wrote this to my test file: #include "SDL.h". My test file now looks like this:
#include "SDL.h"
int main( int argc, char* args[] ) {
//Start SDL
SDL_Init( SDL_INIT_EVERYTHING );
//Quit SDL
SDL_Quit();
return 0;
}
It appears it did fix the declaration problem, but now Code::Blocks opened a SDL_mmjoystick.c file and gave me even more errors: "undefined reference to 'waveInClose#4'", "undefined reference to 'waveOutClose#4'", "undefined reference to 'joyGetNumDevs#0'" and tons of other ones.
Here's a screenshot of what's happening, note the different color of #include texts, I'm not sure why that happens: http://gyazo.com/00656a9c1e57a2bd0db1414fa7d68ced.png
I am not sure how to correctly take this library into use. Any help in this case, or should I make another question for it?
EDIT:
I added -lSDL2 to the linker options and deleted the other parameters. Now it builds fine:
mingw32-g++.exe -Wall -fexceptions -g -IC:\Users\User\Desktop\SDL2-2.0.0\include -c "C:\Users\User\Desktop\CppProjects\SDL project\main.cpp" -o obj\Debug\main.o
mingw32-g++.exe -Wall -fexceptions -g -IC:\Users\User\Desktop\SDL2-2.0.0\include -c "C:\Users\User\Desktop\CppProjects\SDL project\thetestfile.cpp" -o obj\Debug\thetestfile.o
mingw32-g++.exe -LC:\Users\User\Desktop\SDL2-2.0.0\build\.libs -o "bin\Debug\SDL project.exe" obj\Debug\main.o obj\Debug\thetestfile.o -lSDL2 ..\..\SDL2-2.0.0\build\.libs\libSDL2.a C:\Users\User\Desktop\SDL2-2.0.0\build\.libs\libSDL2.a -mwindows
Output size is 945.80 KB
Process terminated with status 0 (0 minutes, 1 seconds)
0 errors, 0 warnings (0 minutes, 1 seconds)
But when I try to run it, it says my computer lacks SDL2.dll, while the whole point was to static-link.
So currently I have the path to build/.libs in my Link libraries -settings, -lSDL2 in the Other linker options, and for search directories I have the path to SDL2-2.0.0/include for the compiler and SDL2-2.0.0/build/.libs for the linker.
In the build/.libs directory I can also see libSDL2.a, libSDL2.dll.a, libSDL2.la and libSDL2.lai files, which I don't know what they are.
It's not necessary to recompile the library,
SDL2 is given with static-link library named "libSDL2.a"
on the folder "SDL2-2.0.0\i686-w64-mingw32\lib\".
Just be sure to add these options to the linker :
"-lmingw32 -lSDL2main -lSDL2 -mwindows -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc"
on Code:Blocks at "Project / Build Options... / Linket settings / Other linker options"
These options allow you to link with what SDL2.dll was using.
You can retreive them on the file "SDL2-2.0.0\i686-w64-mingw32\bin\sdl2-config"
The magical trick is to delete or rename the file "libSDL2.dll.a"
on the folder "SDL2-2.0.0\i686-w64-mingw32\lib\".
I added a "-" before to keep it in case I need it.
I don't know why this librairy overcomes the other and a clue would be appreciated.
I tried with Code::Blocks 12.11 MinGW32 and it worked.
If you run with some projects that use dynamic-link
and some other which use static-link, you will have to
keep your librairies in two different folders knowing that
"libSDL2main.a" will be in those two.
Sorry for my writing, I'm not used to write in english.
Mike

wxwidget compiling on windows command prompt

Can someone please guide me on the method,as to how I would compile wxwidget using windows command prompt or MSYS. [I can't seem to find anything on the wxwiki/wxwidget official book/anywhere else]
I have already compiled wxwidget from the instructions they have provided (using MSYS).
From searching on the Internet it seems one can (maybe?) do it through the use of MAKEFILE (is that correct?)
if yes: WHAT directory & HOW I should link the wx libraries in the MAKEFILE
if no: what is the way besides MAKEFILE?
I know I can use IDE's like code::block and make life simpler but I prefer to compile using the command prompt/msys.
Thanks in advance.
I have created a video on this topic https://www.youtube.com/watch?v=f6FDNR3lh8E
Here is small and simple steps to follow.
Pre-Requirements :
GNU g++ compiler downloaded and installed.
Set gcc/g++ path to Enviroment Variable.
Download WxWidgets Binaries : 1. Header Files, 2. Development Files, 3. DLLs.
Extract then one folder as it is. I have extracted them at D:\WxAPI Folder.
Looks Like :
D:
- WxAPI Folder
- include (Header files has this folder ziped in .7z)
- lib (Development Files & DLL has this folder ziped in .7z and both extracts in this save folder)
Set your project development structure.
My Project Development Structure :
WxExample (Project Folder)
- Build (Folder) : Contains debug and release dlls and exe
- debug (Folder) : Contains debug specific dlls and exe.
- release (Folder) : Contains release specific dlls and exe.
- inlcude (Folder) : Contains project header files.
- src (Folder) : Contains project .cpp files.
- wxCompiler.cmd : Contains compile command created with following steps.
Write Compilation Command
Link Following to Compile.
First Compile Project *.cpp Files :
g++ ".\src*.cpp"
Give Project Output .exe Name :
-o ".\build\release\Project_Name.exe"
Show Project .h File Location to g++ :
-I ".\include"
Provide WxWidget .h Files :
-I "D:\WxAPI\include"
Locate WxWidget setup.h File :
-I "D:\WxAPI\lib\gcc810_x64_dll\mswu"
Supply Binaries Location of WxWidgets :
-L "D:\WxAPI\lib\gcc810_x64_dll"
Provide Compile Flags :
-l wxbase31u
-l wxmsw31u_core
Here D:\WxAPI\lib\gcc810_x64_dll\libwxbase31u.a File Renamed To "wxbase31u"
& D:\WxAPI\lib\gcc810_x64_dll\libwxmsw31u_core.a File Renamed To "wxmsw31u_core" as flag.
You have to add similar file flag as you used in your project as .h
For Example :
-lwxmsw31u_core -lwxbase31u -lwxtiff -lwxjpeg -lwxpng -lwxzlib -lwxregexu -lwxexpat -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lwsock32 -lwininet -loleacc -luxtheme
Here is Full Command :
g++ ".\src*.cpp" -o ".\build\release" -I "D:\WxExample\include" -I "D:\WxAPI\include" -I "D:\WxAPI\lib\gcc810_x64_dll\mswu" -L "D:\WxAPI\lib\gcc810_x64_dll" -l wxbase31u -l wxmsw31u_core
Run wxWidgets.cmd and that's it. Your exe is in your .\Build\release folder.
Set WxWidget DLL path in Enviroment Variable.
If you do not want to copy paste required dll to your release/debug folder.