diff --git a/Makefile b/Makefile index a8df1846..d6499c05 100644 --- a/Makefile +++ b/Makefile @@ -470,6 +470,13 @@ ICG: TRICK_SYSTEM_CXXFLAGS := $(subst -isystem,-I,$(TRICK_SYSTEM_CXXFLAGS)) ICG: $(ICG_EXE) $(ICG_EXE) -f -s -m -n ${TRICK_CXXFLAGS} ${TRICK_SYSTEM_CXXFLAGS} ${TRICK_HOME}/include/trick/files_to_ICG.hh + +ICG_EXE: force-icg-build + +.PHONY: force-icg-build +force-icg-build: + $(MAKE) -C trick_source/codegen/Interface_Code_Gen + # This builds a tricklib share library. trick_lib: $(SIM_SERV_DIRS) $(UTILS_DIRS) | $(TRICK_LIB_DIR) ${TRICK_CXX} $(SHARED_LIB_OPT) -o ${TRICK_LIB_DIR}/libtrick.so $(SIM_SERV_OBJS) $(UTILS_OBJS) diff --git a/docs/documentation/building_a_simulation/Making-the-Simulation.md b/docs/documentation/building_a_simulation/Making-the-Simulation.md index e506a27e..9586cc44 100644 --- a/docs/documentation/building_a_simulation/Making-the-Simulation.md +++ b/docs/documentation/building_a_simulation/Making-the-Simulation.md @@ -91,6 +91,16 @@ Edit a file called "S_overrides.mk". Append to the TRICK_EXCLUDE variable. TRICK_EXCLUDE += /path/to/exclude:/another/path/to/exclude ``` +### Example how to set a C++ standard for ICG and compilation + +Edit a file called "S_overrides.mk". Append to the TRICK_CXXFLAGS variable. + +``` +TRICK_CXXFLAGS += -std=c++11 +``` + +Valid options are c++11, c++14, c++17, or c++20. ICG will parse to c++17 by default, or the newest supported version if c++17 is not availible. + ## Cleaning Up There are several levels of clean. diff --git a/trick_source/codegen/Interface_Code_Gen/main.cpp b/trick_source/codegen/Interface_Code_Gen/main.cpp index b1371b5c..0c431059 100644 --- a/trick_source/codegen/Interface_Code_Gen/main.cpp +++ b/trick_source/codegen/Interface_Code_Gen/main.cpp @@ -38,6 +38,7 @@ llvm::cl::opt units_truth_is_scary("units-truth-is-scary", llvm::cl::desc( llvm::cl::opt sim_services_flag("sim_services", llvm::cl::desc("Gernerate io_src for Trick core headers")); llvm::cl::opt force("force", llvm::cl::desc("Force all io_src files to be generated")); llvm::cl::opt attr_version("v", llvm::cl::desc("Select version of attributes to produce. 10 and 13 are valid"), llvm::cl::init(10)); +llvm::cl::opt standard_version("std", llvm::cl::desc("Set the C++ standard to use when parsing. c++11, c++14, c++17, and c++20 are valid. Default is c++17 or the newest supported by your LLVM version."), llvm::cl::init(""), llvm::cl::ZeroOrMore); llvm::cl::opt debug_level("d", llvm::cl::desc("Set debug level"), llvm::cl::init(0), llvm::cl::ZeroOrMore); llvm::cl::opt create_map("m", llvm::cl::desc("Create map files"), llvm::cl::init(false)); llvm::cl::opt output_dir("o", llvm::cl::desc("Output directory")); @@ -57,12 +58,48 @@ void set_lang_opts(clang::CompilerInstance & ci) { ci.getLangOpts().Bool = true ; ci.getLangOpts().WChar = true ; ci.getLangOpts().CPlusPlus = true ; - ci.getLangOpts().CPlusPlus11 = true ; ci.getLangOpts().CXXOperatorNames = true ; + + // Always use at least C++11 + ci.getLangOpts().CPlusPlus11 = true ; + + +#if (LIBCLANG_MAJOR < 6) + // Check if standard_version was specified and if it's a version that is supported by this libclang + if (standard_version != "") { + if (standard_version == "c++11") { + // Nothing to be done here really + } else if (standard_version == "c++14" || standard_version == "c++17" || standard_version == "c++20") { + std::cerr << "C++ standard " << standard_version << " is not supported by this version of Clang." << std::endl; + } else { + std::cerr << "Invalid C++ standard version specified:" << standard_version << std::endl; + } + } +#endif + + // Activate C++14 parsing #if (LIBCLANG_MAJOR >= 6) ci.getLangOpts().CPlusPlus14 = true ; - ci.getLangOpts().DoubleSquareBracketAttributes = true ; + ci.getLangOpts().DoubleSquareBracketAttributes = true ; #endif + +#if (LIBCLANG_MAJOR >= 6 && LIBCLANG_MAJOR < 10) + // Check if standard_version was specified and if it's a version that is supported by this libclang + if (standard_version != "") { + if (standard_version == "c++11") { + // Turn off c++14, c++11 is already on + ci.getLangOpts().CPlusPlus14 = false ; + } else if (standard_version == "c++14") { + // Nothing to be done here + }else if (standard_version == "c++17" || standard_version == "c++20") { + std::cerr << "C++ standard " << standard_version << " is not supported by this version of Clang." << std::endl; + } else { + std::cerr << "Invalid C++ standard version specified:" << standard_version << std::endl; + } + } +#endif + + // Activate C++17 parsing #ifdef TRICK_GCC_VERSION const char * gcc_version = TRICK_GCC_VERSION; @@ -73,6 +110,24 @@ const char * gcc_version = ""; #if (LIBCLANG_MAJOR >= 10) ci.getLangOpts().GNUCVersion = gccVersionToIntOrDefault(gcc_version, 40805); ci.getLangOpts().CPlusPlus17 = true ; + + // Check if standard_version was specified and if it's a version that is supported by this libclang + if (standard_version != "") { + if (standard_version == "c++11") { + ci.getLangOpts().CPlusPlus14 = false ; + ci.getLangOpts().CPlusPlus17 = false ; + } else if (standard_version == "c++14") { + ci.getLangOpts().CPlusPlus17 = false ; + } else if (standard_version == "c++17" ) { + // Nothing to do here + } else if (standard_version == "c++20") { + // It looks like Clang10 was the first to offer the "c++20" flag, but there was partial support before that. + // (https://clang.llvm.org/cxx_status.html) + ci.getLangOpts().CPlusPlus20 = true ; + } else { + std::cerr << "Invalid C++ standard version specified:" << standard_version << std::endl; + } + } #endif } /**