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)
Related
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 ?
First thing first, here's my minimum reproducible program:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.17)
project(untitled4)
set(CMAKE_CXX_STANDARD 17)
add_library(lib1 SHARED lib1.cpp)
add_executable(untitled4 main.cpp)
target_link_libraries(untitled4 PRIVATE dl)
main.cpp:
#include "iostream"
#include <dlfcn.h>
int Test() {
return 123456;
}
int main() {
auto* handler = dlopen("/home/liu/source/untitled4/cmake-build-debug/liblib1.so", RTLD_LAZY|RTLD_GLOBAL);
if (!handler) {
std::cerr << dlerror();
exit(1);
}
}
and lib1.cpp:
#include "iostream"
extern int Test();
class Foo {
public:
Foo() {
std::cout << Test() << std::endl;
}
};
Foo foo;
now let me explain:
As you can see I defined a function called Test in main.cpp, and I want to the shared library liblib1.so call it when it is loaded.
But when I run the main() function, there's an error log said:
/home/liu/source/untitled4/cmake-build-debug/liblib1.so: undefined symbol: _Z4Testv
I check the symbol by using nm untitled4 |grep Test and the symbol seems exist:
0000000000000b87 t _GLOBAL__sub_I__Z4Testv
0000000000000aea T _Z4Testv
So what did I do wrong? How to fix this?
An important thing to be notice is that in the real case, the build of lib1 and the build of main.cpp are totally separated, the two build don't know each other. But I can make them into one build (very difficult) if this can fix the problem(if there's no other way).
P.S. I tried using extern "C" to wrap around the Test() in both files, but not working, seems not the C/C++ function naming problem.
With the addition of the linker option -rdynamic your code does not fail with "undefined symbol".
You can set that with set_target_properties(untitled4 PROPERTIES ENABLE_EXPORTS 1) or target_link_options(untitled4 BEFORE PRIVATE "-rdynamic").
Example:
cmake_minimum_required(VERSION 3.17)
project(untitled4)
set(CMAKE_CXX_STANDARD 17)
add_library(lib1 SHARED lib1.cpp)
add_executable(untitled4 main.cpp)
set_target_properties(untitled4 PROPERTIES ENABLE_EXPORTS 1)
target_link_libraries(untitled4 PRIVATE dl)
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++)
I am a newcomer to the world of cmake. This question came up while I was experimenting with some basic cmake configurations in C++. To be precise, following is my directory structure :
/src----
|-> CMakeLists.txt
|-> main.cpp
|-> lib----
|-> libfsystem.so
|->filesystem----
|->CMakeLists.txt
|->listfiles.cpp
|->include-----
|->fsystem.h
Now, the /src/filesystem/CMakeLists.txt file is like this
cmake_minimum_required(VERSION 2.8)
project(fsystem)
set(CMAKE_BUILD_TYPE Release)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/build)
find_package(Boost REQUIRED system filesystem)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(fsystem SHARED listfiles.cpp)
While, the /src/CMakeLists.txt file is like this
cmake_minimum_required(VERSION 2.8)
project(vessel_detect)
add_subdirectory(filesystem)
add_executable(main main.cpp)
set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
find_library(libpath fsystem)
MESSAGE(${libpath})
target_link_libraries(main ${libpath})
The library libfsystem.so is successfully created.
The library libfsystem.so is also successfully found by /src/CMakeLists.txt
However when the linking of main.cpp is done, then it gives me several undefined reference errors which should not have happened as everything has already been defined. For greater completeness, following is the content of main.cpp file
Main.cpp
#include<iostream>
#include"filesystem/include/fsystem.h"
using namespace std;
int main(void)
{
string path ("~");
vector<string>* output;
output = listfiles(path);
return 0;
}
The contents of listfiles.cpp are
listfiles.cpp
#include"fsystem.h"
using namespace boost::filesystem;
vector<string>* listfiles(int argc, char* argv[])
{
if (argc<2)
{
std::cout<<"No file name provided"<<std::endl;
}
else
{
path p(argv[1]);
vector<string>* output;
if (exists(p))
{
if(is_directory(p))
{
std::cout<<"You specified a directory"<<std::endl;
std::cout<<"Its contents are as follows :-"<<std::endl;
typedef std::vector<path> vec;
vec v;
copy(directory_iterator(p),directory_iterator(),back_inserter(v));
sort(v.begin(),v.end());
for(vec::const_iterator it(v.begin());it!=v.end();++it)
output->push_back(it->filename().string());
// std::cout<<it->filename()<<std::endl;
}
else if (is_regular_file(p))
{
std::cout<<argv[1]<<" "<<file_size(p)<<std::endl;
}
else
{
std::cout<<"The file is neither a directory nor a regular file"<<std::endl;
}
}
else
{
std::cout<<"The speicified path does not exist"<<std::endl;
}
}
}
And finally, the fsystem.h contents are :
fsystem.h
#ifndef _fsystem_h
#define _fsystem_h
#include<iostream>
#include<string>
#include<vector>
#include"boost/filesystem.hpp"
using namespace std;
vector<string>* listfiles(string);
#endif
Could someone provide me a reason for the undefined reference errors I am getting during the linking of main.cpp ? I would also be grateful if you could provide me with a resolution of this issue.
Thanks
Your not linking boost. you need to add target_link_libraries(fsystem ${Boost_LIBRARIES}) to the end of /src/filesystem/CMakeLists.txt and include_directories(${Boost_INCLUDE_DIRS}) between the find_package and add_library.
cmake_minimum_required(VERSION 2.8)
project(fsystem)
set(CMAKE_BUILD_TYPE Release)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/build)
find_package(Boost REQUIRED system filesystem)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories(${Boost_INCLUDE_DIRS})
add_library(fsystem SHARED listfiles.cpp)
target_link_libraries(fsystem ${Boost_LIBRARIES})
(1) For TARGET_LINK_LIBRARIES you should put the name of the target, thus:
TARGET_LINK_LIBRARIES(main fsystem)
(2) You declare listfiles as vector<string>* listfiles(string) while you define it as vector<string>* listfiles(int,char**)
Additionally you need to link with Boost per the other reply.
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...