Debajit
Debajit

Reputation: 47141

Building C++11 with TextMate?

With a regular C++98 program, to run it from TextMate, all I need to do is a ⌘R to run it from TextMate. With C++11, however that does not work out of the box. For instance if I have the following program:

#include <iostream>
using namespace std;

int main()
{
    for (auto i : {1, 2, 3})
        cout << i << " ";

    cout << "\n";
}

Then doing a ⌘R results in the following C++11 build errors:

untitled:6:10: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
    for (auto i : {1, 2, 3})
         ^
untitled:6:17: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
    for (auto i : {1, 2, 3})
                ^
untitled:6:19: error: cannot deduce type of initializer list because std::initializer_list was not found; include <initializer_list>
    for (auto i : {1, 2, 3})
                  ^
2 warnings and 1 error generated.

This program runs fine in Xcode or with a simple make (I have a export CXXFLAGS="-std=c++0x” in my .bashrc which takes care of make). I can also build it from the command-line with a clang++ -std=c++11 test.cpp, so this is not a compiler issue, but something to do with my TextMate configuration.

Looking at the TextMate Run bundle, I can see that it references TM_CXX_FLAGS. From TextMate Preferences, I appended -std=c++0x and -Wc++11-extensions to TM_CXX_FLAGS. That did not seem to help.

Clearly I’m overlooking something obvious here.

Any pointers on how I could fix this?

Upvotes: 2

Views: 1553

Answers (2)

Allan Odgaard
Allan Odgaard

Reputation: 464

The default variables in Preferences → Variables are disabled by default.

So you need to enable TM_CXX_FLAGS by checking the check box in the left-most column.

Upvotes: 2

Debajit
Debajit

Reputation: 47141

I was able to work-around this by adding -std=c++11 in the Run bundle, which seems a little roundabout. Is there a way I could update TM_CXX_FLAGS globally? (Currently TextMate does not seem to pick up my changes to TM_CXX_FLAGS set in TextMate Preferences)

Here is my current workaround: (This is my Run bundle. The only change I made is adding the -std=c++11)

#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby

require "#{ENV['TM_SUPPORT_PATH']}/lib/tm/executor"
require "#{ENV['TM_SUPPORT_PATH']}/lib/tm/save_current_document"
require "shellwords"

CONFIG = {
  'source.c'      => [ ENV['TM_GCC'] || 'xcrun clang',   "-x c             #{ENV['TM_C_FLAGS']      || '-Wall -include stdio.h'}",                                    'c'  ],
  'source.cc'     => [ ENV['TM_GXX'] || 'xcrun clang++', "-x c++ -std=c++11          #{ENV['TM_CXX_FLAGS']    || '-Wall -include stdio.h -include iostream -Wc++11-extensions'}",                  'cc' ],
  'source.c++'    => [ ENV['TM_GXX'] || 'xcrun clang++', "-x c++ -std=c++11          #{ENV['TM_CXX_FLAGS']    || '-Wall -include stdio.h -include iostream -Wc++11-extensions'}",                  'cc' ],
  'source.objc'   => [ ENV['TM_GCC'] || 'xcrun clang',   "-x objective-c   #{ENV['TM_OBJC_FLAGS']   || '-Wall -include stdio.h -framework Cocoa'}",                   'm'  ],
  'source.objc++' => [ ENV['TM_GXX'] || 'xcrun clang++', "-x objective-c++ #{ENV['TM_OBJCXX_FLAGS'] || '-Wall -include stdio.h -include iostream -framework Cocoa'}", 'mm' ],
}

cc, flags, ext = *CONFIG['source.objc++'] # default
cc, flags, ext = *CONFIG[$&] if ENV["TM_SCOPE"] =~ /\bsource\.(obj)?c(\+\+)?/

TextMate.save_if_untitled(ext)
TextMate::Executor.make_project_master_current_document
args = Shellwords.split(cc) << Shellwords.split(flags) << ENV["TM_FILEPATH"]
TextMate::Executor.run(args, :version_args => ["--version"], :version_regex => /\A([^\n]*) \(GCC\).*/m)

Upvotes: 2

Related Questions