Consider the following CMakeLists.txt file:
cmake_minimum_required(VERSION 3.22)
project(demo CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_executable(demo main.cpp)
target_compile_features(demo PUBLIC cxx_std_14)
And now the following main.cpp c++ code:
#include <iostream>
#include <vector>
int main(int argc, char *argv[])
{
std::cout << "__cplusplus=" << __cplusplus << std::endl;
std::vector<int> v;
// junk code to prevent g++ from removing code (CMAKE_BUILD_TYPE=Release)
v.reserve(10);
v.push_back(42);
v.shrink_to_fit();
return v[argc-1];
}
If I run the above on my Debian bullseye machine (with backports). Here is what I find out after configuration && build:
% cmake -DCMAKE_BUILD_TYPE:STRING=Release . && make
Leads to:
% nm demo | grep cxx17
0000000000001370 W _ZNSt6vectorIiSaIiEE17_M_realloc_insertIJiEEEvN9__gnu_cxx17__normal_iteratorIPiS1_EEDpOT_
However:
% ./demo
__cplusplus=201402
How come I see cxx17 related symbol when I make sure to compile with c++14 only flags ?
For reference:
% g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110
and
% cmake --version
cmake version 3.22.0
Related
I'm working with a slam system, i've install dso, which the code can be seen here::
https://github.com/JakobEngel/dso
Everything works fine, I manage to compile and run without errors. But know I want to parallelize the code, using CUDA. I'm having lot's of trouble adapting it's CMakeLists.txt in order to be able to use CUDA. The original CMakeLists from dso is available here:
dso CMakeLists.txt
I'm trying to adapt it basing my changes on this implementation of another author on another SLAM system:
ORB SLAM 2 CMakeLists.txt using CUDA
Right now my CMakeLists, with my changes (not working), is like this:
SET(PROJECT_NAME DSO)
PROJECT(${PROJECT_NAME})
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
#set(CMAKE_VERBOSE_MAKEFILE ON)
set(BUILD_TYPE Release)
#set(BUILD_TYPE RelWithDebInfo)
set(EXECUTABLE_OUTPUT_PATH bin)
set(LIBRARY_OUTPUT_PATH lib)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
# required libraries
#SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "/usr/include")
find_package(SuiteParse REQUIRED)
find_package(Eigen3 REQUIRED)
find_package(Boost)
# optional libraries
find_package(LibZip QUIET)
find_package(Pangolin 0.2 QUIET)
find_package(OpenCV QUIET)
#find_package(OpenACC)
# flags
add_definitions("-DENABLE_SSE")
set(CMAKE_CXX_FLAGS
"${SSE_FLAGS} -O3 -g -std=c++11"
)
set(CMAKE_C_FLAGS
"${SSE_FLAGS} -O3 -g -std=c++11"
)
#LIST(APPEND CMAKE_C_FLAGS "-Wall -Wextra -DUSE_NVTX") <<<< Error: doesn't recognize -Wall -Wextra
#LIST(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -DUSE_NVTX") << Error: doesn't recognize -Wall -Wextra
find_package(CUDA REQUIRED)
set(CUDA_PROPAGATE_HOST_FLAGS OFF)
SET(CUDA_HOST_COMPILER /usr/bin/g++)
LIST(APPEND CUDA_NVCC_FLAGS "--compiler-options -fno-strict-aliasing -use_fast_math -ccbin gcc-5")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -std=c++11")
if (MSVC)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
endif (MSVC)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY lib)
cuda_include_directories(
${CUDA_TOOLKIT_ROOT_DIR}/samples/common/inc
)
# Sources files
set(dso_SOURCE_FILES
${PROJECT_SOURCE_DIR}/src/FullSystem/FullSystem.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/FullSystemOptimize.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/FullSystemOptPoint.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/FullSystemDebugStuff.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/FullSystemMarginalize.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/Residuals.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/CoarseTracker.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/CoarseInitializer.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/ImmaturePoint.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/HessianBlocks.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/PixelSelector2.cpp
${PROJECT_SOURCE_DIR}/src/OptimizationBackend/EnergyFunctional.cpp
${PROJECT_SOURCE_DIR}/src/OptimizationBackend/AccumulatedTopHessian.cpp
${PROJECT_SOURCE_DIR}/src/OptimizationBackend/AccumulatedSCHessian.cpp
${PROJECT_SOURCE_DIR}/src/OptimizationBackend/EnergyFunctionalStructs.cpp
${PROJECT_SOURCE_DIR}/src/util/settings.cpp
${PROJECT_SOURCE_DIR}/src/util/Undistort.cpp
${PROJECT_SOURCE_DIR}/src/util/globalCalib.cpp
)
include_directories(
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/thirdparty/Sophus
${PROJECT_SOURCE_DIR}/thirdparty/sse2neon
${EIGEN3_INCLUDE_DIR}
)
# decide if we have pangolin
if (Pangolin_FOUND)
message("--- found PANGOLIN, compiling dso_pangolin library.")
include_directories( ${Pangolin_INCLUDE_DIRS} )
set(dso_pangolin_SOURCE_FILES
${PROJECT_SOURCE_DIR}/src/IOWrapper/Pangolin/KeyFrameDisplay.cpp
${PROJECT_SOURCE_DIR}/src/IOWrapper/Pangolin/PangolinDSOViewer.cpp)
set(HAS_PANGOLIN 1)
else ()
message("--- could not find PANGOLIN, not compiling dso_pangolin library.")
message(" this means there will be no 3D display / GUI available for dso_dataset.")
set(dso_pangolin_SOURCE_FILES )
set(HAS_PANGOLIN 0)
endif ()
# decide if we have openCV
if (OpenCV_FOUND)
message("--- found OpenCV, compiling dso_opencv library.")
include_directories( ${OpenCV_INCLUDE_DIRS} )
set(dso_opencv_SOURCE_FILES
${PROJECT_SOURCE_DIR}/src/IOWrapper/OpenCV/ImageDisplay_OpenCV.cpp
${PROJECT_SOURCE_DIR}/src/IOWrapper/OpenCV/ImageRW_OpenCV.cpp)
set(HAS_OPENCV 1)
else ()
message("--- could not find OpenCV, not compiling dso_opencv library.")
message(" this means there will be no image display, and image read / load functionality.")
set(dso_opencv_SOURCE_FILES
${PROJECT_SOURCE_DIR}/src/IOWrapper/ImageDisplay_dummy.cpp
${PROJECT_SOURCE_DIR}/src/IOWrapper/ImageRW_dummy.cpp)
set(HAS_OPENCV 0)
endif ()
# decide if we have ziplib.
if (LIBZIP_LIBRARY)
message("--- found ziplib (${LIBZIP_VERSION}), compiling with zip capability.")
add_definitions(-DHAS_ZIPLIB=1)
include_directories( ${LIBZIP_INCLUDE_DIR_ZIP} ${LIBZIP_INCLUDE_DIR_ZIPCONF} )
else()
message("--- not found ziplib (${LIBZIP_LIBRARY}), compiling without zip capability.")
set(LIBZIP_LIBRARY "")
endif()
# compile main library.
include_directories( ${CSPARSE_INCLUDE_DIR} ${CHOLMOD_INCLUDE_DIR})
cuda_add_library(dso SHARED ${dso_SOURCE_FILES} ${dso_opencv_SOURCE_FILES} ${dso_pangolin_SOURCE_FILES}
${PROJECT_SOURCE_DIR}/src/teste.cu
)
#set_property( TARGET dso APPEND_STRING PROPERTY COMPILE_FLAGS -Wall )
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # OSX
set(BOOST_THREAD_LIBRARY boost_thread-mt)
else()
set(BOOST_THREAD_LIBRARY boost_thread)
endif()
# build main executable (only if we have both OpenCV and Pangolin)
if (OpenCV_FOUND AND Pangolin_FOUND)
message("--- compiling dso_dataset.")
add_executable(dso_dataset ${PROJECT_SOURCE_DIR}/src/main_dso_pangolin.cpp)
target_link_libraries(dso_dataset dso boost_system cxsparse ${BOOST_THREAD_LIBRARY} ${LIBZIP_LIBRARY} ${Pangolin_LIBRARIES} ${OpenCV_LIBS})
else()
message("--- not building dso_dataset, since either don't have openCV or Pangolin.")
endif()
unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
So, 'main_dso_pangolin.cpp' is my main file. At this point, with only this changes the code compiles. But i wanted to try if i was able to make some CUDA code. In order to do this I created a 'teste.cu' file, that has the same code as one of the cuda samples, like this:
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
// CUDA runtime
#include </usr/local/cuda-9.0/include/cuda_runtime.h>
#include <cuda.h>
// helper functions and utilities to work with CUDA
#include </usr/local/cuda-9.0/samples/common/inc/helper_functions.h>
#include </usr/local/cuda-9.0/samples/common/inc/helper_cuda.h>
__global__ static void timedReduction(const float *input, float *output, clock_t *timer)
{
// __shared__ float shared[2 * blockDim.x];
extern __shared__ float shared[];
const int tid = threadIdx.x;
const int bid = blockIdx.x;
if (tid == 0) timer[bid] = clock();
// Copy input.
shared[tid] = input[tid];
shared[tid + blockDim.x] = input[tid + blockDim.x];
// Perform reduction to find minimum.
for (int d = blockDim.x; d > 0; d /= 2)
{
__syncthreads();
if (tid < d)
{
float f0 = shared[tid];
float f1 = shared[tid + d];
if (f1 < f0)
{
shared[tid] = f1;
}
}
}
// Write result.
if (tid == 0) output[bid] = shared[0];
__syncthreads();
if (tid == 0) timer[bid+gridDim.x] = clock();
}
#define NUM_BLOCKS 64
#define NUM_THREADS 256
void xx(int argc, char** argv){
printf("CUDA Clock sample\n");
// This will pick the best possible CUDA capable device
int dev = findCudaDevice(argc, (const char **)argv);
float *dinput = NULL;
float *doutput = NULL;
clock_t *dtimer = NULL;
clock_t timer[NUM_BLOCKS * 2];
float input[NUM_THREADS * 2];
for (int i = 0; i < NUM_THREADS * 2; i++)
{
input[i] = (float)i;
}
checkCudaErrors(cudaMalloc((void **)&dinput, sizeof(float) * NUM_THREADS * 2));
checkCudaErrors(cudaMalloc((void **)&doutput, sizeof(float) * NUM_BLOCKS));
checkCudaErrors(cudaMalloc((void **)&dtimer, sizeof(clock_t) * NUM_BLOCKS * 2));
checkCudaErrors(cudaMemcpy(dinput, input, sizeof(float) * NUM_THREADS * 2, cudaMemcpyHostToDevice));
timedReduction<<<NUM_BLOCKS, NUM_THREADS, sizeof(float) * 2 *NUM_THREADS>>>(dinput, doutput, dtimer);
checkCudaErrors(cudaMemcpy(timer, dtimer, sizeof(clock_t) * NUM_BLOCKS * 2, cudaMemcpyDeviceToHost));
checkCudaErrors(cudaFree(dinput));
checkCudaErrors(cudaFree(doutput));
checkCudaErrors(cudaFree(dtimer));
long double avgElapsedClocks = 0;
for (int i = 0; i < NUM_BLOCKS; i++)
{
avgElapsedClocks += (long double) (timer[i + NUM_BLOCKS] - timer[i]);
}
avgElapsedClocks = avgElapsedClocks/NUM_BLOCKS;
printf("Average clocks/block = %Lf\n", avgElapsedClocks);
}
And in my main, the first thing i do is to call this function. This time, when i do 'cmake' and 'make i get errors like:
/home/cesar/Documents/dso/src/teste.cu:18:21: error: ‘threadIdx’ was not declared in this scope
const int tid = threadIdx.x;
/home/cesar/Documents/dso/src/teste.cu:19:21: error: ‘blockIdx’ was not declared in this scope
const int bid = blockIdx.x;
I've install CUDA Toolkit correctly, but here is the version:
cesar#cesar-X550JX:/usr/local/cuda/bin$ /usr/local/cuda/bin/nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Sep__1_21:08:03_CDT_2017
Cuda compilation tools, release 9.0, V9.0.176
What do you think i'm doing wrong or i'm missing? I'm having many difficulties adapting CMakeLists.txt due to its complexity and well defined structure.
--- EDIT ---
Running with make -j VERBOSE=1 i get this messages which tells me that a regular c++ compiler is being used:
/usr/bin/c++ -fPIC -O3 -g -std=c++11 -D_FORCE_INLINES -shared -Wl,-soname,libdso.so -o lib/libdso.so CMakeFiles/dso.dir/src/FullSystem/FullSystem.cpp.o CMakeFiles/dso.dir/src/FullSystem/FullSystemOptimize.cpp.o CMakeFiles/dso.dir/src/FullSystem/FullSystemOptPoint.cpp.o CMakeFiles/dso.dir/src/FullSystem/FullSystemDebugStuff.cpp.o CMakeFiles/dso.dir/src/FullSystem/FullSystemMarginalize.cpp.o CMakeFiles/dso.dir/src/FullSystem/Residuals.cpp.o CMakeFiles/dso.dir/src/FullSystem/CoarseTracker.cpp.o CMakeFiles/dso.dir/src/FullSystem/CoarseInitializer.cpp.o CMakeFiles/dso.dir/src/FullSystem/ImmaturePoint.cpp.o CMakeFiles/dso.dir/src/FullSystem/HessianBlocks.cpp.o CMakeFiles/dso.dir/src/FullSystem/PixelSelector2.cpp.o CMakeFiles/dso.dir/src/OptimizationBackend/EnergyFunctional.cpp.o CMakeFiles/dso.dir/src/OptimizationBackend/AccumulatedTopHessian.cpp.o CMakeFiles/dso.dir/src/OptimizationBackend/AccumulatedSCHessian.cpp.o CMakeFiles/dso.dir/src/OptimizationBackend/EnergyFunctionalStructs.cpp.o CMakeFiles/dso.dir/src/util/settings.cpp.o CMakeFiles/dso.dir/src/util/Undistort.cpp.o CMakeFiles/dso.dir/src/util/globalCalib.cpp.o CMakeFiles/dso.dir/src/IOWrapper/OpenCV/ImageDisplay_OpenCV.cpp.o CMakeFiles/dso.dir/src/IOWrapper/OpenCV/ImageRW_OpenCV.cpp.o CMakeFiles/dso.dir/src/IOWrapper/Pangolin/KeyFrameDisplay.cpp.o CMakeFiles/dso.dir/src/IOWrapper/Pangolin/PangolinDSOViewer.cpp.o CMakeFiles/dso.dir/src/dso_generated_teste.cu.o /usr/local/cuda/lib64/libcudart_static.a -lpthread -ldl -lrt
[ 96%] Building CXX object CMakeFiles/dso_dataset.dir/src/main_dso_pangolin.cpp.o
/usr/bin/c++ -DENABLE_SSE -DHAS_ZIPLIB=1 -I/usr/include/opencv -I/home/cesar/Documents/dso/src -I/home/cesar/Documents/dso/thirdparty/Sophus -I/home/cesar/Documents/dso/thirdparty/sse2neon -I/usr/include/eigen3 -I/home/cesar/Documents/Pangolin/include -I/home/cesar/Documents/Pangolin/build/src/include -I/usr/local/include -I/usr/include/suitesparse -I/usr/local/cuda/include -O3 -g -std=c++11 -D_FORCE_INLINES -o CMakeFiles/dso_dataset.dir/src/main_dso_pangolin.cpp.o -c /home/cesar/Documents/dso/src/main_dso_pangolin.cpp
I also tried to separate .cpp files from .cu files, used add_library for .cpp and cuda_add_library for .cu files, like this:
add_library(dso ${dso_SOURCE_FILES} ${dso_opencv_SOURCE_FILES} ${dso_pangolin_SOURCE_FILES})
cuda_add_library(my_cuda_lib ${PROJECT_SOURCE_DIR}/src/teste.cu)
And then use my_cuda_lib in target_link_libraries, like this:
target_link_libraries(dso_dataset dso boost_system cxsparse ${BOOST_THREAD_LIBRARY} ${LIBZIP_LIBRARY} ${Pangolin_LIBRARIES} ${OpenCV_LIBS} ${CUDA_LIBRARIES} my_cuda_lib)
But still got the same errors.
-- EDIT: MCVE ---
To demonstrate my error i created a simple example. I have 2 simple files, my main which is a .cpp and my cuda file .cu. My main just calls the function on the other file, looks like this:
#include <iostream>
#include "hello_world.cu"
using namespace std;
int main()
{
teste();
return 0;
}
And my .cu file looks like this:
#include <stdio.h>
#include <iostream>
// CUDA runtime
#include </usr/local/cuda-9.0/include/cuda_runtime.h>
// helper functions and utilities to work with CUDA
#include </usr/local/cuda-9.0/samples/common/inc/helper_functions.h>
#include </usr/local/cuda-9.0/samples/common/inc/helper_cuda.h>
__global__ void kernel (void){
extern __shared__ float shared[];
const int tid = threadIdx.x;
const int bid = blockIdx.x;
}
int teste( void ) {
kernel<<<1,1>>>();
printf( "Hello, World!\n" );
return 0;
}
My CMakeLists.txt that i made to compile this looks like this:
cmake_minimum_required(VERSION 2.8)
set(CUDA_HOST_COMPILER /usr/bin/g++-5)
find_package(CUDA QUIET REQUIRED)
# Pass options to NVCC
set(
CUDA_NVCC_FLAGS
${CUDA_NVCC_FLAGS};
-O3
)
# For compilation ...
# Specify target & source files to compile it from
cuda_add_executable(
helloworld
hello_world.cu
teste.cpp
)
After making cmake and running with "cmake --build ." (i don't know why it has to be this command, normally i just do make -j, but in this example only this works) i get the same errors as in my project, ‘threadIdx’ was not declared in this scope, same for 'blockIdx' etc..
Since you are including hello_world.cu file in your main code, then you want to have it compiled with nvcc compiler. To achieve this change name of teste.cpp file to teste.cu (otherwise g++ will be used).
Also remove 'hello_world.cu' from CMakeLists.txt (it is included already in teste file) to have something like this:
cuda_add_executable(
helloworld
teste.cu
)
Then it should work.
-- EDIT: Additional question --
If you want to keep your .cpp file then you need kind of separation between what g++ can do for you and what nvcc should. So you can introduce to your project additional hello_world.h file:
#ifndef HELLO_WORLD_H
#define HELLO_WORLD_H
int teste();
#endif
include it in your teste.cpp:
#include <iostream>
#include "hello_world.h"
using namespace std;
int main()
{
teste();
return 0;
}
and then your CMakeLists.txt looks like in your original example:
...
cuda_add_executable(
helloworld
teste.cpp
hello_world.cu
)
In such a case hello_world.cu will be compiled with nvcc, and then compilling and linking of teste.cpp will be done by g++ (which will be possible in that case since there is no CUDA code in teste.cpp).
I am attempting to generate code coverage for a small test library. The library only consists of two files.
calculator.cpp:
#include "calculator.h"
Calculator::Calculator()
{
}
Calculator::~Calculator()
{
}
void Calculator::addNumbers(int x, int y)
{
this->result = x + y;
}
calculator.h:
#ifndef CALCULATOR_H
#define CALCULATOR_H
class Calculator
{
public:
Calculator();
~Calculator();
void addNumbers(int x, int y);
};
#endif
I have a unit test for this library that is being executed. It includes the library and runs fine. I have set the cmake_cxx_flags to include -fprofile-arcs and -ftest-coverage in the top level CMakeLists.txt.
cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_CXX_FLAGS "-std=c++11")
include_directories("${PROJECT_BINARY_DIR}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 --coverage")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 --coverage -ftest-coverage -fprofile-arcs")
add_subdirectory(src)
add_subdirectory(test)
I am using a script to take the gcno and gcda files that are generated on build to generate a human readable report.
#!/bin/bash
OUTPUT_DIR="$1/bin/ExecutableTests/Coverage"
mkdir -p "$OUTPUT_DIR"
component=Calculator
dependency=calculator
script=test_calculator.sh
unit_test=unit_test_calculator
mkdir $OUTPUT_DIR/$component
cd "$1"/bin/
make clean || exit 1
make || exit 1
# Create baseline coverage
lcov -c -i -d "$1"/bin/src/"$component"/CMakeFiles/"$dependency".dir -o "$1/Coverage/$component"_"$dependency".coverage.base
# Run the test
$1/scripts/$script $1
# Create test coverage
lcov -c -d "$1"/bin/test/$component/CMakeFiles/"$unit_test".dir -o "$1/Coverage/$component"_"$dependency".coverage.run
lcov -d "$1/test/$component" -a "$1/Coverage/$component"_"$dependency".coverage.base -a "$1/Coverage/$component"_"$dependency".coverage.run -o "$1/Coverage/$component"_"$dependency".coverage.total
genhtml --branch-coverage -o "$OUTPUT_DIR/$component" "$1/Coverage/$component"_"$dependency".coverage.total
rm -f "$1/Coverage/$component"_"$dependency".coverage.base "$1/Coverage/$component"_"$dependency".coverage.run "$1/Coverage/$component"_"$dependency".coverage.total
I can see that the data files are being generated for the library; however when I view the report that is generated from the script it shows that the library is never touched. This is clearly wrong as illustrated by my unit test.
#include "lest_basic.hpp"
#include "calculator.h"
#include <memory>
#include <iostream>
int addResult(int x, int y)
{
Calculator calc1;
return calc1.addNumbers(x, y);
}
const lest::test specification[] =
{
CASE( "Addition" )
{
std::cout << "Starting Addition testing..." << std::endl;
std::cout << "Adding 1 and 2..." << std::endl;
EXPECT(addResult(1, 2) == 3);
std::cout << "Adding 2 and 8..." << std::endl;
EXPECT(addResult(2, 8) > 1);
std::cout << "Adding 7 and 4..." << std::endl;
EXPECT(addResult(7, 4) < 12);
},
};
int main(int argc, char **argv) {
return lest::run( specification );
}
Here is the CMakeLists.txt for my unit test:
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/ExecutableTests/)
include_directories(${CMAKE_SOURCE_DIR}/externalinclude/)
include_directories(${CMAKE_SOURCE_DIR}/src/Calculator/)
add_executable (unit_test_calculator test_calculator.cpp)
target_link_libraries(unit_test_calculator -Wl,--whole-archive calculator -Wl,--no-whole-archive)
My question is why is the report saying that the library code isn't be covered? Are the data files the problem?
I have fixed my issue. The problem was that I wasn't running lcov against the source code after running the unit test. I had the wrong directory.
lcov -c -d "$1"/bin/test/$component/CMakeFiles/"$unit_test".dir -o "$1/Coverage/$component"_"$dependency".coverage.run
Needed to be:
lcov -c -d "$1"/bin/src/$component/CMakeFiles/"$dependency".dir -o "$1/Coverage/$component"_"$dependency".coverage.run
so I've hit a dead end, I'm simplying trying to run the following:
main.cpp:
#include <iostream>
#include <allegro5/allegro.h>
int main(int argc, char **argv) {
std::cout << "Hello, World!" << std::endl;
al_init();
std::cout << "hi" << std::endl;
return 0;
}
CMakeList.txt:
cmake_minimum_required(VERSION 3.6)
project(allegro_test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
SET(ALLEGRO_ROOT C:/Users/duck-/workspace/cpp/recources/allegro/)
INCLUDE_DIRECTORIES( ${ALLEGRO_ROOT}/include )
LINK_DIRECTORIES( ${ALLEGRO_ROOT}/lib)
add_executable(allegro_test ${SOURCE_FILES})
TARGET_INCLUDE_DIRECTORIES(allegro_test PUBLIC ${ALLEGRO_ROOT})
TARGET_LINK_LIBRARIES(allegro_test allegro)
output:
"C:\Users\duck-\.CLion2016.2\system\cmake\generated\allegro test-50fbd97d\50fbd97d\Debug\allegro_test.exe"
Process finished with exit code -1073741701 (0xC000007B)
I'm using allegro-mingw-gcc6.2.0-x64-dynamic-5.2.2.zip from here and have copyied allegro-5.2.dll, cygintl-1.dll & cygintl-2.dll to
C:\Users\duck-.CLion2016.2\system\cmake\generated\allegro test-50fbd97d\50fbd97d\Debug\
where the program's executed. I've installed .NET Framework 4.6.2. Am I missing something? cheers in advance.
Since you are building the program in a Debug configuration, you'll need to include allegro-debug-5.2.dll, and not just allegro-5.2.dll.
I am trying to learn C++ and I am having a bit of nightmare doing a test where I connect to a MySQL database.
I've had issues with the MySQL connector not linking properly then was getting issues related to relocation truncated to fitr_x86_64_32 against symbol.
I think I have fixed that by adding a compiler flag and now the app successfully builds and links.
When I run the app, it gets as far as calling get_driver_instance but then it exits. No exception is thrown, no errors nothing just exit code 0.
Below is my DBManager class
#include "DBConnectionManager.h"
using namespace std;
DBConnectionManager::DBConnectionManager() {
cout << "Starting DBConnectionManager - Updated" << endl;
try {
cout << "Getting driver instance" << endl;
driver = get_driver_instance();
cout << "Got driver instance" << endl;
conn = driver->connect("tcp://127.0.0.1:3306", "root", "password");
conn->setSchema("bugs");
cout << "Connected to database" << endl;
}
catch (SQLException ex) {
cout << "Error connecting to DB: " << ex.what() << endl;
}
catch (...) {
cout << "Something has gone wrong" << endl;
}
}
Below is the header file
#ifndef MYSQLTEST_DBCONNECTIONMANAGER_H
#define MYSQLTEST_DBCONNECTIONMANAGER_H
#include <driver.h>
#include <exception.h>
#include <resultset.h>
#include <statement.h>
using namespace sql;
class DBConnectionManager
{
private:
sql::Driver *driver;
sql::Connection *conn;
sql::Statement *statement;
sql::ResultSet *res;
public:
DBConnectionManager();
void performSql();
};
#endif //MYSQLTEST_DBCONNECTIONMANAGER_H
Below is my main method
#include "DBConnectionManager.h"
int main() {
DBConnectionManager dbConnectionManager;
dbConnectionManager.performSql();
return 0;
}
Below is my CMakeLists.txt file
cmake_minimum_required(VERSION 3.6)
project(MySQLTest)
include_directories("C:\\Program Files\\MySQL\\MySQL Connector C++ 1.1.7\\include\\cppconn" "C:\\Program Files\\MySQL\\MySQL Connector C++ 1.1.7\\lib\\opt")
SET(GCC_COVERAGE_LINK_FLAGS "-m64 -Wl,--image-base -Wl,0x10000000 -lpthread -pthread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -m64 -Wl,--image-base -Wl,0x10000000 -lpthread -pthread ")
set(SOURCE_FILES main.cpp DBConnectionManager.cpp)
add_executable(MySQLTest ${SOURCE_FILES})
add_library(mysqlcppconn.lib)
set_target_properties(MySQLTest PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(mysqlcppconn.lib PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(MySQLTest "C:\\Program Files\\MySQL\\MySQL Connector C++ 1.1.7\\lib\\opt\\mysqlcppconn.lib")
When I create the instance of my DBConnectionManager class it successfully calls the query and prints Starting DBConnectionManager - Updated followed by Getting Driver Instance but then it exits with Process finished with exit code 0 with no clues as to what went wrong.
Update
I'm finally getting somewhere. I found there are some MySQL client libraries within Cygwin so I have download them and referenced them in the cmake file.
My cmake file now looks like this:
cmake_minimum_required(VERSION 3.6)
project(MySQLTest)
SET(CPPCONN_PUBLIC_FUNC=)
SET(GCC_COVERAGE_LINK_FLAGS "-g -m64 -DCPPCONN_PUBLIC_FUNC= -Dmysqlcppconn_EXPORTS -lpthread -pthread -Wl,--image-base -Wl,0x10000000 -lz")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCPPCONN_PUBLIC_FUNC= -Dmysqlcppconn_EXPORTS -std=c++11 -g -m64 -Wl,--image-base -Wl,0x10000000 -lpthread -pthread -lz")
include_directories("C:/mysql_connector/include")
include_directories("C:/boost_1_61_0")
set(BOOST_INCLUDE_DIR C:/boost_1_61_0)
set(BOOST_LIBRARY_DIR C:/boost_1_61_0/libs)
set(SOURCE_FILES main.cpp DBConnectionManager.cpp)
add_executable(MySQLTest ${SOURCE_FILES})
find_package(Boost COMPONENTS REQUIRED)
link_directories(C:/mysql_connector/lib)
target_link_libraries(MySQLTest "C:/mysql_connector/lib/mysqlcppconn.dll" "C:/Program Files/MySQL/MySQL Server 5.7/lib/libmysql.dll" "C:/mysql_connector/lib/libmysqlclient.dll.a" "C:/mysql_connector/lib/libmysqlclient_r.dll.a" ${Boost_LIBRARY_DIR})
Notice how I have linked the libraries libmysqlclient.dll.a and libmysqlclient_r.dll.a which is what I got from Cygwin.
When I run the app now it successfully gets the driver instance and to the console is outputted
Starting DBConnectionManaged - Updated
Getting driver instance
Got driver instance
But when I try and connect with driver->connect I then get the following error
0 [main] MySQLTest 2976 C:\Users\Chris\.CLion2016.2\system\cmake\generated\MySQLTest-8702ae13\8702ae13\Debug\MySQLTest.exe: *** fatal error - Internal error: TP_NUM_C_BUFS too small: 50
When I put it through the debugger, it fails on the driver->connect with
gdb: unknown target exception 0xe06d7363 at 0x7fff11347788
Program received signal ?, Unknown signal.
0x00007fff11347788 in RaiseException () from /cygdrive/c/WINDOWS/System32/KERNELBASE.dll
Update 2
Everything I've read points the mysql connector binaries should work fine, so I started again. Below is now the contents of my cmake file
cmake_minimum_required(VERSION 3.6)
project(MySQLTest)
#add_compile_options("-v")
SET(GCC_COVERAGE_LINK_FLAGS )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(BOOST_INCLUDE_DIR C:/boost_1_61_0)
set(BOOST_LIBRARY_DIR C:/boost_1_61_0/libs)
include_directories("C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/include" "C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/include/cppconn" ${BOOST_INCLUDE_DIR})
set(SOURCE_FILES main.cpp DBConnectionManager.cpp)
add_executable(MySQLTest ${SOURCE_FILES})
find_package(Boost COMPONENTS REQUIRED)
link_directories(C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/lib/opt)
target_link_libraries(MySQLTest C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/lib/opt/mysqlcppconn.lib ${Boost_LIBRARY_DIR})
Now when I compile I get the original error
C:/Program Files/MySQL/MySQL Connector C++ 1.1.7/lib/opt/mysqlcppconn.lib(mysqlcppconn.dll.b):(.text+0x2): relocation truncated to fit: R_X86_64_32 against symbol `__imp_get_driver_instance' defined in .idata$5 section in C:/Program Files/MySQL/MySQL Connector C++ 1.1.7/lib/opt/mysqlcppconn.lib(mysqlcppconn.dll.b)
That sounds like to me like my app is compiling as 32 bit instead of 64 bit. As a test I ran the following code:
cout << "Int size is: " << sizeof(int) << endl;
The code above prints 4 (shouldn't it be 8 if it was compiled as 64 bit).
If my thinking is correct, why isn't it compiling it as 64 bit, I've tried setting the compiler flag -m64 but makes no difference. I've installed the Cygwinx64 as well which CLion is using.
You can use MySQL Connector C++
This is how to configure using Cmake
cmake_minimum_required(VERSION 3.7)
project(projectname)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
Include the dirs where you extracted the mysql-connector-cpp - download
include_directories(/usr/local/include/mysql-connector-cpp/include)
Create a cmake variable containing the project source files
set(SOURCE_FILES main.cpp)
Create your executable
add_executable(projectname ${SOURCE_FILES})
Link after creating executable
target_link_libraries(projectname mysqlcppconn)
Your CMakeList should at least have this or look like this in this order
cmake_minimum_required(VERSION 3.7)
project(projectname)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories(/usr/local/include/mysql-connector-cpp/include)
set(SOURCE_FILES main.cpp)
add_executable(projectname ${SOURCE_FILES})
target_link_libraries(projectname mysqlcppconn)
You can use mysql++ library to connect to mysql from c++.
For that install mysql++,
(Ubuntu)
sudo apt-get install mysql-server mysql-client
sudo apt-get install libmysqlclient-dev libmysql++-dev libmysqlcppconn-dev
(Mac)
brew install mysql++
include library by adding,
/usr/include/mysql++
/usr/include/mysql
and add linkers,
-lmysqlpp -lmysqlclient
Example code,
#include <iostream>
#include <string>
#include <mysql++.h>
#include <mysql.h>
#define dbname "dbname"
#define server "localhost"
#define user "username"
#define pass "password"
using namespace std;
using namespace mysqlpp;
int main() {
Connection con(true);
try {
con.connect(dbname, server, user, pass);
cout << "Connected to database\n";
string s = "SELECT * FROM mirrors_mee WHERE id=1";
Query q = con.query(s);
StoreQueryResult sq = q.store();
StoreQueryResult::iterator it;
it = sq.begin();
while (it != sq.end()) {
Row row = *it;
cout << row[5] << " " << row[6] << " " << row[7] << endl;
it++;
}
} catch (Exception &e) {
cout << e.what() << endl;
}
return 0;
}
You will get full documentation of the library here.
I need to build an Ocaml/C++ module which calls a shared object (.so under linux)
As long as it is a question to compile a simple Ocaml/C++ stub, I manage the thing but when I need to link the .so with ocamlmklib or ocamlopt, it fails
I work under gcc 4.5 (c++0x)
files for the shared object :
hello.hpp
#include <iostream>
#include <string>
using namespace std;
class HelloApplication
{
public :
HelloApplication();
~HelloApplication();
void say(string s);
};
typedef HelloApplication *(*create_hello)();
hello.cpp :
#include "hello.hpp"
HelloApplication::HelloApplication(){}
HelloApplication::~HelloApplication(){}
void HelloApplication::say(string s)
{
cout << "Hello : " << s << endl;
}
extern "C"
{
HelloApplication *create()
{
return new HelloApplication();
}
}
the CMake.txt file to compile the thing :
cmake_minimum_required(VERSION 2.6)
project(testHello_proj)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Release" FORCE)
#set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Debug" FORCE)
set(LIBRARY_OUTPUT_PATH lib/${CMAKE_BUILD_TYPE})
## Compiler flags
if(CMAKE_COMPILER_IS_GNUCXX)
set ( CMAKE_CXX_FLAGS "-O2 -std=c++0x"
CACHE STRING "g++ Compiler Flags for All Builds" FORCE)
set ( CMAKE_CXX_FLAGS_DEBUG "-std=c++0x -O2 -g -Wall"
CACHE STRING "g++ Compiler Flags for Debug Builds" FORCE)
set ( CMAKE_CXX_FLAGS_RELEASE "-O2 -fmessage-length=0 -std=c++0x"
CACHE STRING "g++ Compiler Flags for Release Builds" FORCE)
set ( CMAKE_CXX_FLAGS_MINSIZEREL "-Os -std=c++0x"
CACHE STRING "g++ Compiler Flags for Release minsize builds" FORCE)
set ( CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g1 -std=c++0x"
CACHE STRING "g++ Compiler Flags for Release with Debug Info builds" FORCE)
endif()
file(
GLOB_RECURSE
source_files
src/*
)
add_library(
testHello
SHARED
${source_files}
)
I get a library named libtestHello.so
now files of the Ocaml/C++ module, named mymod:
*mymod_stubs.cpp :*
#include <cstdlib>
#include <dlfcn.h>
#include <string>
#include "hello.hpp"
extern "C" {
#include <memory.h>
#include <mlvalues.h>
}
using namespace std;
HelloApplication* hello;
extern "C" value initHello (value unit) {
CAMLparam1 (unit);
create_hello hello_pMaker;
void* hello_hndl = dlopen("/path_to_cmake_dir/build/lib/Release/libtestHello.so", RTLD_LAZY);
if(hello_hndl == NULL)
{
cerr << "dlopen : " << dlerror() << endl;
exit(EXIT_FAILURE);
}
void *hello_mkr = dlsym(hello_hndl, "create");
if (hello_mkr == NULL)
{
cerr << "dlsym : " << dlerror() << endl;
exit(EXIT_FAILURE);
}
hello_pMaker = (create_hello)hello_mkr;
HelloApplication* hello_ptr(hello_pMaker());
hello = hello_ptr;
CAMLreturn (Val_unit);
}
extern "C" value say (value v_str) {
CAMLparam1 (v_str);
string s = String_val(v_str);
hello->say(s);
CAMLreturn (Val_unit);
}
mymod.ml :
external initHello : unit -> unit = "initHello"
external say : string -> unit = "say"
caller.ml (test file) :
Mymod.initHello;;
Mymod.say "tout le monde";;
Makefile :
CPPSRC=mymod_stubs.cpp
CPPOBJ=mymod_stubs.o
CPPINC=-I/usr/local/lib/ocaml/caml -I/path_to_cmake_dir/src
CPPLIB=-std=c++0x
MODSRC=mymod.ml
MODNAME=mymod
OPTOBJ=mymod.cmx
OPTLIB=mymod.cmxa
CALLERSRC=caller.ml
OPTCALLERFLAGS=-I . -cclib
CALLERLIB=-lstdc++
OPTCALLEREXEC=caller.opt
all: opttest
#g++
cppcompile:
g++ -o ${CPPOBJ} ${CPPLIB} ${CPPINC} -c ${CPPSRC}
#native
optcompile: cppcompile
ocamlopt -c ${MODSRC}
optmklib: optcompile
ocamlmklib -o ${MODNAME} -ccopt -L/path_to_cmake_dir/build/lib/Release -cclib -ltestHello ${CPPOBJ}
ocamlmklib -o ${MODNAME} -ccopt -L/path_to_cmake_dir/build/lib/Release -cclib -ltestHello ${OPTOBJ}
opttest: optmklib
ocamlopt ${OPTCALLERFLAGS} ${CALLERLIB} ${OPTLIB} ${CALLERSRC} -o ${OPTCALLEREXEC}
#clean
clean :
rm -f *.cma *.cmo *.cmx *.cmxa *.cmi *.so *.a *.o ${OPTCALLEREXEC}
it compiles but I can't open the shared object libtestHello.so:
$: ./caller.opt ./caller.opt: error while loading shared libraries:
libtestHello.so: cannot open shared object file: No such file or
directory
thanks for your help :)
You probably need to pass -rdynamic and -Wl,-rpath at link time.
(and I am not sure you can call Ocaml code from C or C++ code without care; you'll need to initialize the Ocaml runtime system; likewise the std C++ library might not work from an unpatched ocaml program, e.g. because of constructors for static objects...)