Good day. Building program without using cmake
''' g++ -lpthread src/how2thread.cpp src/main.cpp -ggdb3 -std=c++17 -Wextra '''
produces no errors.
Although, using
'''
cmake . && make
'''
generates following build errors:
[ 25%] Building CXX object CMakeFiles/how2thread_lib.dir/src/how2thread.cpp.obj
D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.cpp: In member function 'how2thread::Request how2thread::Scheduler::get_request()':
D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.cpp:103:67: error: use of deleted function 'std::lock_guard<_Mutex>::lock_guard(const std::lock_guard<_Mutex>&) [with _Mutex = std::mutex]'
103 | auto m_lock = std::lock_guard<std::mutex>(data_arr_protect);
| ^
In file included from C:/msys64/mingw64/include/c++/12.1.0/mutex:43,
from D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.hpp:8,
from D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.cpp:4:
C:/msys64/mingw64/include/c++/12.1.0/bits/std_mutex.h:237:7: note: declared here
237 | lock_guard(const lock_guard&) = delete;
I specify in my header file, that data_arr_protect is std::mutex object
class Scheduler
{
// class for schedule slicers, processors and collecting data
public:
Scheduler(const std::vector<char>& data,
const std::string& mask); // construct and parse data
Request get_request(); // used to get another batch
void write_request(Request&&);
void write_finding(Finding&& find);
using Find_it = decltype(std::declval<std::vector<Finding>&>().cbegin());
Find_it cbegin();
Find_it cend();
const auto& get_slicing_status(){return is_slicing;} //
std::string mask;
#ifndef DEBUG_V
private:
#endif
const size_t slicer_num;
std::queue<Request> data_arr; // consider switching to deQ
std::mutex data_arr_protect;//for mt rw to vec // might be switching to semaphores
std::queue<Actor_processor> proc_instances_q;
std::queue<Actor_slicer> slicer_instances_q;
std::vector<Finding> result_arr;
std::mutex result_protect;//for mt write to vec
protected:
friend class Actor_slicer; // we need access from slicers to mutexes as they're pretty lowlvl
std::vector<std::mutex> char_segments_protect;
std::vector<size_t> finish_line_no;
std::atomic<size_t> is_slicing; // for break cond
};
My cmake file looks next
cmake_minimum_required(VERSION 3.10.0)
project(how2thread
VERSION 0.0.1
DESCRIPTION "simple mt parser app"
LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
file(GLOB_RECURSE src_files src/*.cpp)
add_library(how2thread_lib src/how2thread.cpp src/how2thread.hpp)
add_executable(how2thread src/main.cpp)
target_link_libraries(how2thread PRIVATE how2thread_lib)
target_link_libraries(how2thread PRIVATE Threads::Threads)
What can cause compiler's misinterpretation and how i must fix it?
I tried different linking options, as building my how2thread.cpp file with main.cpp file, although it didn't help. And I do not get errors about undefined class or something, so, I guess, header file being included by .cpp one
Nothing is being misinterpreted. The issue is the following line: (Which appears only in the error message, not the code you show. Please always provide a minimal reproducible example!)
auto m_lock = std::lock_guard<std::mutex>(data_arr_protect);
This is copy-initialization of m_lock from the initializer expression which before C++17 required the type to be move-constructible, which std::lock_guard is not. Direct-initialization with auto (e.g. auto m_lock(std::lock_guard<std::mutex>(data_arr_protect));) would also not work for the same reason.
To compile this line you need to use C++17 or later, but you are asking cmake to set C++14 with
set(CMAKE_CXX_STANDARD 14)
So change the 14 to 17.
Or if you require compatibility with C++14, you will have to avoid the auto initialization idiom for non-movable types:
std::lock_guard<std::mutex> m_lock(data_arr_protect);
Related
Ok, I have this strange bug, or behavior I don't understand. If I use -static-libstdc++ link flag in my project, LLDB fails to show underlying type of a pointer. So here is small example. I have the very basic test executable, with only one main.cpp file:
// main.cpp
#include <memory>
class TestBase
{
public:
TestBase() = default;
virtual ~TestBase() = default;
int m_baseInt = 10;
};
class TestDerived : public TestBase
{
public:
TestDerived() = default;
virtual ~TestDerived() override = default;
int m_derivedInt = 20;
};
int main(int,char*[])
{
std::unique_ptr<TestBase> regularBase = std::make_unique<TestBase>();
std::unique_ptr<TestBase> hiddentBase = std::make_unique<TestDerived>();
TestBase*volatile base = hiddentBase.get();
volatile int breakpoint = 10;
++breakpoint;
}
and one CMake file to build it
# CMakeLists.txt
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)
project(quick-test VERSION 0.1.0 LANGUAGES CXX C)
add_executable(test-exe "main.cpp")
For ide I use vscode with CodeLLDB module, and so if you look at 'base' variable it will show TestDerived class (as it should):
But with only one chage, by adding -static-libstdc++ link option to my test executable
# CMakeLists.txt
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)
project(quick-test VERSION 0.1.0 LANGUAGES CXX C)
add_executable(test-exe "main.cpp")
target_link_options(test-exe PRIVATE -static-libstdc++)
now lldb is incapable to deduce underlying type of a 'base' pointer:
For compilation I used clang 14.0.0 and gcc 11.2.0, but it didn't make any difference.
Why does linking statically c++ std lib causes this, and is there any solution for this accept removing this flag?
I am trying to have a member array in a class with its length specified by the const static int variable for future needs.
My compiler throws an error with it, and I am not sure this is an error about a uniform initialization or array initialization, or both.
Here is the header file:
#ifndef SOUECE_H
#define SOURCE_H
class Test
{
public:
Test();
static const int array_length{2};
double array[array_length];
};
#endif
This is the source file.
#include "source.h"
Test::Test()
:array_length{0} //Typo of array{0}
{
}
These are the problem messages.
[enter image description here][1]
[1]: https://i.stack.imgur.com/IQ2Mk.png
This is the CMake file.
cmake_minimum_required(VERSION 3.0.0)
project(temp VERSION 0.1.0)
include(CTest)
enable_testing()
add_executable(temp main.cpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
Finally, these are what the compiler is complaining about when I try to build the project.
[main] Building folder: temp
[build] Starting build
[proc] Executing command: /usr/local/bin/cmake --build /Users/USERNAME/Desktop/temp/build --config Debug --target all -j 14 --
[build] [1/2 50% :: 0.066] Building CXX object CMakeFiles/temp.dir/main.cpp.o
[build] FAILED: CMakeFiles/temp.dir/main.cpp.o
[build] /usr/bin/clang++ -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk -MD -MT CMakeFiles/temp.dir/main.cpp.o -MF CMakeFiles/temp.dir/main.cpp.o.d -o CMakeFiles/temp.dir/main.cpp.o -c ../main.cpp
[build] In file included from ../main.cpp:1:
[build] ../source.h:8:22: error: function definition does not declare parameters
[build] static const int array_length{2};
[build] ^
[build] ../source.h:9:18: error: use of undeclared identifier 'array_length'
[build] double array[array_length];
[build] ^
[build] 2 errors generated.
[build] ninja: build stopped: subcommand failed.
[build] Build finished with exit code 1
I am using macOS 12.0 beta, with VS Code 1.60.2, clang 13.0.0, CMake 3.20.2.
Please let me know if you see any wrong or have any suggestions.
This cannot work:
Test::Test()
:array_length{0}
You cannot set a const static data member in your constructor. A static value has the same value accross all object instances. But as it is also const no instance is allowed to change the value.
Since array_length is static const you have to initialize it like this:
source.h
#ifndef SOUECE_H
#define SOURCE_H
class Test
{
public:
Test();
static const int array_length = 2;
//static const int array_length{2}; this will also work just note that we cannot use constructor initializer list to initialize static data members
double array[array_length];
};
#endif
source.cpp
#include "source.h"
Test::Test()//we cannot use constructor initializer list to initialize array_length
{
}
Note that static const int array_length{2}; will also work but the thing is that in the constructor we cannot use constructor initializer list to initialize static data member.
EDIT:
If you decide to use static const int array_length{2}; then make sure that you have C++11(or later) enabled in your CMakeLists.txt. For this you can add
set (CMAKE_CXX_STANDARD 11)
to your CMakeLists.txt.
Alternatively, you could instead add
target_compile_features(targetname PUBLIC cxx_std_11)
in your CMakeLists.txt. In your case replace targetname with temp since that is the targetname that you have. Check this out for more how to active C++11 in CMake .
According to cppreference, to determine if std::hardware_constructive_interference_size is usable it uses the following example:
#include <new>
#ifdef __cpp_lib_hardware_interference_size
using std::hardware_constructive_interference_size;
using std::hardware_destructive_interference_size;
#else
// 64 bytes on x86-64 │ L1_CACHE_BYTES │ L1_CACHE_SHIFT │ __cacheline_aligned │ ...
constexpr std::size_t hardware_constructive_interference_size
= 2 * sizeof(std::max_align_t);
constexpr std::size_t hardware_destructive_interference_size
= 2 * sizeof(std::max_align_t);
#endif
However, my system defines __cpp_lib_hardware_interference_size but there is no symbol std::hardware_constructive_interference_size.
How can I handle this situation?
Is there a way to check if a symbol is defined?
Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
macOS Catalina 10.15.7 (MacBook Pro 2019)
CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
project(untitled4)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
if (UNIX AND NOT APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
endif()
add_executable(untitled4 main.cpp)
How can I handle this situation?
You could detect the broken language implementation using pre-defined macros and make an exception for it.
Detection could be made by trying to compile and run a small program:
#include <new>
int main() {
#ifdef __cpp_lib_hardware_interference_size
// return 0 if the interference_sizes are defined
return !(std::hardware_constructive_interference_size &&
std::hardware_destructive_interference_size);
#else
return 1; // no interference_sizes
#endif
}
clang++ -std=c++17 -o hwisize hwisize.cpp 2>/dev/null && ./hwisize
has_hw_interference_sizes=$?
If the compilation fails, has_hw_interference_sizes will be 1.
If the compilation succeeds, but __cpp_lib_hardware_interference_size is not defined, has_hw_interference_sizes will be 1.
If the compilation succeeds, and __cpp_lib_hardware_interference_size is defined, has_hw_interference_sizes will be 0.
(The reversed bool logic is how common shells define true (0) and false (not 0))
Just plug that into your build system.
I've been working on os X 10.13 with AppleLLVM 9.1.0(clang-902.0.39.1), and example as follow
#include <experimental/optional>
#include <iostream>
template<typename T>
class p {
public:
T value;
p(T& t):value(t){}
p(T const& t):value(t){}
~p() = default;
};
template <typename T1, typename T2>
constexpr auto operator+(p<T1> const &lhs, p<T2> const &rhs) noexcept {
return p<decltype(lhs.value + rhs.value)>(lhs.value + rhs.value);
}
int main(int, char* []) {
p<int> v1(20);
p<int> v2(10);
auto v3 = v1+v2;
std::cout << v3.value <<std::endl;
return 0;
}
compiled with
c++ -std=c++17 -o test test.cpp
it works perfect for I was just trying to use the new feature of return type deduction as referred in N3638 which proposed a written style as
template<typename T> auto f(T t);
However, when I was about to use it in my CMake(3.11.1) organized project with several flags show as follow:
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_FLAGS "-Wall -fpermissive -Wno-unused-parameter -Werror")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb3")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -ggdb3 -DNDEBUG")
it failed to compile telling me "'auto' return without trailing return type; deduced return types are a C++14 extension".
and I've tried the next flag also getting the same result:
set(CMAKE_CXX_FLAGS "-std=c++17")
It mostly look alike a CMake problem failing at environment set, while I got confused about what CMake flags should I set to enable this new feature? Or was it a compiler-related issue?
Sry guys.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
works absolutely fine.
The problem was caused by an old version dependency library which used "std::auto_ptr" deprecated in c++11 and removed in c++17 (however still compiles in c++11), hence the CMakeLists was dedicated to c++11 standard.
Problem solved.
And in my ubuntu env, the old version library was updated by apt-get.
Good day,
here is my code
#include <iostream>
#include <Magick++.h>
using namespace std;
using namespace Magick;
int main(int argc, char **argv) {
InitializeMagick(*argv);
Image image;
try {
image.read(argv[1]);
}
catch( Exception &error_ ) {
cout << "Caught exception: " << error_.what() << endl;
return 1;
}
int x = image.columns();
cout<<"your picture's width is "<< x << "px"<<endl;
return 0;
}
I use KDevelop(which uses CMake as builder),
when I try to compile the app, it throws me an error
main.cpp:25: undefined reference to `Magick::Image::columns() const'
Here's what my CMakeLists.txt contains.
cmake_minimum_required(VERSION 3.5)
project(hello)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(hello ${SOURCE_FILES})
add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 )
add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 )
find_package(ImageMagick COMPONENTS Magick++)
include_directories(${ImageMagick_INCLUDE_DIRS})
target_link_libraries(hello ${ImageMagick_LIBRARIES})
I figured out that there're often issues with undefined references when CMakeLists isn't written correctly, but I made it according to this About Magick++, how to write the CMakeLists?
where am I wrong? I can add any information needed.
UPD 1.
version of magick++,
8:6.8.9.9-7ubuntu5.7
system info:
Description: Linux Mint 18.1 Serena
UPD 2.
I just removed parenthesis and when tryed to compile with
size_t x = image.columns;
size_t y = image.rows;
KDevelop threw me
main.cpp:25:22: error: cannot convert ‘Magick::Image::columns’ from type ‘size_t (Magick::Image::)() const {aka long unsigned int (Magick::Image::)() const}’ to type ‘size_t {aka long unsigned int}’
even when
auto x = image.columns;
auto y = image.rows;
it throws
main.cpp:25:20: error: cannot convert ‘Magick::Image::columns’ from
type ‘size_t (Magick::Image::)() const {aka long unsigned int
(Magick::Image::)() const}’ to type ‘long unsigned int
(Magick::Image::*)() const’
what's happening?
P.S. hooray, this is my first question on stackoverflow! :-)
If you are able to compile your program without CMake using g++ main.cpp `Magick++-config --cxxflags --cppflags --ldflags --libs` (but for some reason cannot use ${ImageMagick_LIBRARIES} in CMake), then you can make use of Magick++-config in your CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(hello LANGUAGES CXX)
add_executable(hello main.cpp)
target_compile_features(hello PRIVATE cxx_std_11)
find_package(ImageMagick REQUIRED COMPONENTS Magick++)
target_compile_definitions(hello PRIVATE
MAGICKCORE_QUANTUM_DEPTH=16
MAGICKCORE_HDRI_ENABLE=0
)
target_include_directories(hello PRIVATE ${ImageMagick_INCLUDE_DIRS})
execute_process(COMMAND Magick++-config --ldflags
OUTPUT_VARIABLE ImageMagick_LINK_FLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
target_link_libraries(hello PRIVATE ${ImageMagick_LINK_FLAGS})
Here, execute_process allows us to get the result of Magick++-config --ldflags into a variable, which we can pass as flags to the linker through target_link_libraries.
Also, note how I've used target_compile_features rather than setting the global CMAKE_CXX_FLAGS variable, target_compile_definitions rather than add_definitions and target_include_directories rather than include_directories. It's better to use local (target-based) commands rather than modifying global state, both in programming and in CMake, since they can have unforeseen repercussions down the line -- in the context of CMake, those global commands would have affected nested sub-projects.
ForgottenUbrella 's version which I adapted didn't quite work for me, copying a line in from another project fixed it. Note, I'm using c++20 not 11.
I had the following error:
..... undefined reference to symbol 'pthread_create##GLIBC_2.2.5'
and the line that fixed it:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++2a -pthread")