I'm trying to use GTKMM with a project which makes use of C++11 features.
The problem is that apparently C++11 deprecated some parts of the language, which GTKMM seems to be using.
Is there any way to get rid of those messages while keeping the useful compiler warnings for my code?
The compiler is GCC 5.2 on Linux. These are the notices I'm talking about:
In file included from /usr/include/glibmm-2.4/glibmm/wrap.h:23:0,
from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:26,
from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23,
from /usr/include/glibmm-2.4/glibmm.h:91,
from /usr/include/gtkmm-3.0/gtkmm.h:87,
from test.cpp:1:
/usr/include/glibmm-2.4/glibmm/objectbase.h:215:13: warning: ‘template<class> class std::auto_ptr’ is deprecated [-Wdeprecated-declarations]
static std::auto_ptr<Threads::Mutex> extra_object_base_data_mutex;
^
In file included from /usr/include/c++/5.2.0/memory:81:0,
from /usr/include/glibmm-2.4/glibmm/objectbase.h:32,
from /usr/include/glibmm-2.4/glibmm/wrap.h:23,
from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:26,
from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23,
from /usr/include/glibmm-2.4/glibmm.h:91,
from /usr/include/gtkmm-3.0/gtkmm.h:87,
from test.cpp:1:
/usr/include/c++/5.2.0/bits/unique_ptr.h:49:28: note: declared here template<typename> class auto_ptr;
In case its something wrong with the compiler parameters, here's the CMakeLists ( was reused from an OpenCV project, please tell in case there is something wrong in the file):
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
list( APPEND CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs -libs")
project( interface )
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTKMM REQUIRED gtkmm-3.0)
include_directories(${GTKMM_INCLUDE_DIRS})
link_directories(${GTKMM_LIBRARY_DIRS})
add_definitions(${GTKMM_CFLAGS_OTHER})
add_executable( interface test.cpp )
target_link_libraries(interface ${GTKMM_LIBRARIES})
We fixed this in glibmm fairly recently:
https://bugzilla.gnome.org/show_bug.cgi?id=748630#c11
So the best way to fix it for your build is to update your glibmm and gtkmm versions, when you can.
Just a dirty hack (because probably the usage of auto_ptr inside GTKMM is questionable so you want to report a bug to GTKMM); you might use some diagnostic pragmas and replace #include <gtkmm.h> with
//untested code
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <gtkmm.h>
#pragma GCC diagnostic warning "-Wdeprecated-declarations"
But auto_ptr is indeed deprecated in C++11 and I am not sure it mixes well with your C++11 standard library.
(Perhaps using Qt5 instead of GtkMM might be reasonable, since GtkMM might not be maintained for long, however it seems to know the issue; otherwise hope and perhaps contribute to improving GtkMM).
You probably should also use valgrind in your tests
Related
My goal is to understand a GNU libraries autoconf build system. I am aware that libiconv can be build successfully using a crafted MS Visual Studio project with manully added source code files. So the question is more academical rather than practical. I took into account there is no official support of Windows platform for gnulib also.
Following the guide from INSTALL.windows to build libiconv, I faced with next compilation error when built iconv againts dynamic MSVC runtime(cl /MD or cl /MDd).
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_malloc.h(85): error C2375: 'rpl_free': redefinition; different linkage
D:\work\env\build-env\msvc2019\shared-debug-shared-runtime\iconv\srclib\string.h(599): note: see declaration of 'rpl_free'
Configure invocation:
/cygdrive/d/work/src/libiconv/configure --enable-relocatable --enable-static=no --enable-shared=yes --host=x86_64-w64-mingw32 --prefix=/iconv 'CFLAGS=/MDd /Z7 /Od /D_DEBUG /RTC1' 'CXXFLAGS=/MDd /Z7 /Od /D_DEBUG /RTC1'
Compiler invocation:
compile cl /nologo -DHAVE_CONFIG_H -DEXEEXT=\".exe\" -I. -I/cygdrive/d/work/src/libiconv/srclib -I.. -I../lib -DDEPENDS_ON_LIBICONV=1 -DDEPENDS_ON_LIBINTL=1 /D_WIN32_WINNT=_WIN32_WINNT_WIN7 /DWIN32 /D_WIN64 /D_UNICODE /D_CRT_SECURE_NO_WARNINGS /MDd /Z7 /Od /D_DEBUG /RTC1 /D_DLL -c -o stat.obj `cygpath -w '/cygdrive/d/work/src/libiconv/srclib/stat.c'`
stat.c
Configure generated iconv/srclib/string.h
/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
_GL_EXTERN_C void free (void *);
#if 1
# if (1 && !defined free \
&& !(defined __cplusplus && defined GNULIB_NAMESPACE))
# define free rpl_free
_GL_EXTERN_C void free (void *);
# endif
#endif
WinSDK/include/ucrt/corecrt_malloc.h
_ACRTIMP _CRT_HYBRIDPATCHABLE
void __cdecl free(
_Pre_maybenull_ _Post_invalid_ void* _Block
);
WinSDK/include/ucrt/corecrt.h defines next
#ifndef _ACRTIMP
#if defined _CRTIMP && !defined _VCRT_DEFINED_CRTIMP
#define _ACRTIMP _CRTIMP
#elif !defined _CORECRT_BUILD && defined _DLL
#define _ACRTIMP __declspec(dllimport)
#else
#define _ACRTIMP
#endif
#endif
After research and investigation I found out that gnulib(as a part of GNU autoconf build system for libiconv) replaces unsatisfying function calls with its own implementation.
rpl_free is a replacement name to replace regular free() function from the C runtime as MSVC free function is not recognized as a POSIX compliant. It seems to me there is no option to tell to configure not to replace suck functions.
An hack with environment variable REPLACE_FREE=0 did the trick and I have turned off function replacement.
However, MSVC compiler still complaints on different linkage. I believe, MSVC runtime exports its API functions with __declspec(dllimport) for consumers when gnulib declares its free() function signature with no extra attributes.
I wonder, is there a 'paved-road' to build libiconv(or other GNU library that leverage gnulib) linked to dynamic MSVC runtime using original autoconf system? Can I achieve that with no gnulib m4 files alteration?
To answer your general question:
Yes, GNU projects with the GNU build system (Autoconf, optionally Automake, Libtool, and Gnulib) can in general be built with the MSVC compiler. The compile script translates compiler options in the traditional Unix style to compiler options for MSVC.
The experience with GNU libiconv, GNU gettext, and other packages, which all have essentially the same INSTALL.windows instructions, shows that this is well possible. But it often requires tweaks in the build system, to cope with dllimport/dllexport, issues related to backslashes, to file names in Cygwin syntax vs. native Windows syntax, and so on. In particular, note that on Windows, it is hairy to export variables from a shared library; exporting functions is much simpler.
You can typically ignore warnings from MSVC regarding the dllimport/dllexport of functions. This warning merely means that the compiler has added one or two extra instructions per function invocation.
Gnulib indeed overrides many libc functions, such as free(), so that the application source code does not get cluttered with workarounds. The precise reason for each override is documented. For the free() function, it is documented here. While Gnulib has ways to disable specific workarounds, in this case I would strongly advise against it: the effects of a wrong errno value can be severe malfunction of any application.
To answer your specific problem about GNU libiconv:
You have encountered a specific build problem; the README of the package tells you where to report bugs.
GNU packages have releases. The latest GNU libiconv release, version 1.16, does not have the problem. In general, before attempting to compile the newest sources from the git repository, it is advisable to use the newest release. This will be simpler, as it has usually been tested before the release.
I am using an inline global variable which works well for the purpose of it.
class MyClass {
public:
void Func() {
}
}
inline MyClass myClass; // global inline variable
Above works well for my purpose but I get a warning when my code compiles on gcc with compiler below C++17. Following is the warning
warning: inline variables are only available with -std=c++1z or
-std=gnu++1z
Question:
How can I suppress the warning on gcc?
I tried to suppress the warning by using a #pragma like below
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++17-extensions"
inline MyClass myClass;
#pragma GCC diagnostic pop
Above #pragma technique works on clang, but looks like GCC to not understand the #pragma? I just want to brute force suppress the warning on GCC. How can I do that?
Looks like gcc warning options list does not even mention about this?
https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
I am using gcc (GCC) 7.3.0
To understand why you cannot suppress this warning, look at what happens if the code is compiled with a compiler that does not support inline variables. (Inline variable support started with gcc 7.) Older versions of gcc process your code and spit out error: 'myClass' declared as an 'inline' variable. Not a warning, but an unsuppressible error. Hard stop; object code not produced.
Newer versions of gcc are able to be more understanding and helpful, but at the same time they have an obligation to maintain some degree of compatibility with older compilers. These newer compilers can recognize this C++17 feature, and it's been determined that ignoring "inline" downgrades the error to a warning (compilation does not necessarily need to stop). Furthermore, the message was given information about how to resolve this situation (assuming the code is correct). At the same time, this warning is still essentially the error produced by older versions of gcc, just given a makeover to make it more user-friendly. It cannot be suppressed any more than the old error could. Your choices are to write valid pre-17 code or to enable C++17 features.
**Edit: Found my problem. As explained by the following answer, I was not actually doing any linking when making the static library. Instead, I made a shared library and linked libstdc++ statically.
Compile a static library link with standard library (static)**
I am trying to create a method to use c++11 on an ancient arm platform running kernel (2.6.37). Unfortunately the latest cross compile our BSP contains is GCC 4.5.3, which does not support all the c++11 utilites we need.
Initially I tried to use old versions of crosstool-ng to build a cross compiler, but the older versions were too broken. The newer versions did not support the 2.6.37 kernel. I was able to complete one build, however the g++ binary was not built, making the whole endeavor useless (I did check that c++ was enabled in the menuconfig).
Thus my last option was to build gcc natively at version 4.9.4 and create a statically linked library to have my gcc 4.5.3 cross compiler link against. This seems to work for the most part. I create my library on the target with the following:
g++ -std=c++11 --static -c main2.cpp
ar -cvq libmain2.a main2.o
I then copy over the files and try build on the host machine with gcc 4.5.3 and get the following:
arm-angstrom-linux-gnueabi-g++ simple.cpp -lmain2 -L.
(I cleaned up some of the output)
undefined reference to `std::_Hash_bytes(void const*, unsigned int, unsigned int)'
undefined reference to
std::__throw_regex_error(std::regex_constants::error_type)'
However, when I use nm, I get the following:
$ arm-angstrom-linux-gnueabi-nm libmain2.a | grep Hash_bytes
U _ZSt11_Hash_bytesPKvjj
U _ZSt11_Hash_bytesPKvjj
$ arm-angstrom-linux-gnueabi-nm libmain2.a | grep throw_regex
U _ZSt19__throw_regex_errorNSt15regex_constants10error_typeE
U _ZSt19__throw_regex_errorNSt15regex_constants10error_typeE
Does anyone know what the heck is going on? Unfortunately we need to be able to use our cross compiler on the host system for most work, but we are also needing to integrate this specific library which uses c++11.
Also note that if I take out the regex and hash functionality from my code but leave other c++11 concepts like nullptr, type inference, delegation etc, the code compiles and runs on the target fine.
Edit: Okay, so after a little more investigation, it looks like the functions _Hash_bytes and __throw_regex_error are not being statically linked into the static library. I guess I need to know why this is the case in order to fix the issue.
My cmake project shall compile c++14 code. It also uses the CMakeLists.txts included from its external libraries (which are git submodules in my project). The build fails on macOS Sierra (cmake 3.6.2) because the default STL of clang is old and doesn't handle c++11. As far as I understand, there are two STLs shipped with clang: libstdc++ (from gcc) (default) or libc++. So if I add the -stdlib=libc++ option to cmake, the source compiles:
add_compile_options( "$<$<COMPILE_LANGUAGE:CXX>:-std=c++14>" )
add_compile_options( "$<$<COMPILE_LANGUAGE:CXX>:-stdlib=libc++>" )
But then it fails at link time because it tries to use libstdc++ for linking. How do I specify in cmake that the new STL libc++ shall be used for the whole build process?
PS: What is the rationale behind clang using the gcc STL by default if it is too old? Could I permanently specify which STL it shall use? Or am I doing something completely wrong (could some of my subprojects silently force gcc?)?
You should rely on CMake to handle compile options. Just specify the wanted standard version:
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
target_compile_features can also be used to require particular features of the standard (and implicitly ask CMake to set the adequate configuration). More information here.
EDIT
You figured out the solution, you also had to remove the following line in the CMakeLists of Ogred3D:
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7)
Removing it prevented CMake to add the flag mmacosx-version-min=10.7 causing the error.
I suppose, you also need to pass that flang to the linker in the clang case:
link_libraries("-stdlib=libc++")
I just restarted working on a project which has been on hold for a few months. Last time I compiled it it was working just fine, without any error nor warning.
Yet when I tried to compile it earlier today I got this warning
attention : ‘template<class _Operation> class std::binder2nd’ is deprecated [-Wdeprecated-declarations]
This warning literally appears hundreds of time when including Eigen/Geometry, which I use all over my project
In file included from [...]/include/Eigen/src/Core/ArrayBase.h:109:0,
from [...]/include/Eigen/Core:350,
from [...]/include/Eigen/Geometry:4,
from [...]/include/[myproject]/types.hh:8,
from [...]/include/[myproject]/voronoi.hh:8
Since then I haven't updated Eigen (is used 3.2.4 which is still the last update today).
However, since last time I compiled it, GCC has been updated to 5.1.0 (I'm using archlinux)
Question:
Is there an issue with gcc 5.1.0 telling me std::binder2nd is deprecated
Should Eigen be updated ?
How can I silent those specific warning without loosing the verbosity of my build ?
ANSWER
I appreas that std::bind2nd is really deprecated and that a commit has been done to solve that in Eigen. This commit is however not yet merged with the master branch :/ (and doesn't solve the issue as some std::bind2nd are still present in Eigen's code)
Bottom line is: Eigen's last stable version is deprecated
Is there an issue with gcc 5.1.0 telling me std::binder2nd is deprecated
No, the C++ standard says it's deprecated in C++11, so if you compile in C++11 mode then it is supposed to be deprecated.
Should Eigen be updated ?
Yes. if it wants to be C++17 compatible, as std::bind2nd doesn't exist post-C++14 at all.
How can I silent those specific warning without loosing the verbosity of my build ?
Suppress the warning. Either compile with -Wno-deprecated-declarations on the command-line or do it in the source when including the Eigen headers:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <eigen/whatever.h>
#pragma GCC diagnostic pop
Or, as the other answer says, tell GCC to treat the Eigen headers as system headers, which happens automatically if they are in /usr/include, or are included with -isystem, or are included from another header that does:
#pragma GCC system_header
#include <eigen/whatever.h>
How can I silent those specific warning without loosing the verbosity ?
Edit the CMakeLists.txt file. Add this line somewhere after CMAKE_CXX_FLAGS is set.
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
Previous answer mentioned adding this to #pragma or to command line. I am biased against #pragma because I find it hard later on to remember where I put it. So as general practice, I try to avoid #pragma. Adding to command line means you have to remember to type this everytime you recompile.
Instead of using the -I flag to include files use -isystem to include Eigen headers:
g++-5 -isystem/usr/include/eigen3 source_file_here.cpp
This flag is intended for system headers that don't conform to C standards but are considered false positives when warnings are generated. Eigen headers are used much like system headers and thus for most users the warnings are not helpful but merely an annoying false positive.
Credit goes to Ilya Popov's comment in the original question.