I'm using boost 1.53.0, and have had no problems up to this point (and have used sockets, timers, containers, algorithm, all without trouple).
I love the idea of using boost exceptions, especially because of the line number and what not.
however, in my (super simple) code:
#include <iostream>
#include <fstream>
#include <boost/scoped_ptr.hpp>
#include <boost/exception/all.hpp>
struct my_error: virtual boost::exception, virtual std::exception { };
int main(int argc, char* argv[])
{
try
{
BOOST_THROW_EXCEPTION(my_error());
}
catch(...)
{
std::cout <<"fail";
}
}
Project generated with CMAKE (hopefully that's not screwing it up)
cmake_minimum_required (VERSION 2.8)
project(error_test)
IF(WIN32)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(Boost_NO_SYSTEM_PATHS FALSE)
ENDIF()
find_package(Boost COMPONENTS system date_time)
include_directories(${Boost_INCLUDE_DIRS}
)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME}
${Boost_LIBRARIES})
Instead of throwing, BOOST_THROW_EXCEPTION enters an infinite recursion!
The compiler even catches this, stating a compiler warning
warning C4717: 'boost::exception_detail::throw_exception_' : recursive on all control paths, function will cause runtime stack overflow.
and it just keeps hitting:
test.exe!boost::exception_detail::throw_exception_<my_error>(const my_error & x, const char * current_function, const char * file, int line) Line 84 + 0xd1 bytes C++
I am using visual studio 2010 (win 64). I built boost using the following command, if that helps:
.\b2 install --prefix=C:\devtools\boost_1_53_0 --toolset=msvc --build-type=complete --build-dir=C:\devtools\bin\boost_1_53_0 address-model=64 architecture=x86
EDIT Adding expanded macros:
looks like the macro expands to
::boost::exception_detail::throw_exception_(my_error(), __FUNCSIG__ ,"main.cpp",40);
which expands to
throw_exception_( E const & x, char const * current_function, char const * file, int line )
{
::boost::exception_detail::throw_exception_(set_info( set_info( set_info( enable_error_info(x), throw_function(current_function)), throw_file(file)), throw_line(line)), __FUNCSIG__ ,"C:\\devtools\\boost_1_53_0\\boost/throw_exception.hpp",91);
#line 92 "C:\devtools\boost_1_53_0\boost/throw_exception.hpp"
}
That's just plain weird. As you can easily check at https://svn.boost.org/svn/boost/tags/release/Boost_1_53_0/boost/throw_exception.hpp boost::exception::throw_exception_ is not not recursive at all.
The only way I can see such a thing happening is with evil macros. Please try putting this in your main file, before and after every include directive.
#if defined(throw_exception) || defined(throw_exception_)
#error Somebody set us up the bomb
#endif
OK, so it looks like for some reason
throw_exception_( E const & x, char const * current_function, char const * file, int line )
{
boost::throw_exception(
set_info(
set_info(
set_info(
enable_error_info(x),
throw_function(current_function)),
throw_file(file)),
throw_line(line)));
}
was changed to
throw_exception_( E const & x, char const * current_function, char const * file, int line )
{
BOOST_THROW_EXCEPTION(
set_info(
set_info(
set_info(
enable_error_info(x),
throw_function(current_function)),
throw_file(file)),
throw_line(line)));
}
in my code...so I must have broken my own boost build. Sorry about the wild goose chase! I voted to close this thread...
Related
I am using Windows 10 and CMake to build my project (using MinGW Makefiles as the generator), while choosing Clang/Clang++ (LLVM) as my compiler due to my Language Server Protocol also being for Clang.
However, when trying to link a static library I had created to my main executable, none of the definitions in the translation units were able to be resolved.
For a simple recreation:
File system
+ root/
+ main.cpp
+ foobar.cpp
+ foobar.hpp
+ CMakeLists.txt
// main.cpp
#include <iostream>
#include "foobar.hpp"
int main( int argc, char** argv ) {
foo();
std::cin.get();
return 0;
}
// foobar.cpp
#include "foobar.hpp"
void foo() {
std::cout << "bar" << std::endl;
}
// foobar.hpp
#pragma once
#ifndef FOOBAR_HEADER_H
#define FOOBAR_HEADER_H
#include <iostream>
void foo();
#endif
# CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(linker_fail
VERSION 1.0.0
LANGUAGES C CXX)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_library(foobar
foobar.cpp
foobar.hpp)
add_executable(${PROJECT_NAME}
main.cpp)
target_link_libraries(${PROJECT_NAME} PUBLIC
foobar)
Then for building:
root> cmake -S . -B bin -G "MinGW Makefiles"
root> cmake --build bin
lld-link: error: undefined symbol: void __cdecl foo(void)
Does anyone know how to fix this? Should I have passed some arguments to the compiler/linker? Or does Clang just not allow static linking?
I want to build a simple application based on a .cpp and a .h file.
I couldn't make my project work so i started from a basic example but didn't succeed as i'm just starting creating project in Linux. From what i've seen, my CMakeLists should be like this :
My CMakeLists.txt :
cmake_minimum_required(VERSION 3.5)
set(CMAKE_CXX_STANDARD 11)
project(test C CXX)
add_executable(${PROJECT_NAME} main_new.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
My main_new.cpp :
#include <read.h>
int main(int argc, char* argv[])
{
int a, b, c, d, e = 0;
std::cout << "hello im example " << std::endl;
read_int(&a, &b, &c, &d, &e);*
return 0;
}
My read.h :
#ifdef __cplusplus
extern "C" {
#endif
int read_int(int *vectorA, int *vectorB, int *matrixA, int *matrixB, int *flags);
#ifdef __cplusplus
}
#endif
My .cpp and .h file are in the same folder. cmake . is giving me no error, but after using make i get
main_new.cpp:(.text+0x68) : undefined reference to « read_int »
I'm using the makefile created by the cmake command. Should i create a custom makefile ?
Edit : Added question :
I also have to implement .so files, but doing target_link_libraries(test ${CMAKE_SOURCE_DIR}/libA.so ${CMAKE_SOURCE_DIR}/libB.so) in my CMakeLists.txt file doesn't work. How can i link these libraries to my executable ?
This is my C++ code:
#include "stdlib.h"
#include "stdio.h"
#include <iostream>
int main(int argc, char *argv[] ) {
int width, height;
unsigned char *rgba;
FILE *fp = fopen("/home/pic.tif", "rb");
if(!fp)
std::cout<<"failed"<<std::endl;
rgba = floadtiff(fp, &width, &height);
fclose(fp);
if(rgba == 0)
printf("TIFF file unreadable\n");
}
I am using this library by #MalcolmMcLean, and that's what my loadtiff.c is.I have compiled it using gcc and am trying to link that library.
This is my CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.12.2)
project (test)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} cmake/)
add_executable(test tiffs.cpp)
target_link_libraries(test loadtiff)
and these are the errors I get when trying to make the program:
error: ‘floadtiff’ was not declared in this scope
Why can't I access this function, which is defined in loadtiff.c?
In tipps.cpp add:
extern "C" {
#include "loadtiff.h"
}
In CMakeLists.txt change to:
cmake_minimum_required(VERSION 2.8.12.2)
project(tiffs)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} cmake/)
add_library(loadtiff tiffloader/loadtiff.c)
target_include_directories(loadtiff PUBLIC tiffloader/loadtiff.h)
add_executable(tiffs tiffs.cpp)
target_link_libraries(tiffs loadtiff)
where "tiffloader/" is wherever you put the "loadtiff" files.
Do not name projects or targets after reserved words like "test", or you will get CMake warnings.
So you've got 2 problems.
1) your code is an abhorrent mixture of C and C++. For example, you're outputting text using C++
std::cout<<"failed"<<std::endl;
and C
printf("TIFF file unreadable\n");
Pick just one language and stick to it. Given it appears that floadtiff is expecting a FILE *, you'll probably be better off writing your code in C.
2) You're trying to use a library without telling the compiler anything about it. That's what header files are for. They tell the compiler you're using code from a different file and how the functions in that file are called. There should be a "loadtiff.h" file somewhere - you need to include that. That will contain definitions for the functions inside "loadtiff.c", such as floadtiff.
Without those definitions, your compiler has no idea if you're passing in the right number and/or type of parameters to those functions. It doesn't know what the return type of the function is or if it doesn't have one.
In C++ this information is especially important as you have function overloading, so it has to know exactly which function you're calling. In C, it's not quite so rigid and will make assumptions - which are often incorrect - about the function, but it will still warn you that it's done this.
If I use the following source
#include <cstdlib>
#include <cstdio>
#include <iostream>
extern "C" {
#include "loadtiff.h"
}
int main(int argc, char argv[] ) {
int width, height;
unsigned char* rgba;
FILE* fp = fopen("/home/user/pic.tif", "rb");
if(!fp)
std::cout << "failed" << std::endl;
rgba = floadtiff(fp, &width, &height);
fclose(fp);
if(rgba == 0)
printf("TIFF file unreadable\n");
return 0;
}
with the following CMakeLists.txt file under Visual Studio 14 and CMake 3.8.2
cmake_minimum_required(VERSION 2.8.12.2)
project (test)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} cmake/)
add_executable(test tiffs.cpp)
add_library(loadtiff STATIC loadtiff.c)
target_link_libraries(test loadtiff)
CMake generates a fully functional solution and Visual Studio is able to build it without errors.
Edit:
I assumed you have tiffs.cpp, loadtiff.c and loadtiff.h located in the same directory.
Here is the cmake file that i am using
cmake_minimum_required (VERSION 3.0)
project (midasd)
set (midas VERSION_MAJOR 0)
set (midas VERSION_MINOR 0)
set (midas VERSION_REVISION 1)
find_library(libconfig libconfig)
add_executable(midasd src/main.cpp)
target_link_libraries(midasd "${libconfig_LIBS}")
The problem i am facing is undefined reference for config_init. The main function is as follows
#include <libconfig.h>
int main(int argc, char *argv[])
{
midas::midasCtx *container = new midas::midasCtx(argc,argv);
config_t cfg;
config_init(&cfg);
return 0;
}
Where am i going wrong with CMAKE ?
Actually the libconfig is recognized as simply -lconfig not -llibconfigin linking argument. The CMakeLists.txt should contain
target_link_libraries(my_project config)
Source
This manual(https://hyperrealm.github.io/libconfig/libconfig_manual.html) says " To link with the library, specify ‘-lconfig++’ as an argument to the linker. "
So I fixed like following code and build was completed.
target_link_libraries(my_project config++)
CLion doesn't seem to recognize c++ tuples, although I can build and run my program from the terminal.
When trying to build, I only get "Build failed", while all the members of tuple are highlighted and I'm getting "Can't resolve namespace member tuple" (same with tie and make_tuple).
Here is my simple test:
#include<iostream>
#include<tuple>
std::tuple<int,int> testTuple();
int main(int argc, char** argv) {
int a, b;
std::tie(a,b) = testTuple();
std::cout<<a<<" "<<b;
return 0;
}
std::tuple<int,int> testTuple()
{
return std::make_tuple(0,1);
}
My CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(testTuple)
SET(CMAKE_CXX_COMPILER, /usr/bin/g++-4.8)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_BUILD_TYPE Debug)
set(SOURCE_FILES "src/main.cpp")
add_executable(simplification ${SOURCE_FILES})
For implementing such features as code-competition, jump to definitions and so on features CLion has it's own c++ parser.
So if your code compiled, but CLion show some kind of errors,
go and report bug to jetbrain (https://youtrack.jetbrains.com/issues/CPP)