Cannot use the C++ `std::filesystem` library with Meson build - c++

I am trying to build a piece of C++ code that uses the new C++17 Filesystem library, using the Meson build system.
This is the piece of meson.build file involved:
if not compiler.has_header('filesystem') # This is OK
warning('The compiler has no <filesystem> header file')
endif
filesystem_dep = dependency('libc++fs', modules : ['filesystem'])
test_exe = executable('test', test_src,
include_directories : include_dirs,
dependencies : filesystem_dep
)
In case the boost::filesystem library is used, this should be the correct syntax:
filesystem_dep = dependency('boost', modules : ['filesystem'])
How can I specify I want the version contained in the Standard C++ library? This is what I tried without success: 'libc++fs', 'stdlib', 'stdc++', 'libc++', 'c++', 'c++17'.
This is the error message I get from Meson:
src/meson.build:33:0: ERROR: Native dependency 'libc++fs' not found
The compiler I am currently using is LLVM/clang.

dependency() is for external libraries. Standard libraries should be configured using compiler command line with special functions like add_XXX_arguments(). So, try
add_project_arguments(['-stdlib=libc++'], language : 'cpp')
add_project_link_arguments(['-stdlib=libc++','-lstdc++fs'], language : 'cpp')
However, '-lstdc++fs' maybe not needed in your case.

Related

error while compiling a c++ code which is called inside of a python code, with boost python

I started a project in Python and I want to work with some image objects. I want to call some C++ functions in my Python's code. After some research, I decided to use the Python Boost library to call a C++ function in my Python code.
My Boost version is : libboost_python3-py36.so.1.65.1.
and I am using Python v3.6.
I wrote my C++ code like this in my CppProject.cpp:
char const* myMethod() {
// do some operations ...
return "It is Done";
}
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(CppProject) {
boost::python::def("getTryString", myMethod); // boost::python is the namespace
}
also, I created my CMakeLists.txt like this:
cmake_minimum_required(VERSION 2.8.3)
FIND_PACKAGE(PythonInterp)
FIND_PACKAGE(PythonLibs)
FIND_PACKAGE(Boost COMPONENTS python)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
PYTHON_ADD_MODULE(NativeLib CppProject)
FILE(COPY MyProject.py DESTINATION .) # See the whole tutorial to understand this line
and finally, this is my Python code in MyProject.py:
import NativeLib
# some preprocess
print (NativeLib.getTryString)
After writing the code, I created a directory with the name build.
and in that directory, I ran this command:
cmake -DCMAKE_BUILD_TYPE=Release ..
After that and before I run my Python code, I did make it and finally, I ran my python's code but segmentation fault occurred!
Could someone help me with solving this error?
The compiler needs all symbols you use in your program to be declared before you use them. If you use a symbol which have't been declared it will give you an error because it doesn't know about it.
Now when you use BOOST_PYTHON_MODULE, that symbol is unknown by the compiler, and the whole statement is therefore syntactically wrong.
You must include the Boost header files that defines the BOOST_PYTHON_MODULE macro, as well as boost::python::def.

Adding my method to OpenCV

I want to add new method in OpenCV library. I made my_funct.cpp whose code is as simple as:
#include "precomp.hpp"
#include <stdio.h>
void cv::my_funct(){
printf("%s\n","Hello world!");
}
and I added header CV_EXPORTS_W void my_funct(); to files C:\opencv\build\include\opencv2\imgproc\imgproc.hpp and C:\opencv\sources\modules\imgproc\include\opencv2\imgproc\imgproc.hpp. Then I used CMake to build new binaries for whole library, but when I make a new project in which I use my_funct() I get an error:
The procedure entry point _ZN2cv8my_functEv could not be located in
the dynamic link library path_to_this_project\project.exe.
Other opencv functions work just fine. I'm using mingw32 to compile library and the version of OpenCV is 2.4.9. Can you tell me what am I doing wrong?
This looks like an MinGW run-time error. So going by the assumption that you didn't get any compiler or linker errors while building project.exe, your executable most likely doesn't find the matching .dll to your .dll.a import library (which must have included the my_funct() definition).
I would recommend during developments phase - not talking about the install() scripting - to add a post-build step using add_custom_command() and generator expressions to copy the right DLL next to your project.exe:
add_custom_command(
TARGET project
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"<... path to matching DLL ...>"
"$<TARGET_FILE_DIR:project>"
)
Certainly you could also let CMake find the matching DLL, but before I could go into details there I would need to see your project.exe CMake script.
Maybe also good idea - if you are in the process of extending OpenCV code - would be to use ExternalProject_Add() to include OpenCV into your project.
References
MinGW-w64 - for 32 and 64 bit Windows - Wiki: Procedure entry point OpenProcessToken? could not be located in the dynamic link library kernel32.dll
MinGW "The procedure entry point libiconv could not be located ..."
Getting started with OpenCV 2.4 and MinGW on Windows 7

Cmake test : was a library compiled/linked against libc++ or libstd++?

I am using cmake to manage my project that uses a third party library.
This library could have been compiled/linked against libc++ or libstd++ (Depending on the version).
I know how to tell cmake to compile/link my project against libc++ or libstdc++, but I don't know how to check if the library I am using was compiled/linked against libc++ or libstd++. Is there any cmake command to check that?
For shared libraries you can use the GetPrerequisites standard module to test if the library depends on libstc++ or libc++.
For example, the following code test if boost's program_options library has been compiled against libstc++ or libc++:
set (_library "/usr/local/lib/libboost_program_options.dylib")
set (_prequesites "")
set (_exclude_system FALSE)
set (_recurse FALSE)
set (_exePath "")
set (_searchDirs "")
get_prerequisites(${_library} _prequesites ${_exclude_system} ${_recurse} "${_exePath}" "${_searchDirs}")
if (_prequesites MATCHES "/libstdc\\+\\+")
message("using libstc++")
elseif (_prequesites MATCHES "/libc\\+\\+")
message("using libc++")
else()
message("using neither libstc++ nor libc++")
endif()
For static libraries you probably have to resort to running nm on the library file to determine external symbols and then search for characteristic strings like __gnu_ in the output.
Do you have an error if you link to the wrong version ? If it's the case, you can use try_compile from CMake. Example of use :
try_compile(
TRY_COMPILE_SUCCESS
${CMAKE_BINARY_DIR}/tmpTryDir
${CMAKE_MODULES_DIR}/SourceFile.cpp
CMAKE_FLAGS
"-DINCLUDE_DIRECTORIES=${TRY_INCLUDE_DIRS}"
"-DLINK_DIRECTORIES=${TRY_LIBRARY_DIRS}"
"-DLINK_LIBRARIES=${TRY_LIBRARIES}"
COMPILE_DEFINITIONS
"-DCOMPILER_OPTION"
)
And then, the CMake variable TRY_COMPILE_SUCCESS contains TRUE or FALSE depending of the compilation success.

gnat gprbuild : how to build a dynamic dll and link with a static c++ library

I have a full Ada project I want to build to get a dynamic dll.
Therefore I have to link it with another static library (myanotherlibrary.lib).
I use this command line :
gprbuild -d "D:\My_grp_project\My_grp_project.gpr"
Here the content of the .gpr :
project My_grp_project is
Architecture := "x86";
for Languages use ("Ada");
for Source_Dirs use (".", "source", "source\common");
for Library_Dir use "dll\" & Architecture;
for Library_Ali_Dir use "ali\" & Architecture;
for Library_Name use "My_grp_project";
for Library_Kind use "dynamic";
for Object_Dir use "obj\" & Architecture;
package Linker is
for Default_Switches ("Ada") use ("-L.", "-lbar");
end Linker;
end My_grp_project;
I put "myanotherlibrary.lib" in the directory "D:\My_grp_project\", but it still doesn't link: "undefined reference to ..."
Could anyone help me please ?
Regards
Glen
Looking at the docs, I think you should be using the Library_Options attribute instead of package Linker:
for Library_Options use ("-L.", "-lbar”);
(I’m confused - do you mean myanotherlibrary.lib or bar.lib?)
I’d be a bit concerned about using a static library from a dynamic library: I’d expect the dynamic library to be built with -fPIC or equivalent switch to get position-independent code, so that the same loaded library binary can be seen at different addresses in each of the executables using it.
Here the solution I finally found.
It is not possible to link static library compiled with MSVC. I had to compile my static library with GCC (same version as the one included in GNAT).
I had to add "Library_Options" options, without "-L" and "-l" arguments (another problem I passed). Note that package Linker is not taken into account while building a dynamic library. Note also that paths shall have no spaces !
project My_grp_project is
for Languages use ("Ada");
for Source_Dirs use (".", "source", "source\common");
for Library_Dir use “dll";
for Library_Ali_Dir use "ali";
for Object_Dir use "obj";
for Library_Name use "My_grp_project";
for Library_Kind use "dynamic";
for Library_Options use ("path\myanotherlibrary.a", "path_to_GNAT\libstdc++.a");
end My_grp_project;
I builded the project in the GPS (default option) : "Build All"
In result I do have my dynamic library "libMy_grp_project.dll"
Voilà.
Thanks !

How to link boost.build project to particular static library

I use boost.build for my project. Of course, I use boost itself. Also, for test purposes I use google-test library with my project. I have to link my project with google-test's static library. I've found the workaround to do that for MinGW (for linux's gcc works too)
exe foo : $(IMPORTANT_PART) $(TEST_UTILITY_PART) : <toolset>gcc <linkflags>"../../libs/gtest-1.6.0/libs/gtest_main.a" <linkflags>-static <linkflags>-lpthread ;
It looks kind of ugly but it works. The rule for msvc looks much much more ugly
exe foo : $(IMPORTANT_PART) $(TEST_UTILITY_PART) : <toolset>msvc <linkflags>/LIBPATH:../../libs/gtest-1.6.0/libs <linkflags>/DEFAULTLIB:gtest_main-mdd.lib
<linkflags>/DEFAULTLIB:gtestd-md.lib
;
Is there more natural way to link target with external static library in boost.build project file.
P.S. Of cource using google-test and boost mix smells not good, but anyway there are a lot of external libraries that cover areas boost doesn't cover.
TIA
Great! Thank the persond who pointed me http://www.boost.org/boost-build2/doc/html/bbv2/tutorial/prebuilt.html page. (the comment disappeared) It seems to be, I did read this page not carefully. And target lib with file property does the thing I searched for. Thanks!
As for using google test and boost build I did this way: I made Jamfile for google-test. It is very simple:
gtest.lib/Jamfile
project gtest_main
: requirements <include>../../../libs/gtest-1.6.0/include
<include>../../../libs/gtest-1.6.0/
: source-location ../../../libs/gtest-1.6.0
: build-dir ../../../libs/gtest-1.6.0/bin.b2 ;
lib gtest_main : src/gtest_main.cc src/gtest-all.cc : <link>static ;
Then, somewhere in my project file:
use-project /gtest : ./gtest.lib ;
and mentioning //gtest in project's requirements section.