CMake fails to compile with GCC 6.3 - gcc

CMake fails to bootstrap with GCC 6.3 installed.
The tests checking for a C++ compiler fail due to not finding stdlib.h and iostream.h which were removed in GCC 5.
Output of Bootstrap.cmk/cmake_bootstrap.log:
Try: cc
Line: cc cmake_bootstrap_39083_test.c -o cmake_bootstrap_39083_test
---------- file -----------------------
#ifdef __cplusplus
# error "The CMAKE_C_COMPILER is set to a C++ compiler"
#endif
#include<stdio.h>
#if defined(__CLASSIC_C__)
int main(argc, argv)
int argc;
char* argv[];
#else
int main(int argc, char* argv[])
#endif
{
printf("%d%c", (argv != 0), (char)0x0a);
return argc-1;
}
------------------------------------------
1
Test succeeded
Try: g++
Line: g++ -DTEST1 cmake_bootstrap_39083_test.cxx -o cmake_bootstrap_39083_test
---------- file -----------------------
#if defined(TEST1)
# include <iostream>
#else
# include <iostream.h>
#endif
class NeedCXX
{
public:
NeedCXX() { this->Foo = 1; }
int GetFoo() { return this->Foo; }
private:
int Foo;
};
int main()
{
NeedCXX c;
#ifdef TEST3
cout << c.GetFoo() << endl;
#else
std::cout << c.GetFoo() << std::endl;
#endif
return 0;
}
------------------------------------------
In file included from /usr/include/c++/6.3.0/ext/string_conversions.h:41:0,
from /usr/include/c++/6.3.0/bits/basic_string.h:5402,
from /usr/include/c++/6.3.0/string:52,
from /usr/include/c++/6.3.0/bits/locale_classes.h:40,
from /usr/include/c++/6.3.0/bits/ios_base.h:41,
from /usr/include/c++/6.3.0/ios:42,
from /usr/include/c++/6.3.0/ostream:38,
from /usr/include/c++/6.3.0/iostream:39,
from cmake_bootstrap_39083_test.cxx:3:
/usr/include/c++/6.3.0/cstdlib:75:25: fatal error: stdlib.h: No such file or directory
#include_next <stdlib.h>
^
compilation terminated.
Test failed to compile
Try: g++
Line: g++ -DTEST2 cmake_bootstrap_39083_test.cxx -o cmake_bootstrap_39083_test
---------- file -----------------------
#if defined(TEST1)
# include <iostream>
#else
# include <iostream.h>
#endif
class NeedCXX
{
public:
NeedCXX() { this->Foo = 1; }
int GetFoo() { return this->Foo; }
private:
int Foo;
};
int main()
{
NeedCXX c;
#ifdef TEST3
cout << c.GetFoo() << endl;
#else
std::cout << c.GetFoo() << std::endl;
#endif
return 0;
}
------------------------------------------
cmake_bootstrap_39083_test.cxx:5:23: fatal error: iostream.h: No such file or directory
# include <iostream.h>
^
compilation terminated.
Test failed to compile
Try: g++
Line: g++ -DTEST3 cmake_bootstrap_39083_test.cxx -o cmake_bootstrap_39083_test
---------- file -----------------------
#if defined(TEST1)
# include <iostream>
#else
# include <iostream.h>
#endif
class NeedCXX
{
public:
NeedCXX() { this->Foo = 1; }
int GetFoo() { return this->Foo; }
private:
int Foo;
};
int main()
{
NeedCXX c;
#ifdef TEST3
cout << c.GetFoo() << endl;
#else
std::cout << c.GetFoo() << std::endl;
#endif
return 0;
}
------------------------------------------
cmake_bootstrap_39083_test.cxx:5:23: fatal error: iostream.h: No such file or directory
# include <iostream.h>
^
compilation terminated.
Test failed to compile
Update:
The issue could be resolved changing the following line in cstdlib:
#include_next <stdlib.h>
To:
#include <stdlib.h>

Related

How to prevent accidental emission of constexpr functions

Ben Deane mentions the throw trick, which ensures a link error when a constexpr function is used in a non-constexpr context.
Here is my take:
#include <iostream>
struct Exc;
constexpr int foo( int a )
{
if( a == 42 )
{
throw Exc{};
}
return 666;
}
int main()
{
constexpr auto ret = foo(43);
std::cout << ret << "\n";
return ret;
}
But I couldn't make it work (clang++ 3.8.1-23 and g++ 6.3.0):
$ clang++ -std=c++14 main.cpp
main.cpp:9:15: error: invalid use of incomplete type 'ExcBase'
throw ExcBase{};
^~~~~~~~~
main.cpp:3:8: note: forward declaration of 'ExcBase'
struct ExcBase;
^
1 error generated.
A comment in this thread suggests another trick:
#include <iostream>
constexpr int foo( int a )
{
if( a == 42 )
{
(void)reinterpret_cast<int>(a);
}
return 666;
}
int main()
{
constexpr auto ret = foo(43);
std::cout << ret << "\n";
return ret;
}
Which works: no errors or warnings; when the invocation is replaced with foo(42), clang returns:
$ clang++ -std=c++14 main.cpp
main.cpp:19:20: error: constexpr variable 'ret' must be initialized by a constant expression
constexpr auto ret = foo(42);
^ ~~~~~~~
main.cpp:10:15: note: reinterpret_cast is not allowed in a constant expression
(void)reinterpret_cast<int>(a);
^
main.cpp:19:26: note: in call to 'foo(42)'
constexpr auto ret = foo(42);
^
1 error generated.
Which is great. But gcc compiles the code happily in both cases. And now the question. How can a constexpr function be written in such a way, that it cannot be used in non-constexpr environments?
The problem is you actually instantiate (call constructor) a struct which is of incomplete type. This trick you talk about requires any symbol which will not be found at link time. So instead of struct you may use int:
http://coliru.stacked-crooked.com/a/3df5207827c8888c
#include <iostream>
extern int Exc;
constexpr int foo( int a )
{
if( a == 42 )
{
throw Exc;
}
return 666;
}
int main()
{
// Compiles
constexpr auto ret = foo(43);
std::cout << ret << "\n";
// This will show linker error as expected:
// /tmp/ccQfT6hd.o: In function `main':
// main.cpp:(.text.startup+0x4c): undefined reference to `Exc'
// collect2: error: ld returned 1 exit status
int nn;
std::cin >> nn;
auto ret2 = foo(nn);
return ret;
}

Issues with Inheritance and OpenCL

I am trying to port some code to linux from Windows. I have gotten pretty far, but now I am stuck on an error with inheritance. But I can't figure out what's not working. It appears that It's not importing the header, but I can't figure out why because it seems to me that is should be working.
here is the error output:
/usr/bin/c++ -DHAVE_CLOGS -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NO_DEBUG -DQT_WIDGETS_LIB -std=c++11 -I/code/cuda/JF-Cut/src/build -I/code/cuda/JF-Cut/src/QVisualizer -I/code/cuda/clogs-install/include -I/usr/local/cuda-7.5/targets/x86_64-linux/include -isystem /opt/Qt/5.5/gcc_64/include -isystem /opt/Qt/5.5/gcc_64/include/QtWidgets -isystem /opt/Qt/5.5/gcc_64/include/QtGui -isystem /opt/Qt/5.5/gcc_64/include/QtCore -isystem /opt/Qt/5.5/gcc_64/./mkspecs/linux-g++ -fPIC -o CMakeFiles/QGCWidget.dir/Graph_Cut/QGCWidget.cpp.o -c /code/cuda/JF-Cut/src/QVisualizer/Graph_Cut/QGCWidget.cpp
In file included from /code/cuda/JF-Cut/src/QVisualizer/Graph_Cut/QGCWidget.cpp:44:0:
/code/cuda/JF-Cut/src/QVisualizer/Graph_Cut/../infrastructures/QError.h:45:11: error: ‘cl::Error’ has not been declared
using cl::Error;
^
/code/cuda/JF-Cut/src/QVisualizer/Graph_Cut/../infrastructures/QError.h:48:1: error: expected class-name before ‘{’ token
{
^
/code/cuda/JF-Cut/src/QVisualizer/Graph_Cut/../infrastructures/QError.h: In member function ‘void QError::serialize(std::ostringstream&, cl_int)’:
/home/sansomk/code/cuda/JF-Cut/src/QVisualizer/Graph_Cut/../infrastructures/QError.h:68:13: error: ‘cl::Error’ has not been declared
cl::Error::serialize(s, code);
Here is the Code for QError.h
#ifndef QERROR_H
#define QERROR_H
#ifndef __CL_ENABLE_EXCEPTIONS
#define __CL_ENABLE_EXCEPTIONS
#endif
// removed #include "../3rdParty/cl/cl_stacktrace.hpp"
#if defined(__APPLE__) || defined(__MACOSX)
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.hpp>
#endif
#define Q_LOGIC_ERROR -100
#define Q_INVALID_ARGUMENT -101
#define Q_LENGTH_ERROR -102
#define Q_OUT_OF_RANGE -103
#define Q_FUTURE_ERROR -104
#define Q_RUNTIME_ERROR -110
#define Q_RANGE_ERROR -111
#define Q_OVERFLOW_ERROR -112
#define Q_UNDERFLOW_ERROR -113
#define Q_SYSTEM_ERROR -114
using cl::Error;
class QError : public cl::Error
{
protected:
cl_int level_;
void serialize(std::ostringstream& s, cl_int code)
{
std::string error;
switch (code)
{
case Q_LOGIC_ERROR: error = "Q_LOGIC_ERROR"; break;
case Q_INVALID_ARGUMENT: error = "Q_INVALID_ARGUMENT"; break;
case Q_LENGTH_ERROR: error = "Q_LENGTH_ERROR"; break;
case Q_OUT_OF_RANGE: error = "Q_OUT_OF_RANGE"; break;
case Q_FUTURE_ERROR: error = "Q_FUTURE_ERROR"; break;
case Q_RUNTIME_ERROR: error = "Q_RUNTIME_ERROR"; break;
case Q_RANGE_ERROR: error = "Q_RANGE_ERROR"; break;
case Q_OVERFLOW_ERROR: error = "Q_OVERFLOW_ERROR"; break;
case Q_UNDERFLOW_ERROR: error = "Q_UNDERFLOW_ERROR"; break;
case Q_SYSTEM_ERROR: error = "Q_SYSTEM_ERROR"; break;
}
if (!error.empty()) s << " > " << error << ", ";
cl::Error::serialize(s, code);
}
public:
QError(cl_int level, cl_int err, const char * errStr = NULL) : level_(level), cl::Error(err, errStr) {}
~QError() throw() {}
cl_int level(void) const { return level_; }
virtual const char * what() throw ()
{
std::ostringstream s;
serialize(s, err_);
errStr_ = s.str();
return errStr_.c_str();
}
};
#endif // QERROR_H
In order to use cl::Error you need to define __CL_ENABLE_EXCEPTIONS.
I can see you have it there, but that file is a header file. If you include OpenCL headers somewhere else earlier in the compilation unit (.cpp) without defining __CL_ENABLE_EXCEPTIONS. Then the later includes will simply skip (due to ifdefs in the header file to avoid multiple instances of the same .h file).
What you should do for these types of global compilation defines, is declare them in the command line.
g++ ... -D__CL_ENABLE_EXCEPTIONS
That way you ensure the defines are enabled at the very beginning of the compilation.

serialize temporary into boost archive

The following is not possible for any boost output archive:
int foo(){
return 4;
}
ar << static_cast<unsigned int>(foo());
Is there an alternative without out creating a local temporary x=foo().
and why is the underlying archive operator <<(T & t) not const reference , for an output archive such that the above would work?
This seems to work, and I think this is why:
... To help detect such cases, output archive operators expect to be
passed const reference arguments.
It seems worth noting that in your example ar << foo(); does not work either (i.e. it doesn't have to do with your cast).
#include <fstream>
#include <iostream>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
unsigned int foo(){
return 4;
}
int main()
{
{
std::ofstream outputStream("someFile.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << static_cast<const int&>(foo());
}
std::ifstream inputStream("someFile.txt");
boost::archive::text_iarchive inputArchive(inputStream);
int readBack;
inputArchive >> readBack;
std::cout << "Read back: " << readBack << std::endl;
return 0;
}

how to use boost log from multiple files with Gloa

I am trying to create a Global Logger within my entire application so I can use
src::severity_logger_mt< >& lg = my_logger::get();
to get the global logger for different classes (resided in different files) logging.
I try to follow the example listed in boost.org (as listed below). But does not seems to work. Did anyone know any example I can follow or what I need to do make if works. Thanks.
http://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/log/detailed/sources.html
BOOST_LOG_GLOBAL_LOGGER(my_logger, src::severity_logger_mt)
// my_logger.h
// ===========
#include "my_logger.h"
BOOST_LOG_GLOBAL_LOGGER_INIT(my_logger, src::severity_logger_mt)
{
src::severity_logger_mt< > lg;
lg.add_attribute("StopWatch", boost::make_shared< attrs::timer >());
return lg;
}
// my_logger.cpp
// ===========
#include "my_logger.h"
BOOST_LOG_GLOBAL_LOGGER_INIT(my_logger, src::severity_logger_mt)
{
src::severity_logger_mt< > lg;
lg.add_attribute("StopWatch", boost::make_shared< attrs::timer >());
return lg;
}
I've just managed to get this working myself
Logging.h
#pragma once
#include <boost/log/expressions.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup.hpp>
#define INFO BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::info)
#define WARN BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::warning)
#define ERROR BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::error)
#define SYS_LOGFILE "/var/log/example.log"
//Narrow-char thread-safe logger.
typedef boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> logger_t;
//declares a global logger with a custom initialization
BOOST_LOG_GLOBAL_LOGGER(my_logger, logger_t)
Logging.cpp
#include "Logging.h"
namespace attrs = boost::log::attributes;
namespace expr = boost::log::expressions;
namespace logging = boost::log;
//Defines a global logger initialization routine
BOOST_LOG_GLOBAL_LOGGER_INIT(my_logger, logger_t)
{
logger_t lg;
logging::add_common_attributes();
logging::add_file_log(
boost::log::keywords::file_name = SYS_LOGFILE,
boost::log::keywords::format = (
expr::stream << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
<< " [" << expr::attr< boost::log::trivial::severity_level >("Severity") << "]: "
<< expr::smessage
)
);
logging::add_console_log(
std::cout,
boost::log::keywords::format = (
expr::stream << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
<< " [" << expr::attr< boost::log::trivial::severity_level >("Severity") << "]: "
<< expr::smessage
)
);
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::info
);
return lg;
}
main.c
#include "Logging.h"
int main(int argc, char **argv)
{
INFO << "Program started";
return 0;
}
My build settings
AM_LDFLAGS += -lboost_system -lboost_thread -lpthread
AM_LDFLAGS += -DBOOST_LOG_DYN_LINK -lboost_log_setup -lboost_log
AM_CXXFLAGS += -std=c++11 -DBOOST_LOG_DYN_LINK

Taking decltype of main

Trying to invoke hi or std::move on it results in this:
/tmp/cch3DRvH.o: In function `main':
main.cpp:(.text.startup+0x5): undefined reference to `hi(int, char**)'
collect2: error: ld returned 1 exit status
#include <type_traits>
#include <utility>
#include <iostream>
#include <typeinfo>
#include <functional>
int main(int argc, char* argv[])
{
decltype(main) hi;
decltype(main) hi2;
// std::function<int(int, char**)> hi2 = std::move(hi);
// hi(argc, argv);
std::cout << std::boolalpha;
std::cout << std::is_same<decltype(main), decltype(hi)>::value << std::endl;
std::cout << std::is_function<decltype(main)>::value << std::endl;
std::cout << std::is_function<decltype(hi)>::value << std::endl;
std::cout << std::is_same<decltype(std::move(main)), decltype(std::move(hi))>::value << std::endl;
std::cout << std::is_same<decltype(hi2), decltype(hi)>::value << std::endl;
return 0;
}
Output:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:16:54: warning: ISO C++ forbids taking address of function ‘::main’ [-Wpedantic]
std::cout << std::is_same<decltype(std::move(main)), decltype(std::move(hi))>::value << std::endl;
main.cpp:16:54: warning: ISO C++ forbids taking address of function ‘::main’ [-Wpedantic]
true
true
true
true
true
It seems hi is almost the same as main except it doesn't give warnings like when using std::cout << hi. Is it possible to get this program to not output undefined reference tohi(int, char**)'`?
decltype(main) is an alias for the type int(int, char **). You have declared a function hi with this type but did not define it.
To get rid of the undefined reference error, just define the function:
int hi( int, char ** ) {
return 0;
}
The messages that appear before true are not output from your program but from the compiler.

Resources