I've tried enabling C++11 in CDT by adding AX_CXX_COMPILE_STDCXX_11 to my configure.ac file. I've tried moving it around in the file, this seems like the only place where it doesn't error out. I've even tried adding the optional noext flag, but that gives me a syntax error.
The code I'm trying to compile is:
#include <iostream>
#include <memory>
void
print_hello(){
std::unique_ptr<char[]> cha;
std::cout << "11?" << std::endl;
}
Where unique_ptr is of course a c++11 feature.
This is how my configure.ac looks:
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.64)
AC_INIT(fooProj, 1.0)
AC_CANONICAL_SYSTEM
AC_PROG_CXX
AC_LANG([C++])
AX_CXX_COMPILE_STDCXX_11
dnl Initialize automake
AM_INIT_AUTOMAKE
dnl this allows us specify individual liking flags for each target
AM_PROG_CC_C_O
dnl Initialize Libtool
LT_INIT
dnl Check if Libtool is present
dnl Libtool is used for building share libraries
AC_PROG_LIBTOOL
AC_CONFIG_FILES(Makefile
exampleProgram/Makefile
libTestLib/Makefile
include/Makefile)
AC_OUTPUT
If all your want is make your code compile to the C++11 standard, then clean your build, then add AM_CXXFLAGS = -std=c++11 to the Makefile.am where your source is, then rebuild. The AX_CXX_COMPILE_STDCXX_11 in configure.ac is unnecessary for this.
You need an m4 macro from this page on the gnu website [1]. Save it as ax_cxx_compile_stdcxx_11.m4 in your project root.
[1]: http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html ""
sudo apt-get install autoconf-archive
Related
I'm following this tutorial:
http://www.bfilipek.com/2017/08/cpp17-details-filesystem.html
to checkout new c++ filesystem feature. However I'm unable to compile even minimal example on my machine:
#include <string>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main()
{
std::string path = "/";
for (auto & p : fs::directory_iterator(path))
std::cout << p << std::endl;
}
I was using XCode, CLion and command line while trying to compile it but nothing works, I have Version 9.3 (9E145) with (seemingly proper) project settings, none of which work:
Here is my CMakeLists.txt file for CLion:
cmake_minimum_required(VERSION 3.8)
project(FileSystem2)
set(CMAKE_CXX_STANDARD 17)
add_executable(FileSystem2 main.cpp)
Here is an output from > gxx --version:
Nevertheless this is what I get as an output from my IDEs:
What am I doing wrong, it looks to me that my compiler should support c++17?
Edit
As per Owen Morgan's answer I've installed clang (actual install command was brew install llvm) but it now complains about absence of string.h. Any thoughts?
The compiler shipped with Xcode supports C++17 language features but not C++17 standard library features. Looking at your screenshot you will see the standard library support goes up to C++11, and Apple has not yet shipped a version of clang that has stdlib support for either C++14 or C++17.
However hope is not lost! You can download the newest version of clang from the brew package manager.
brew install clang
Then you can compile by setting your cmake compiler flags to be your custom brew version and then running that.
Here is a link how to do that: http://antonmenshov.com/2017/09/09/clang-openmp-setup-in-xcode/
Edit:
After installing llvm you will need to link your llvm path into your current shell. I have a shell script that I use at work to get this set up properly. Hope this helps.
#!/bin/bash
brew update
brew install --with-toolchain llvm # llvm but with all the headers
xcode-select --install # installs additional headers that you might be mimssing.
echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.bash_profile # exports the custom llvm path into the shell
sudo ln -s /usr/local/opt/llvm/bin/clang++ /usr/local/bin/clang++-brew # optional but I like to have a symlink set.
Edit 2:
Clang 6.0 doesn't have <filesystem> included on macOS yet, however you can get <experimental/filesystem>, and link against -lc++experimental, and use std::experimental::filesystem instead of std::filesystem.
Final command line invocation:
Owen$ /usr/local/Cellar/llvm/6.0.0/bin/clang++ fs.cpp -std=c++1z -L /usr/local/Cellar/llvm/6.0.0/lib/ -lc++experimental
Edit 3:
Current clang version 7.0.1 supports either <filesystem> or <experimental/filesystem>. In any case, the compiler command line must be slightly different:
Owen$ /usr/local/Cellar/llvm/7.0.1/bin/clang++ main.cpp -std=c++1z -L /usr/local/Cellar/llvm/7.0.1/lib/ -lc++fs
with -lc++fs instead of -lc++experimental.
Optionally, you can replace-std=c++1z with -std=c++17 as well.
If you don't want to change compiler to use std::filesystem (because it's a pain), another option is to use the Boost Filesystem library. Boost Filesystem was the basis for std::filesystem, so for most uses it's completely compatible with std::filesystem.
Setting up Boost is pretty easy if you're using CMake. Just brew install boost then in your CMakeLists.txt do something like:
# Boost
set(boost_min_ver 1.50.0)
set(boost_libs system filesystem)
find_package(Boost ${boost_min_ver})
if(Boost_FOUND)
find_package(Boost ${boost_min_ver} COMPONENTS ${boost_libs})
endif()
target_link_libraries(your_target ${Boost_LIBRARIES})
The extra verbosity in finding Boost helps, I find, to suppress some warnings CMake would otherwise throw at you.
Then in your C++ code:
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
If you're feeling very fancy, you can use the __has_include define to check if the standard filesystem include is available, and if so, set namespace fs = std::filesystem and fallback to Boost only if the std version isn't available.
As std::filesystem support on macOS with the official compiler and Xcode 11.1 is now limited to Catalina/10.15 deployment targets and up, I want to humbly add ghc::filesystem by myself as an additional option. It was written because I wanted to use std::filesystem on macOS, so it might be worth a try.
It is a header-only feature complete implementation of std::filesystem for macOS, Linux and Windows, works from C++11 to C++17, and it tries to stay close to the standard. It might be a less heavy dependency than boost (if you don't use that already). In the simplest form, just drop the main header file next to your source, include filesystem.hpp, eventually add
namespace fs = ghc::filesystem;
and use it like it is std::filesystem. It is also possible to separate parts of the implementation into a cpp by using the additional header files, the readme explains how to do that.
Note: It was implemented with utf8-everywhere in mind, but has an option to enable std::wstring interfaces on Windows as specified by the standard. The std::string_view related functions are limited to C++17, as it doesn't include a backport of std::string_view.
More details can be found in the readme under differences in api.
I am trying to compile a fortran code with gnu-autotools. The openmp specific lines in configure.ac is:
AC_PROG_FC([gfortran])
AC_OPENMP
FCFLAGS="$OPENMP_FCFLAGS -fcheck=all"
If I compile with this, I am not getting omp related compiler options, as described in the AC_OPENMP macro in autoconf manual.
If I explicitly place -fopenmp in place of $OPENMP_FFLAGS, only then its working.
Any help please?
Autoconf typically likes testing everything for C language by default and that's why you're only getting $OPENMP_CFLAGS as a result for the AC_OPENMP command. However, Autoconf also provides mechanisms to change the programming language (and therefore the compiler also) by using the AC_LANG command (please, take a look at Autoconf / Language Choice webpage for further details and also some alternatives).
The following code has been tested using the command autoconf 2.69 and using the command: autoreconf -fiv (also using an empty Makefile.am file).
AC_INIT([omp-fortran-sample], [1.0])
AC_PROG_CC
AC_PROG_FC([gfortran])
dnl Checks for OpenMP flag for C language, stores it in $OPENMP_CFLAGS
AC_LANG(C)
AC_OPENMP
dnl Checks for OpenMP flag for Fortran language, stores it in $OPENMP_FCFLAGS
AC_LANG(Fortran)
AC_OPENMP
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
The resulting execution of the configure shows two tests for OpenMP as seen here:
checking for gcc option to support OpenMP... -fopenmp
checking for gfortran option to support OpenMP... -fopenmp
And Makefile now includes both OPENMP_CFLAGS and OPENMP_FCFLAGS definitions, among the rest, as shown below:
...
MKDIR_P = /bin/mkdir -p
OBJEXT = o
OPENMP_CFLAGS = -fopenmp
OPENMP_FCFLAGS = -fopenmp
PACKAGE = omp-fortran-sample
...
There are utilities which use an existing compiler by adding a command as a prefix (so instead of calling cc -c file.c you could call distcc cc -c file.c).
When using CMake the compiler command can be changed, however I ran into problems trying to use distcc, though this would likely apply to any command prefix to the compiler (ccache too).
CMake expects the compiler to be an absolute path,so setting CMAKE_C_COMPILER to /usr/bin/distcc /usr/bin/cc, gives an error:
/usr/bin/distcc /usr/bin/cc
is not a full path to an existing compiler tool.
Setting the compiler to /usr/bin/distcc andCMAKE_C_COMPILER_ARG1 or CMAKE_C_FLAGS to begin with /usr/bin/cc works in some cases, but fails with CHECK_C_SOURCE_COMPILES(checked if there was some way to support this, even prefixing CMAKE_REQUIRED_FLAGS didn't work).
The only way I found to do this is to wrap the commands in a shell script.
#!/bin/sh
exec /usr/bin/distcc /usr/bin/cc "$#"
While this works, It would be nice to be able to use compiler helpers with CMake, without having to go though shell scripts (giving some small overhead when the build system could just use a command prefix).
So my question is:
Can CMake use compiler prefix commands (such as distcc) directly?, without shell script wrappers?
Since CMake 3.4.0 there has been a CMAKE_<LANG>_COMPILER_LAUNCHER variable and corresponding target property <LANG>_COMPILER_LAUNCHER. So if your project is C-only you would do something like:
cmake -DCMAKE_C_COMPILER_LAUNCHER=ccache /path/to/source
CCACHE_PREFIX=distcc make -j`distcc -j`
If you have a C++ project, use -DCMAKE_CXX_COMPILER_LAUNCHER=ccache.
Or, make your CMakeLists.txt smart and use ccache automatically if it can be found:
#-----------------------------------------------------------------------------
# Enable ccache if not already enabled by symlink masquerading and if no other
# CMake compiler launchers are already defined
#-----------------------------------------------------------------------------
find_program(CCACHE_EXECUTABLE ccache)
mark_as_advanced(CCACHE_EXECUTABLE)
if(CCACHE_EXECUTABLE)
foreach(LANG C CXX)
if(NOT DEFINED CMAKE_${LANG}_COMPILER_LAUNCHER AND NOT CMAKE_${LANG}_COMPILER MATCHES ".*/ccache")
message(STATUS "Enabling ccache for ${LANG}")
set(CMAKE_${LANG}_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE} CACHE STRING "")
endif()
endforeach()
endif()
Just as a hint: never use <LANG>_COMPILER_LAUNCHER to cross compile. If <LANG>_COMPILER_LAUNCHER is used together with distcc the absolute compiler path is sent to distcc and the host is not using the cross comping toolchain!
Instead you should use the old school method, just overwrite the compiler path:
export PATH=/usr/lib/distcc:$PATH
It took me hours to find out...
I'm writing my first configure.ac and need to search for a C++ library.
I tried the following line, but when run the configure script, it finds nothing.
AC_SEARCH_LIBS([xmlpp::Document::get_root_node], [xml++-2.6])
Probably something is wrong with it. So, how can I make autoconf look for C++ libraries? I don't want to supply a global method (and don't think libxml++ has one either).
You might want to try AX_CXX_CHECK_LIB from the Autoconf macro archive. you should probably make sure that you either use AC_LANG([C++]) or surround the call with AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]).
This link is about finding a C-style signature function to the library so that it can be tested by autoconf or write your own test:
https://nerdland.net/2009/07/detecting-c-libraries-with-autotools/
Maybe worth to try, but I am getting an error with the AC_LANG_PROGRAM macro. The problem is put -llibname before the foo.cpp file. My compiler cares about the order of the -l and cpp file. The linker will not be able to find the function in the library.
Hope this helps. My suggestion would be to use CMake instead of Autoconf.
This CMakeLists.txt file should get you started:
cmake_minimum_required(VERSION 2.8)
# http://www.cmake.org/cmake/help/cmake-2-8-docs.html#module:FindLibXml2
find_package(libxml2 2.6 REQUIRED) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:find_package
include_directories(${LIBXML2_INCLUDE_DIR}) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:include_directories
add_executable(myApp main.cpp other.cpp) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_executable
target_link_libraries(myApp ${LIBXML2_LIBRARIES}) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:target_link_libraries
To use the file, after adjusting for your project of course. Put it in your Source dir as CMakeLists.txt, then:
mkdir build
cd build
cmake .. # This is like autoconf and generates the make files
make
If it sounds intriguing check out the giant youtube vid on all the benefits: http://www.youtube.com/watch?v=8Ut9o4OdSC0
It's good to use CMake, CTest, CDash, and CPack together in a project.
I would like to do the following: If CCache is present in PATH, use "ccache g++" for compilation, else use g++. I tried writing a small my-cmake script containing
CC="ccache gcc" CXX="ccache g++" cmake $*
but it does not seem to work (running make still does not use ccache; I checked this using CMAKE_VERBOSE_MAKEFILE on).
Update:
As per this link I tried changing my script to
cmake -D CMAKE_CXX_COMPILER="ccache" -D CMAKE_CXX_COMPILER_ARG1="g++" -D CMAKE_C_COMPILER="ccache" -D CMAKE_C_COMPILER_ARG1="gcc" $*
but cmake bails out complaining that a test failed on using the compiler ccache (which can be expected).
As of CMAKE 3.4 you can do:
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
It is now possible to specify ccache as a launcher for compile commands and link commands (since cmake 2.8.0). That works for Makefile and Ninja generator. To do this, just set the following properties :
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) # Less useful to do it for linking, see edit2
endif(CCACHE_FOUND)
It is also possible to set these properties only for specific directories or targets.
For Ninja, this is possible since version 3.4.
For XCode, Craig Scott gives a workaround in his answer.
Edit : Thanks to uprego and Lekensteyn's comment, I edited the answer to check if ccache is available before using it as launcher and for which generators is it possible to use a compile launcher.
Edit2: #Emilio Cobos recommended to avoid doing that for the linking part as ccache doesn't improve linking speed and can mess with other types of cache like sccache
I personally have /usr/lib/ccache in my $PATH. This directory contains loads of symlinks for every possible name the compiler could be called from (like gcc and gcc-4.3), all pointing to ccache.
And I didn't even create the symlinks. That directory comes pre-filled when I install ccache on Debian.
From CMake 3.1, it is possible to use ccache with the Xcode generator and Ninja is supported from CMake 3.4 onwards. Ninja will honour RULE_LAUNCH_COMPILE just like the Unix Makefiles generator (so #Babcool's answer gets you there for Ninja too), but getting ccache working for the Xcode generator takes a little more work. The following article explains the method in detail, focussing on a general implementation which works for all three CMake generators and making no assumptions about setting up ccache symlinks or the underlying compiler used (it still lets CMake decide the compiler):
https://crascit.com/2016/04/09/using-ccache-with-cmake/
The general gist of the article is as follows. The start of your CMakeLists.txt file should be set up something like this:
cmake_minimum_required(VERSION 2.8)
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
# Support Unix Makefiles and Ninja
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
endif()
project(SomeProject)
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
if(RULE_LAUNCH_COMPILE AND CMAKE_GENERATOR STREQUAL "Xcode")
# Set up wrapper scripts
configure_file(launch-c.in launch-c)
configure_file(launch-cxx.in launch-cxx)
execute_process(COMMAND chmod a+rx
"${CMAKE_BINARY_DIR}/launch-c"
"${CMAKE_BINARY_DIR}/launch-cxx")
# Set Xcode project attributes to route compilation through our scripts
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
endif()
The two script template files launch-c.in and launch-cxx.in look like this (they should be in the same directory as the CMakeLists.txt file):
launch-c.in:
#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_C_COMPILER}" "$#"
launch-cxx.in:
#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_CXX_COMPILER}" "$#"
The above uses RULE_LAUNCH_COMPILE alone for Unix Makefiles and Ninja, but for the Xcode generator it relies on help from CMake's CMAKE_XCODE_ATTRIBUTE_... variables support. The setting of the CC and CXX user-defined Xcode attributes to control the compiler command and LD and LDPLUSPLUS for the linker command is not, as far as I can tell, a documented feature of Xcode projects, but it does seem to work. If anyone can confirm it is officially supported by Apple, I'll update the linked article and this answer accordingly.
I didn't like to set a symlink from g++ to ccache. And CXX="ccache g++" didn't work for me as some cmake test case wanted to have just the compiler program without attributes.
So I used a small bash script instead:
#!/bin/bash
ccache g++ "$#"
and saved it as an executable in /usr/bin/ccache-g++.
Then C configured cmake to use /usr/bin/ccache-g++ as C++ compiler.
This way it passes the cmake test cases and I feel more comfortable than having symlinks that I might forget about in 2 or 3 weeks and then maybe wonder if something doesn't work...
I verified the following works (source: this link):
CC="gcc" CXX="g++" cmake -D CMAKE_CXX_COMPILER="ccache" -D CMAKE_CXX_COMPILER_ARG1="g++" -D CMAKE_C_COMPILER="ccache" -D CMAKE_C_COMPILER_ARG1="gcc" $*
Update: I later realized that even this does not work. Strangely it works every alternate time (the other times cmake complains).
Let me add one important item that was not mentioned here before.
While bootstrapping a minimalistic build system from the ubuntu:18.04 docker image, I've found that order of installation makes a difference.
In my case ccache worked fine when calling gcc, but failed to catch invocations of the same compiler by the other names: cc and c++.
To fully install ccache, you need to make sure all compilers are installed first, or add a call to update-ccache symlinks to be safe.
sudo /usr/sbin/update-ccache-symlinks
export PATH="/usr/lib/ccache/:$PATH"```
... and then (due to updated symlinks) also calls to cc and c++ get caught!
In my opinion the best way is to symlink gcc,g++ to ccache, but if you would like to use within cmake, try this:
export CC="ccache gcc" CXX="ccache g++" cmake ...
Here are 2 methods I think are clean/robust, and also don't pollute your CMake code.
1.) Set environment variables
This method is nice since you don't have to individually set it up for each CMake project. The con is you may not want ccache for each CMake project.
# Requires CMake 3.17 (https://cmake.org/cmake/help/latest/envvar/CMAKE_LANG_COMPILER_LAUNCHER.html)
export CMAKE_CXX_COMPILER_LAUNCHER=/usr/bin/ccache
export CMAKE_C_COMPILER_LAUNCHER=/usr/bin/ccache
2.) Pass in cache variables during project configuration
Con a bit annoying to do for each project. This can be negated by your IDE though.
# Requires CMake 3.4
$ cmake ... -D CMAKE_CXX_COMPILER_LAUNCHER=/usr/bin/ccache \
-D CMAKE_C_COMPILER_LAUNCHER=/usr/bin/ccache
NOTE: It isn't really necessary to specify the full path.
If ccache is in your path you can just specify ccache instead.
export CMAKE_CXX_COMPILER_LAUNCHER=ccache
export CMAKE_C_COMPILER_LAUNCHER=ccache
It is extending #Nicolas answer.
Add following line to your cmake file:
list(PREPEND CMAKE_PROGRAM_PATH /usr/lib/ccache)
Or add it as argument to cmake configuration step:
cmake -DCMAKE_PROGRAM_PATH=/usr/lib/ccache