After compiling my program with
$ cmake .
$ make
I get 5 errors of this form:
$ make
Scanning dependencies of target Project
[ 50%] Building CXX object CMakeFiles/myproj.dir/main.cpp.o
In file included from /path/to/my/proj/main.cpp:2:0:
/path/to/my/proj/library.hpp: In member function ‘virtual double MyProjClass::get_value(double, double) const’:
/path/to/my/proj/library.hpp:419:26: error: ‘sqrtf’ is not a member of ‘std’
const float F = (std::sqrtf(1.0f + 2.0f) - 1.0f) / 2;
^
Other errors include floorf not being a member of std.
Looking at this thread, it's because I'm not compiling with C++11, and looking at this thread thread, "[...] CMake will make sure the C++ compiler is invoked with the appropriate command line flags."
Well, my CMake is obviously not doing this. Why am I getting these errors, and how do I go about fixing them?
Edit: Here's my CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(Noise)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp vector.hpp noise.hpp)
add_executable(Noise ${SOURCE_FILES})
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
target_link_libraries(Noise ${SDL2_LIBRARIES})
You don't say what C++ compiler you are using but assuming it is g++ 5.x though 7, sqrtf
and floorf are not within the std namespace under -std=c++11, -std=c++14 or -std=c++1z. They are
simply in the global namespace, when cmath is included.
Related
I have an application that is written in C. I would like to use the LAPACK library to do some linear algebra calculations. I am using LAPACKE, which is the C interface to LAPACK. The C code compiled fine with GCC, but I am having trouble linking the libraries with GCC. It only works with GFORTRAN. I downloaded the lapack-3.11.0.tar.gz file from the LAPACK website. I unpacked the file then I built it. I did not make any changes to the make.inc.example file, which was already configured for a linux machine running GNU compilers. Here is how I built it once in the ~/lapack-3.11.0 directory:
cp make.inc.example make.inc
make
LAPACK built successfully and all of the tests passed. Then, I built LAPACKE. To do this, I simply ran make in the ~/lapack-3.11.0/LAPACKE directory. Similarly, it built successfully and all of the tests passed. Notice that in my case, LAPACK is installed in my home directory and not in a system directory.
To test that I could actually use LAPACKE, I wrote a sample C program that solves a system of equations using LAPACKE_dgesv().
lapack_test.c:
#include <stdio.h>
#include <lapacke.h>
int main()
{
int n = 3;
int nrhs = 1;
int lda = n;
int ipiv[n];
double a[9] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 10.0};
double b[3] = {3.0, 3.0, 4.0};
int info;
info = LAPACKE_dgesv(LAPACK_ROW_MAJOR, n, nrhs, a, lda, ipiv, b, nrhs);
if (info == 0)
{
printf("Solution: %f %f %f\n", b[0], b[1], b[2]);
}
else
{
printf("dgsev failed with error code %d\n", info);
}
return 0;
}
Assuming that lapack_test.c is in my home directory, here is how I compiled it and linked the libraries:
gcc -I./lapack-3.11.0/LAPACKE/include -c -o lapack_test.o lapack_test.c
gfortran -o lapack_test lapack_test.o ./lapack-3.11.0/liblapacke.a ./lapack-3.11.0/liblapack.a ./lapack-3.11.0/librefblas.a
This gave my no errors. However, GFORTRAN is very inconvenient for my case. In my application I have many C libraries that probably will not link using GFORTRAN. Or at least, I do not think that that they will.
If I use GCC, I get linkage errors. For example, if I simply replace GFORTRAN with GCC in the last step I get a bunch of errors:
/usr/bin/ld: ./lapack-3.11.0/liblapack.a(iparmq.o): in function `iparmq_':
iparmq.f:(.text+0x25e): undefined reference to `logf'
/usr/bin/ld: iparmq.f:(.text+0x26b): undefined reference to `lroundf'
/usr/bin/ld: ./lapack-3.11.0/liblapack.a(xerbla.o): in function `xerbla_':
xerbla.f:(.text+0x55): undefined reference to `_gfortran_st_write'
/usr/bin/ld: xerbla.f:(.text+0x60): undefined reference to `_gfortran_string_len_trim'
/usr/bin/ld: xerbla.f:(.text+0x77): undefined reference to `_gfortran_transfer_character_write'
/usr/bin/ld: xerbla.f:(.text+0x87): undefined reference to `_gfortran_transfer_integer_write'
/usr/bin/ld: xerbla.f:(.text+0x8f): undefined reference to `_gfortran_st_write_done'
/usr/bin/ld: xerbla.f:(.text+0x9a): undefined reference to `_gfortran_stop_string'
collect2: error: ld returned 1 exit status
Seems to be linking the static library liblapacke.a with no errors. liblapack.a seems to be where the errors are. It is a FORTRAN library, so it makes sense why it would not link correctly using GCC.
Is there a workaround here? Is it worth using LAPACKE? Or, should I try some other way to interface between FORTRAN and C?
There is no difference in linking else than some libraries being added automatically. gfortran and gcc do the same when linking. Only gfortran links some libraries like libgfortran or libm automatically while with gcc you have to use -lgfortran or -lm. Otherwise they do the exact same thing.
You can even use the gcc command to compile Fortran code and the gfortran command to compile C code. Or C++ code. It really does not matter. Just link all the necessary library when linking, depending whether you link with gcc, gfortran, g++ or ld.
In the end the linking is always done by ld, just with some particular flags added by the compiler command.
Finally, to be precise, distinguish GCC, the GNU compiler collection, and gcc, the command that calls the C frontend or the GCC's C compiler. The gfortran command calls the Fortran frontend. They share the same backend and middlend. When you call, e.g. gcc test.f90, the command recognizes that it is a Fortran source file and will invoke the Fortran frontend for you.
I have a library with a C++ wrapper around auto-generated C code, built with CMake and gcc. When I compile it I get these warnings which I would like to inhibit:
src/ssp/autogenerated.c: In function ‘x1111’:
src/ssp/autogenerated.c:185:1: warning: implicit declaration of function ‘x1111’; did you mean ‘x1110’? [-Wimplicit-function-declaration]
185 | x1111();
| ^~~~~~~~~~
I should be able to inhibit these warnings with the -Wno-implicit-function-declaration warning option. I add that to my CMakeLists.txt like so:
file(GLOB SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/ssp/*.c src/ssp/*.cpp)
add_library(mylib SHARED ${SRCS})
target_compile_options(mylib PRIVATE "-Wno-implicit-function-declaration")
However, there is still a *.cpp source in there and so compiling gives me:
cc1plus: error: command-line option ‘-Wno-implicit-function-declaration’ is valid for C/ObjC but not for C++ [-Werror]
cc1plus: all warnings being treated as errors
Is there a way inhibit these warnings? I'm imagining it might be possible to apply -Wno-implicit-function-declaration to C sources only or to have it ignored by g++?
Apply the option only to C sources. See cmake generator expressions:
target_compile_options(mylib PRIVATE
$<$<COMPILE_LANGUAGE:C>:-Wno-implicit-function-declaration>
)
I want to use a timer as advised in
How can I measure the execution time of one thread?
However, I receive the error message
In file included from /usr/include/c++/5/thread:35:0,
/usr/include/c++/5/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support \
^
The CMake output of
message("${CMAKE_CXX_FLAGS}" and "${CMAKE_C_FLAGS}")
is
-std=c++11 -fPIC -Wall;and; -std=c++11
What is wrong?
If you would like your project to require C++11, I suggest you do something like this:
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
project(test)
[...]
If you are building a library, and you would like user of your library to transitively use the correct flags, you could look into https://cmake.org/cmake/help/latest/manual/cmake-compile-features.7.html#requiring-language-standards
I use CMake to generate unix makefiles. After that I compile project using make utility.
Problem is that I can't see any warnings! For example, this results in clean build without warnings:
#include <iostream>
class Foo
{
int first;
int second;
public:
Foo(int a, int b)
: second(a) // invalid initialization order
, first(b)
{
}
};
int main(int argc, char** argv)
{
int unused; // unused variable
int x;
double y = 3.14159;
x = y; // invalid cast
Foo foo(1,2);
std::cout << y << std::endl;
return 0;
}
Unused variable and lossy variable cast - no warnings! My CMakeLists.txt file is minimalistic:
cmake_minimum_required(VERSION 2.8)
add_executable(main main.cpp)
When I run cmake and then make my output looks like this:
[100%] Building CXX object CMakeFiles/main.dir/main.cpp.o
Linking CXX executable main
[100%] Built target main
But when I add this line of code:
#warning ("Custom warning")
resulting output contains warning:
[100%] Building CXX object CMakeFiles/main.dir/main.cpp.o
../src/main.cpp:15:2: warning: #warning ("Custom Warning") [-Wcpp]
Linking CXX executable main
[100%] Built target main
I use Ubuntu 12.04 LTS and GCC as a compiler. Maybe CMake passes some flag to compiler that results in absence of warnings. How can I check it? I can't read makefiles generated by CMake, they are a little bit cryptic.
The positions on compiler warnings are divided. There are package maintainers who will tell you that they know what they are doing, and compiler warnings should be ignored in any case. (I think they couldn't be more wrong.) But I guess that is why CMake mostly leaves the warning settings alone.
If you want to be a bit more sophisticated about it, check for the compiler being used, and add the flag to the specific property of the specific target.
Apply to a Single Target
if ( CMAKE_COMPILER_IS_GNUCC )
target_compile_options(main PRIVATE -Wall -Wextra)
endif()
if ( MSVC )
target_compile_options(main PRIVATE /W4)
endif()
Apply to All Targets
if ( CMAKE_COMPILER_IS_GNUCC )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
endif()
if ( MSVC )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
Note: add -Werror for GCC or /WX for MSVC to treat all warnings as errors. This will treat all warnings as errors. This can be handy for new projects to enforce warning strictness.
Also, -Wall -Wextra does not mean "all errors"; historically -Wall meant "all errors that everybody could agree on", and -Wextra "some more". Start with that, then peruse the manual for your version of GCC, and find what else the compiler can do for you with regards to warnings...
Solve problem with this line of code:
add_definitions ("-Wall")
Result now looks like this:
[100%] Building CXX object CMakeFiles/main.dir/main.cpp.o
../src/main.cpp:15:2: warning: #warning ("Custom warning") [-Wcpp]
../src/main.cpp: In constructor ‘WarnSrc::WarnSrc(int, int)’:
../src/main.cpp:6:9: warning: ‘WarnSrc::second’ will be initialized after [-Wreorder]
../src/main.cpp:5:9: warning: ‘int WarnSrc::first’ [-Wreorder]
../src/main.cpp:8:5: warning: when initialized here [-Wreorder]
../src/main.cpp: In function ‘int main(int, char**)’:
../src/main.cpp:19:9: warning: unused variable ‘unused’ [-Wunused-variable]
../src/main.cpp:20:9: warning: variable ‘x’ set but not used [-Wunused-but-set-variable]
Linking CXX executable main
[100%] Built target main
I'm having trouble building a little program that uses Boost.Test on my Mac with a Boost installed by MacPorts at /opt/local/lib/
Here's my minimal source file, test.cpp:
#define BOOST_TEST_MODULE MyTest
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE(test1) {
}
and my CMakeLists.txt:
cmake_minimum_required(VERSION 2.6)
project (test)
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
add_executable(test test.cpp)
and an excerpt of from make VERBOSE=1:
[100%] Building CXX object CMakeFiles/test.dir/test.cpp.o
g++ -o CMakeFiles/test.dir/test.cpp.o -c /Users/exclipy/Code/cpp/inline_variant/question/test.cpp
Linking CXX executable test
"/Applications/CMake 2.8-5.app/Contents/bin/cmake" -E cmake_link_script CMakeFiles/test.dir/link.txt --verbose=1
g++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/test.dir/test.cpp.o-o test
Undefined symbols for architecture x86_64:
"_main", referenced from:
start in crt1.10.6.o
"vtable for boost::unit_test::unit_test_log_t", referenced from:
boost::unit_test::unit_test_log_t::unit_test_log_t() in test.cpp.o
boost::unit_test::unit_test_log_t::~unit_test_log_t() in test.cpp.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
As you can see, it doesn't know how to link to Boost library. So I try adding to CMakeLists.txt:
target_link_libraries(test boost_unit_test_framework)
But I just get:
g++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/test.dir/test.cpp.o-o test -lboost_unit_test_framework
ld: library not found for -lboost_unit_test_framework
From lots of trial and error, I've found that manually running this works:
$ g++ test.cpp -L/opt/local/lib -lboost_unit_test_framework -DBOOST_TEST_DYN_LINK
But after hours of fiddling, I can't get it to build from CMake. I don't care whether it links dynamically or statically, I just want it to work.
You need to tell CMake where to find the boost libraries (the -L/opt/local/lib in your g++ line). You can accomplish this by adding the following line (if you had no problem with find_package):
link_directories ( ${Boost_LIBRARY_DIRS} )
before add_executable.
Another alternative is using the single-header variant of the UTF. This variant is really simple (you only need to include <boost/test/included/unit_test.hpp> but it has a major drawback in its considerable increase in build time.
The find_package(Boost COMPONENTS ...) call collects the required link libraries for the searched Boost components (e.g.,unit_test_framework) in the CMake variable Boost_LIBRARIES.
To get rid of the link error, add:
target_link_libraries(test ${Boost_LIBRARIES})
EDIT 2020-02
The details of building a Boost.Test module are on the documentation here and covered with many examples on the documentation. Usually if main is not found, this might be due to:
mixing static and shared library versions of Boost.Test (the linker prefers shared libraries)
improper definitions of the BOOST_TEST_MODULE and/or BOOST_TEST_DYN_LINK macros: depending on those, the Boost.Test framework will define (correctly) a main or not.
Previous (wrong) answer
Well here, the problem is not that cmake does not find the boost_unit_test_framework library, but rather that this specific library does not contain the main entry point for running the binary.
In fact, you should link against ${Boost_TEST_EXEC_MONITOR_LIBRARY} since it contains the proper definitions. You should also avoid defining the macro BOOST_TEST_DYN_LINK.