diff options
31 files changed, 368 insertions, 151 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index e4d2a9a..6623959 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -310,6 +310,8 @@ endmacro() # Simply to improve readability of the main script. #----------------------------------------------------------------------- macro (CMAKE_BUILD_UTILITIES) + find_package(Threads) + #--------------------------------------------------------------------- # Create the kwsys library for CMake. set(KWSYS_NAMESPACE cmsys) diff --git a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst index f522c6b..7d3dfd1 100644 --- a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst +++ b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst @@ -3,15 +3,29 @@ AUTOGEN_TARGET_DEPENDS Target dependencies of the corresponding ``_autogen`` target. -Targets which have their :prop_tgt:`AUTOMOC` target ``ON`` have a -corresponding ``_autogen`` target which is used to autogenerate generate moc -files. As this ``_autogen`` target is created at generate-time, it is not -possible to define dependencies of it, such as to create inputs for the ``moc`` -executable. +Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property +``ON`` have a corresponding ``_autogen`` target which is used to auto generate +``moc`` and ``uic`` files. As this ``_autogen`` target is created at +generate-time, it is not possible to define dependencies of it, +such as to create inputs for the ``moc`` or ``uic`` executable. -The ``AUTOGEN_TARGET_DEPENDS`` target property can be set instead to a list of -dependencies for the ``_autogen`` target. The buildsystem will be generated to -depend on its contents. +The :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property can be set instead to a +list of dependencies of the ``_autogen`` target. Dependencies can be target +names or file names. See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. + +Use cases +^^^^^^^^^ + +If :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` depends on a file that is either + +- a :prop_sf:`GENERATED` non C++ file (e.g. a :prop_sf:`GENERATED` ``.json`` + or ``.ui`` file) or +- a :prop_sf:`GENERATED` C++ file that isn't recognized by :prop_tgt:`AUTOMOC` + and :prop_tgt:`AUTOUIC` because it's skipped by :prop_sf:`SKIP_AUTOMOC`, + :prop_sf:`SKIP_AUTOUIC`, :prop_sf:`SKIP_AUTOGEN` or :policy:`CMP0071` or +- a file that isn't in the target's sources + +it must added to :prop_tgt:`AUTOGEN_TARGET_DEPENDS`. diff --git a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst index b738ecf..69957bf 100644 --- a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst +++ b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst @@ -1,21 +1,27 @@ AUTOMOC_DEPEND_FILTERS ---------------------- -Filter definitions used by :prop_tgt:`AUTOMOC` to extract file names from -source code as additional dependencies for the ``moc`` file. - -This property is only used if the :prop_tgt:`AUTOMOC` property is ``ON`` -for this target. +Filter definitions used by :prop_tgt:`AUTOMOC` to extract file names from a +source file that are registered as additional dependencies for the +``moc`` file of the source file. Filters are defined as ``KEYWORD;REGULAR_EXPRESSION`` pairs. First the file content is searched for ``KEYWORD``. If it is found at least once, then file names are extracted by successively searching for ``REGULAR_EXPRESSION`` and taking the first match group. -Consider a filter extracts the file name ``DEP`` from the content of a file -``FOO``. If ``DEP`` changes, then the ``moc`` file for ``FOO`` gets rebuilt. -The file ``DEP`` is searched for first in the vicinity -of ``FOO`` and afterwards in the target's :prop_tgt:`INCLUDE_DIRECTORIES`. +The file name found in the first match group is searched for + +- first in the vicinity of the source file +- and afterwards in the target's :prop_tgt:`INCLUDE_DIRECTORIES`. + +If any of the extracted files changes, then the ``moc`` file for the source +file gets rebuilt even when the source file itself doesn't change. + +If any of the extracted files is :prop_sf:`GENERATED` or if it is not in the +target's sources, then it might be necessary to add it to the +``_autogen`` target dependencies. +See :prop_tgt:`AUTOGEN_TARGET_DEPENDS` for reference. By default :prop_tgt:`AUTOMOC_DEPEND_FILTERS` is initialized from :variable:`CMAKE_AUTOMOC_DEPEND_FILTERS`, which is empty by default. @@ -24,22 +30,75 @@ See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. -Example -^^^^^^^ +Example 1 +^^^^^^^^^ -Consider a file ``FOO.hpp`` holds a custom macro ``OBJ_JSON_FILE`` and we -want the ``moc`` file to depend on the macro`s file name argument:: +A header file ``my_class.hpp`` uses a custom macro ``JSON_FILE_MACRO`` which +is defined in an other header ``macros.hpp``. +We want the ``moc`` file of ``my_class.hpp`` to depend on the file name +argument of ``JSON_FILE_MACRO``:: + // my_class.hpp class My_Class : public QObject { Q_OBJECT - OBJ_JSON_FILE ( "DEP.json" ) + JSON_FILE_MACRO ( "info.json" ) + ... + }; + +In ``CMakeLists.txt`` we add a filter to +:variable:`CMAKE_AUTOMOC_DEPEND_FILTERS` like this:: + + list( APPEND CMAKE_AUTOMOC_DEPEND_FILTERS + "JSON_FILE_MACRO" + "[\n][ \t]*JSON_FILE_MACRO[ \t]*\\([ \t]*\"([^\"]+)\"" + ) + +We assume ``info.json`` is a plain (not :prop_sf:`GENERATED`) file that is +listed in the target's source. Therefore we do not need to add it to +:prop_tgt:`AUTOGEN_TARGET_DEPENDS`. + +Example 2 +^^^^^^^^^ + +In the target ``my_target`` a header file ``complex_class.hpp`` uses a +custom macro ``JSON_BASED_CLASS`` which is defined in an other header +``macros.hpp``:: + + // macros.hpp ... + #define JSON_BASED_CLASS(name, json) \ + class name : public QObject \ + { \ + Q_OBJECT \ + Q_PLUGIN_METADATA(IID "demo" FILE json) \ + name() {} \ }; + ... + +:: -Then we might use :variable:`CMAKE_AUTOMOC_DEPEND_FILTERS` to -define a filter like this:: + // complex_class.hpp + #pragma once + JSON_BASED_CLASS(Complex_Class, "meta.json") + // end of file - set(CMAKE_AUTOMOC_DEPEND_FILTERS - "OBJ_JSON_FILE" "[\n][ \t]*OBJ_JSON_FILE[ \t]*\\([ \t]*\"([^\"]+)\"" +Since ``complex_class.hpp`` doesn't contain a ``Q_OBJECT`` macro it would be +ignored by :prop_tgt:`AUTOMOC`. We change this by adding ``JSON_BASED_CLASS`` +to :variable:`CMAKE_AUTOMOC_MACRO_NAMES`:: + + list(APPEND CMAKE_AUTOMOC_MACRO_NAMES "JSON_BASED_CLASS") + +We want the ``moc`` file of ``complex_class.hpp`` to depend on +``meta.json``. So we add a filter to +:variable:`CMAKE_AUTOMOC_DEPEND_FILTERS`:: + + list(APPEND CMAKE_AUTOMOC_DEPEND_FILTERS + "JSON_BASED_CLASS" + "[\n^][ \t]*JSON_BASED_CLASS[ \t]*\\([^,]*,[ \t]*\"([^\"]+)\"" ) + +Additionally we assume ``meta.json`` is :prop_sf:`GENERATED` which is +why we have to add it to :prop_tgt:`AUTOGEN_TARGET_DEPENDS`:: + + set_property(TARGET my_target APPEND PROPERTY AUTOGEN_TARGET_DEPENDS "meta.json") diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake index cf502f6..5ddd64f 100644 --- a/Modules/CMakeDetermineFortranCompiler.cmake +++ b/Modules/CMakeDetermineFortranCompiler.cmake @@ -66,12 +66,20 @@ else() # The order is 95 or newer compilers first, then 90, # then 77 or older compilers, gnu is always last in the group, # so if you paid for a compiler it is picked by default. - set(CMAKE_Fortran_COMPILER_LIST - ftn - ifort ifc af95 af90 efc f95 pathf2003 pathf95 pgf95 pgfortran lf95 xlf95 - fort flang gfortran gfortran-4 g95 f90 pathf90 pgf90 xlf90 epcf90 fort77 - frt pgf77 xlf fl32 af77 g77 f77 nag - ) + if(CMAKE_HOST_WIN32) + set(CMAKE_Fortran_COMPILER_LIST + ifort pgf95 pgfortran lf95 fort + flang gfortran gfortran-4 g95 f90 pgf90 + pgf77 g77 f77 nag + ) + else() + set(CMAKE_Fortran_COMPILER_LIST + ftn + ifort ifc efc pgf95 pgfortran lf95 xlf95 fort + flang gfortran gfortran-4 g95 f90 pgf90 + frt pgf77 xlf g77 f77 nag + ) + endif() # Vendor-specific compiler names. set(_Fortran_COMPILER_NAMES_GNU gfortran gfortran-4 g95 g77) diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index ece0547..1b6823c 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -19,6 +19,25 @@ # on UNIX, cygwin and mingw +if(CMAKE_LINKER) + # we only get here if CMAKE_LINKER was specified using -D or a pre-made CMakeCache.txt + # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE + # find the linker in the PATH if necessary + get_filename_component(_CMAKE_USER_LINKER_PATH "${CMAKE_LINKER}" PATH) + if(NOT _CMAKE_USER_LINKER_PATH) + find_program(CMAKE_LINKER_WITH_PATH NAMES ${CMAKE_LINKER} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) + if(CMAKE_LINKER_WITH_PATH) + set(CMAKE_LINKER ${CMAKE_LINKER_WITH_PATH}) + get_property(_CMAKE_LINKER_CACHED CACHE CMAKE_LINKER PROPERTY TYPE) + if(_CMAKE_LINKER_CACHED) + set(CMAKE_LINKER "${CMAKE_LINKER}" CACHE STRING "Default Linker" FORCE) + endif() + unset(_CMAKE_LINKER_CACHED) + endif() + unset(CMAKE_LINKER_WITH_PATH CACHE) + endif() +endif() + # if it's the MS C/CXX compiler, search for link if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC" OR "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xMSVC" diff --git a/Modules/FindLua.cmake b/Modules/FindLua.cmake index b59b9b3..7eba206 100644 --- a/Modules/FindLua.cmake +++ b/Modules/FindLua.cmake @@ -122,6 +122,7 @@ endif () if (NOT LUA_VERSION_STRING) foreach (subdir IN LISTS _lua_include_subdirs) unset(LUA_INCLUDE_PREFIX CACHE) + unset(LUA_INCLUDE_PREFIX) find_path(LUA_INCLUDE_PREFIX ${subdir}/lua.h HINTS ENV LUA_DIR diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake index e21ec38..965948e 100644 --- a/Modules/FindwxWidgets.cmake +++ b/Modules/FindwxWidgets.cmake @@ -837,7 +837,7 @@ else() # extract linkdirs (-L) for rpath (i.e., LINK_DIRECTORIES) string(REGEX MATCHALL "-L[^;]+" wxWidgets_LIBRARY_DIRS "${wxWidgets_LIBRARIES}") - string(REPLACE "-L" "" + string(REGEX REPLACE "-L([^;]+)" "\\1" wxWidgets_LIBRARY_DIRS "${wxWidgets_LIBRARY_DIRS}") DBG_MSG_V("wxWidgets_LIBRARIES=${wxWidgets_LIBRARIES}") diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index e7c0732..a0010a2 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -765,6 +765,7 @@ target_link_libraries(CMakeLib cmsys ${CMAKE_LIBUV_LIBRARIES} ${CMAKE_LIBRHASH_LIBRARIES} ${CMake_KWIML_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} ) if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "sparc") diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 1477f0d..f1fdb60 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 11) -set(CMake_VERSION_PATCH 20180220) +set(CMake_VERSION_PATCH 20180226) #set(CMake_VERSION_RC 1) diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 92dac79..0561799 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -7,6 +7,7 @@ #include <stddef.h> #include <string> +#include <utility> #include <vector> struct cmGeneratorExpressionContext; @@ -64,17 +65,16 @@ private: struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator { GeneratorExpressionContent(const char* startContent, size_t length); - void SetIdentifier( - std::vector<cmGeneratorExpressionEvaluator*> const& identifier) + + void SetIdentifier(std::vector<cmGeneratorExpressionEvaluator*> identifier) { - this->IdentifierChildren = identifier; + this->IdentifierChildren = std::move(identifier); } void SetParameters( - std::vector<std::vector<cmGeneratorExpressionEvaluator*>> const& - parameters) + std::vector<std::vector<cmGeneratorExpressionEvaluator*>> parameters) { - this->ParamChildren = parameters; + this->ParamChildren = std::move(parameters); } Type GetType() const override diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index 278de04..7b4dc7b 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -6,6 +6,7 @@ #include <assert.h> #include <stddef.h> +#include <utility> cmGeneratorExpressionParser::cmGeneratorExpressionParser( const std::vector<cmGeneratorExpressionToken>& tokens) @@ -92,7 +93,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( assert(this->it != this->Tokens.end()); ++this->it; --this->NestingLevel; - content->SetIdentifier(identifier); + content->SetIdentifier(std::move(identifier)); result.push_back(content); return; } @@ -198,8 +199,8 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( ((this->it - 1)->Content - startToken->Content) + (this->it - 1)->Length; GeneratorExpressionContent* content = new GeneratorExpressionContent(startToken->Content, contentLength); - content->SetIdentifier(identifier); - content->SetParameters(parameters); + content->SetIdentifier(std::move(identifier)); + content->SetParameters(std::move(parameters)); result.push_back(content); } diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index a4570e1..fa7dc51 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -737,26 +737,24 @@ bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly( bool cmGlobalVisualStudioGenerator::TargetIsCSharpOnly( cmGeneratorTarget const* gt) { - // check to see if this is a C# build - std::set<std::string> languages; - { - // Issue diagnostic if the source files depend on the config. - std::vector<cmSourceFile*> sources; - if (!gt->GetConfigCommonSourceFiles(sources)) { - return false; - } - // Only "real" targets are allowed to be C# targets. - if (gt->Target->GetType() > cmStateEnums::OBJECT_LIBRARY) { - return false; - } + // C# targets can be defined with add_library() (using SHARED or STATIC) and + // also using add_executable(). We do not treat imported C# targets the same + // (these come in as UTILITY) + if (gt->GetType() != cmStateEnums::SHARED_LIBRARY && + gt->GetType() != cmStateEnums::STATIC_LIBRARY && + gt->GetType() != cmStateEnums::EXECUTABLE) { + return false; } - gt->GetLanguages(languages, ""); - if (languages.size() == 1) { - if (*languages.begin() == "CSharp") { - return true; - } + + // Issue diagnostic if the source files depend on the config. + std::vector<cmSourceFile*> sources; + if (!gt->GetConfigCommonSourceFiles(sources)) { + return false; } - return false; + + std::set<std::string> languages; + gt->GetLanguages(languages, ""); + return languages.size() == 1 && languages.count("CSharp") > 0; } bool cmGlobalVisualStudioGenerator::TargetCanBeReferenced( diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 2a38599..d3f5aac 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -459,7 +459,11 @@ void cmGlobalXCodeGenerator::AddExtraTargets( // Add ZERO_CHECK bool regenerate = !mf->IsOn("CMAKE_SUPPRESS_REGENERATION"); - if (regenerate) { + bool generateTopLevelProjectOnly = + mf->IsOn("CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY"); + bool isTopLevel = + !root->GetStateSnapshot().GetBuildsystemDirectoryParent().IsValid(); + if (regenerate && (isTopLevel || !generateTopLevelProjectOnly)) { this->CreateReRunCMakeFile(root, gens); std::string file = this->ConvertToRelativeForMake(this->CurrentReRunCMakeMakefile.c_str()); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index f4faf47..e18959b 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -856,9 +856,27 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( vars["FLAGS"] = this->ComputeFlagsForObject(source, language); vars["DEFINES"] = this->ComputeDefines(source, language); vars["INCLUDES"] = this->ComputeIncludes(source, language); + if (!this->NeedDepTypeMSVC(language)) { - vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat( - objectFileName + ".d", cmOutputConverter::SHELL); + bool replaceExt(false); + if (!language.empty()) { + std::string repVar = "CMAKE_"; + repVar += language; + repVar += "_DEPFILE_EXTENSION_REPLACE"; + replaceExt = this->Makefile->IsOn(repVar); + } + if (!replaceExt) { + // use original code + vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat( + objectFileName + ".d", cmOutputConverter::SHELL); + } else { + // Replace the original source file extension with the + // depend file extension. + std::string dependFileName = + cmSystemTools::GetFilenameWithoutLastExtension(objectFileName) + ".d"; + vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat( + objectFileDir + "/" + dependFileName, cmOutputConverter::SHELL); + } } this->ExportObjectCompileCommand( diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 92d67db..c7b60b9 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -856,10 +856,7 @@ void cmVisualStudio10TargetGenerator::WriteTargetSpecificReferences() void cmVisualStudio10TargetGenerator::WriteTargetsFileReferences() { - for (std::vector<TargetsFileAndConfigs>::iterator i = - this->TargetsFileAndConfigsVec.begin(); - i != this->TargetsFileAndConfigsVec.end(); ++i) { - TargetsFileAndConfigs const& tac = *i; + for (TargetsFileAndConfigs const& tac : this->TargetsFileAndConfigsVec) { this->WriteString("<Import Project=\"", 3); (*this->BuildFileStream) << tac.File << "\" "; (*this->BuildFileStream) << "Condition=\""; @@ -894,10 +891,9 @@ void cmVisualStudio10TargetGenerator::WriteWinRTReferences() } if (!references.empty()) { this->WriteString("<ItemGroup>\n", 1); - for (std::vector<std::string>::iterator ri = references.begin(); - ri != references.end(); ++ri) { + for (std::string const& ri : references) { this->WriteString("<Reference Include=\"", 2); - (*this->BuildFileStream) << cmVS10EscapeXML(*ri) << "\">\n"; + (*this->BuildFileStream) << cmVS10EscapeXML(ri) << "\">\n"; this->WriteString("<IsWinMDFile>true</IsWinMDFile>\n", 3); this->WriteString("</Reference>\n", 2); } @@ -910,13 +906,11 @@ void cmVisualStudio10TargetGenerator::WriteWinRTReferences() void cmVisualStudio10TargetGenerator::WriteProjectConfigurations() { this->WriteString("<ItemGroup Label=\"ProjectConfigurations\">\n", 1); - for (std::vector<std::string>::const_iterator i = - this->Configurations.begin(); - i != this->Configurations.end(); ++i) { + for (std::string const& c : this->Configurations) { this->WriteString("<ProjectConfiguration Include=\"", 2); - (*this->BuildFileStream) << *i << "|" << this->Platform << "\">\n"; + (*this->BuildFileStream) << c << "|" << this->Platform << "\">\n"; this->WriteString("<Configuration>", 3); - (*this->BuildFileStream) << *i << "</Configuration>\n"; + (*this->BuildFileStream) << c << "</Configuration>\n"; this->WriteString("<Platform>", 3); (*this->BuildFileStream) << cmVS10EscapeXML(this->Platform) << "</Platform>\n"; @@ -927,10 +921,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurations() void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() { - for (std::vector<std::string>::const_iterator i = - this->Configurations.begin(); - i != this->Configurations.end(); ++i) { - this->WritePlatformConfigTag("PropertyGroup", *i, 1, + for (std::string const& c : this->Configurations) { + this->WritePlatformConfigTag("PropertyGroup", c, 1, " Label=\"Configuration\"", "\n"); if (this->ProjectType != csproj) { @@ -977,12 +969,12 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() if (this->MSTools) { if (!this->Managed) { - this->WriteMSToolConfigurationValues(*i); + this->WriteMSToolConfigurationValues(c); } else { - this->WriteMSToolConfigurationValuesManaged(*i); + this->WriteMSToolConfigurationValuesManaged(c); } } else if (this->NsightTegra) { - this->WriteNsightTegraConfigurationValues(*i); + this->WriteNsightTegraConfigurationValues(c); } this->WriteString("</PropertyGroup>\n", 1); @@ -1132,10 +1124,8 @@ void cmVisualStudio10TargetGenerator::WriteCustomCommands() this->CSharpCustomCommandNames.clear(); std::vector<cmSourceFile const*> customCommands; this->GeneratorTarget->GetCustomCommands(customCommands, ""); - for (std::vector<cmSourceFile const*>::const_iterator si = - customCommands.begin(); - si != customCommands.end(); ++si) { - this->WriteCustomCommand(*si); + for (cmSourceFile const* si : customCommands) { + this->WriteCustomCommand(si); } // Add CMakeLists.txt file with rule to re-run CMake for user convenience. @@ -1154,9 +1144,8 @@ void cmVisualStudio10TargetGenerator::WriteCustomCommand( if (this->SourcesVisited.insert(sf).second) { if (std::vector<cmSourceFile*> const* depends = this->GeneratorTarget->GetSourceDepends(sf)) { - for (std::vector<cmSourceFile*>::const_iterator di = depends->begin(); - di != depends->end(); ++di) { - this->WriteCustomCommand(*di); + for (cmSourceFile const* di : *depends) { + this->WriteCustomCommand(di); } } if (cmCustomCommand const* command = sf->GetCustomCommand()) { @@ -1179,10 +1168,10 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( // VS 10 will always rebuild a custom command attached to a .rule // file that doesn't exist so create the file explicitly. if (source->GetPropertyAsBool("__CMAKE_RULE")) { - if (!cmSystemTools::FileExists(sourcePath.c_str())) { + if (!cmSystemTools::FileExists(sourcePath)) { // Make sure the path exists for the file std::string path = cmSystemTools::GetFilenamePath(sourcePath); - cmSystemTools::MakeDirectory(path.c_str()); + cmSystemTools::MakeDirectory(path); cmsys::ofstream fout(sourcePath.c_str()); if (fout) { fout << "# generated from CMake\n"; @@ -1216,20 +1205,17 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( this->WriteString("</None>\n", 2); this->WriteString("</ItemGroup>\n", 1); } - for (std::vector<std::string>::const_iterator i = - this->Configurations.begin(); - i != this->Configurations.end(); ++i) { - cmCustomCommandGenerator ccg(command, *i, lg); + for (std::string const& c : this->Configurations) { + cmCustomCommandGenerator ccg(command, c, lg); std::string comment = lg->ConstructComment(ccg); comment = cmVS10EscapeComment(comment); std::string script = cmVS10EscapeXML(lg->ConstructScript(ccg)); // input files for custom command std::stringstream inputs; inputs << cmVS10EscapeXML(source->GetFullPath()); - for (std::vector<std::string>::const_iterator d = ccg.GetDepends().begin(); - d != ccg.GetDepends().end(); ++d) { + for (std::string const& d : ccg.GetDepends()) { std::string dep; - if (lg->GetRealDependency(*d, *i, dep)) { + if (lg->GetRealDependency(d, c, dep)) { ConvertToWindowsSlash(dep); inputs << ";" << cmVS10EscapeXML(dep); } @@ -1237,15 +1223,14 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( // output files for custom command std::stringstream outputs; const char* sep = ""; - for (std::vector<std::string>::const_iterator o = ccg.GetOutputs().begin(); - o != ccg.GetOutputs().end(); ++o) { - std::string out = *o; + for (std::string const& o : ccg.GetOutputs()) { + std::string out = o; ConvertToWindowsSlash(out); outputs << sep << cmVS10EscapeXML(out); sep = ";"; } if (this->ProjectType == csproj) { - std::string name = "CustomCommand_" + *i + "_" + + std::string name = "CustomCommand_" + c + "_" + cmSystemTools::ComputeStringMD5(sourcePath); std::string inputs_s = inputs.str(); std::string outputs_s = outputs.str(); @@ -1253,10 +1238,10 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( script = cmVS10EscapeQuotes(script); inputs_s = cmVS10EscapeQuotes(inputs_s); outputs_s = cmVS10EscapeQuotes(outputs_s); - this->WriteCustomRuleCSharp(*i, name, script, inputs_s, outputs_s, + this->WriteCustomRuleCSharp(c, name, script, inputs_s, outputs_s, comment); } else { - this->WriteCustomRuleCpp(*i, script, inputs.str(), outputs.str(), + this->WriteCustomRuleCpp(c, script, inputs.str(), outputs.str(), comment); } } @@ -1314,8 +1299,8 @@ std::string cmVisualStudio10TargetGenerator::ConvertPath( { return forceRelative ? cmSystemTools::RelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), path.c_str()) - : path.c_str(); + this->LocalGenerator->GetCurrentBinaryDirectory(), path) + : path; } static void ConvertToWindowsSlash(std::string& s) @@ -1341,10 +1326,8 @@ void cmVisualStudio10TargetGenerator::WriteGroups() this->GeneratorTarget->GetAllConfigSources(); std::set<cmSourceGroup*> groupsUsed; - for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si = - sources.begin(); - si != sources.end(); ++si) { - std::string const& source = si->Source->GetFullPath(); + for (cmGeneratorTarget::AllConfigSource const& si : sources) { + std::string const& source = si.Source->GetFullPath(); cmSourceGroup* sourceGroup = this->Makefile->FindSourceGroup(source, sourceGroups); groupsUsed.insert(sourceGroup); @@ -1376,9 +1359,8 @@ void cmVisualStudio10TargetGenerator::WriteGroups() "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"); this->WriteString(project_defaults.c_str(), 0); - for (ToolSourceMap::const_iterator ti = this->Tools.begin(); - ti != this->Tools.end(); ++ti) { - this->WriteGroupSources(ti->first.c_str(), ti->second, sourceGroups); + for (auto const& ti : this->Tools) { + this->WriteGroupSources(ti.first.c_str(), ti.second, sourceGroups); } // Added files are images and the manifest. @@ -1510,7 +1492,7 @@ void cmVisualStudio10TargetGenerator::AddMissingSourceGroups( } void cmVisualStudio10TargetGenerator::WriteGroupSources( - const char* name, ToolSources const& sources, + std::string const& name, ToolSources const& sources, std::vector<cmSourceGroup>& sourceGroups) { this->WriteString("<ItemGroup>\n", 1); @@ -1847,7 +1829,7 @@ void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool, std::string sourceFile = this->ConvertPath(sf->GetFullPath(), forceRelative); if (this->LocalGenerator->GetVersion() == cmGlobalVisualStudioGenerator::VS10 && - cmSystemTools::FileIsFullPath(sourceFile.c_str())) { + cmSystemTools::FileIsFullPath(sourceFile)) { // Normal path conversion resulted in a full path. VS 10 (but not 11) // refuses to show the property page in the IDE for a source file with a // full path (not starting in a '.' or '/' AFAICT). CMake <= 2.8.4 used a @@ -2168,7 +2150,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( *source); } clOptions.AddIncludes(includeList); - clOptions.SetConfiguration(config.c_str()); + clOptions.SetConfiguration(config); clOptions.PrependInheritedString("AdditionalOptions"); clOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream, " ", "\n", lang); @@ -3451,6 +3433,17 @@ void cmVisualStudio10TargetGenerator::AddLibraries( std::string currentBinDir = this->LocalGenerator->GetCurrentBinaryDirectory(); for (cmComputeLinkInformation::Item const& l : libs) { + // Do not allow C# targets to be added to the LIB listing. LIB files are + // used for linking C++ dependencies. C# libraries do not have lib files. + // Instead, they compile down to C# reference libraries (DLL files). The + // `<ProjectReference>` elements added to the vcxproj are enough for the + // IDE to deduce the DLL file required by other C# projects that need its + // reference library. + if (l.Target && + cmGlobalVisualStudioGenerator::TargetIsCSharpOnly(l.Target)) { + continue; + } + if (l.IsPath) { std::string path = this->LocalGenerator->ConvertToRelativePath(currentBinDir, l.Value); diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index adef127..124db4e 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -153,7 +153,7 @@ private: void WriteEvent(const char* name, std::vector<cmCustomCommand> const& commands, std::string const& configName); - void WriteGroupSources(const char* name, ToolSources const& sources, + void WriteGroupSources(std::string const& name, ToolSources const& sources, std::vector<cmSourceGroup>&); void AddMissingSourceGroups(std::set<cmSourceGroup*>& groupsUsed, const std::vector<cmSourceGroup>& allGroups); diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index ccbff83..fb74fda 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -152,9 +152,8 @@ bool cmVisualStudioGeneratorOptions::IsManaged() const bool cmVisualStudioGeneratorOptions::UsingUnicode() const { // Look for the a _UNICODE definition. - for (std::vector<std::string>::const_iterator di = this->Defines.begin(); - di != this->Defines.end(); ++di) { - if (*di == "_UNICODE") { + for (std::string const& di : this->Defines) { + if (di == "_UNICODE") { return true; } } @@ -163,9 +162,8 @@ bool cmVisualStudioGeneratorOptions::UsingUnicode() const bool cmVisualStudioGeneratorOptions::UsingSBCS() const { // Look for the a _SBCS definition. - for (std::vector<std::string>::const_iterator di = this->Defines.begin(); - di != this->Defines.end(); ++di) { - if (*di == "_SBCS") { + for (std::string const& di : this->Defines) { + if (di == "_SBCS") { return true; } } @@ -227,7 +225,7 @@ void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration() // It translates to -arch=<virtual> -code=<real>. cmSystemTools::ReplaceString(arch_name, "sm_", "compute_"); } - for (auto const& c : codes) { + for (std::string const& c : codes) { std::string entry = arch_name + "," + c; result.push_back(entry); } @@ -237,7 +235,7 @@ void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration() // -gencode=<arch>,<code> // -gencode=<arch>,[<code1>,<code2>] // -gencode=<arch>,"<code1>,<code2>" - for (auto const& e : gencode) { + for (std::string const& e : gencode) { std::string entry = e; cmSystemTools::ReplaceString(entry, "arch=", ""); cmSystemTools::ReplaceString(entry, "code=", ""); @@ -285,7 +283,7 @@ void cmVisualStudioGeneratorOptions::FixManifestUACFlags() uacExecuteLevelMap["highestAvailable"] = "HighestAvailable"; uacExecuteLevelMap["requireAdministrator"] = "RequireAdministrator"; - for (auto const& subopt : subOptions) { + for (std::string const& subopt : subOptions) { std::vector<std::string> keyValue; cmsys::SystemTools::Split(subopt, keyValue, '='); if (keyValue.size() != 2 || (uacMap.find(keyValue[0]) == uacMap.end())) { @@ -332,9 +330,8 @@ void cmVisualStudioGeneratorOptions::Parse(const char* flags) // Process flags that need to be represented specially in the IDE // project file. - for (std::vector<std::string>::iterator ai = args.begin(); ai != args.end(); - ++ai) { - this->HandleFlag(ai->c_str()); + for (std::string const& ai : args) { + this->HandleFlag(ai.c_str()); } } @@ -437,7 +434,8 @@ cmIDEOptions::FlagValue cmVisualStudioGeneratorOptions::TakeFlag( return value; } -void cmVisualStudioGeneratorOptions::SetConfiguration(const char* config) +void cmVisualStudioGeneratorOptions::SetConfiguration( + const std::string& config) { this->Configuration = config; } @@ -566,31 +564,27 @@ void cmVisualStudioGeneratorOptions::OutputFlagMap(std::ostream& fout, const char* indent) { if (this->Version >= cmGlobalVisualStudioGenerator::VS10) { - for (std::map<std::string, FlagValue>::iterator m = this->FlagMap.begin(); - m != this->FlagMap.end(); ++m) { + for (auto const& m : this->FlagMap) { fout << indent; if (!this->Configuration.empty()) { this->TargetGenerator->WritePlatformConfigTag( - m->first.c_str(), this->Configuration.c_str(), 0, 0, 0, &fout); + m.first.c_str(), this->Configuration.c_str(), 0, 0, 0, &fout); } else { - fout << "<" << m->first << ">"; + fout << "<" << m.first << ">"; } const char* sep = ""; - for (std::vector<std::string>::iterator i = m->second.begin(); - i != m->second.end(); ++i) { - fout << sep << cmVisualStudio10GeneratorOptionsEscapeForXML(*i); + for (std::string const& i : m.second) { + fout << sep << cmVisualStudio10GeneratorOptionsEscapeForXML(i); sep = ";"; } - fout << "</" << m->first << ">\n"; + fout << "</" << m.first << ">\n"; } } else { - for (std::map<std::string, FlagValue>::iterator m = this->FlagMap.begin(); - m != this->FlagMap.end(); ++m) { - fout << indent << m->first << "=\""; + for (auto const& m : this->FlagMap) { + fout << indent << m.first << "=\""; const char* sep = ""; - for (std::vector<std::string>::iterator i = m->second.begin(); - i != m->second.end(); ++i) { - fout << sep << cmVisualStudioGeneratorOptionsEscapeForXML(*i); + for (std::string const& i : m.second) { + fout << sep << cmVisualStudioGeneratorOptionsEscapeForXML(i); sep = ";"; } fout << "\"\n"; diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h index 2dffe9b..2c56d42 100644 --- a/Source/cmVisualStudioGeneratorOptions.h +++ b/Source/cmVisualStudioGeneratorOptions.h @@ -91,7 +91,7 @@ public: const char* suffix, const std::string& lang); void OutputFlagMap(std::ostream& fout, const char* indent); - void SetConfiguration(const char* config); + void SetConfiguration(const std::string& config); private: cmLocalVisualStudioGenerator* LocalGenerator; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 5620723..f4f4a15 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2387,17 +2387,17 @@ int cmake::Build(const std::string& dir, const std::string& target, std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n"; return 1; } - std::unique_ptr<cmGlobalGenerator> gen( - this->CreateGlobalGenerator(cachedGenerator)); - if (!gen.get()) { + cmGlobalGenerator* gen = this->CreateGlobalGenerator(cachedGenerator); + if (!gen) { std::cerr << "Error: could create CMAKE_GENERATOR \"" << cachedGenerator << "\"\n"; return 1; } + this->SetGlobalGenerator(gen); const char* cachedGeneratorInstance = this->State->GetCacheEntryValue("CMAKE_GENERATOR_INSTANCE"); if (cachedGeneratorInstance) { - cmMakefile mf(gen.get(), this->GetCurrentSnapshot()); + cmMakefile mf(gen, this->GetCurrentSnapshot()); if (!gen->SetGeneratorInstance(cachedGeneratorInstance, &mf)) { return 1; } diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 62157bb..0ce6d72 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -348,6 +348,7 @@ if(BUILD_TESTING) if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^89]|[89][0-9])") ADD_TEST_MACRO(CSharpOnly CSharpOnly) ADD_TEST_MACRO(CSharpLinkToCxx CSharpLinkToCxx) + ADD_TEST_MACRO(CSharpLinkFromCxx CSharpLinkFromCxx) endif() ADD_TEST_MACRO(COnly COnly) @@ -1445,6 +1446,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProject") set_tests_properties(ExternalProject PROPERTIES + RUN_SERIAL 1 TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT}) add_test(NAME ExternalProjectSubdir @@ -1484,6 +1486,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectLocal") set_tests_properties(ExternalProjectLocal PROPERTIES + RUN_SERIAL 1 TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT}) add_test(ExternalProjectUpdateSetup ${CMAKE_CTEST_COMMAND} @@ -1499,6 +1502,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate") set_tests_properties(ExternalProjectUpdateSetup PROPERTIES + RUN_SERIAL 1 TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT}) add_test(NAME ExternalProjectUpdate @@ -1513,6 +1517,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate") set_tests_properties(ExternalProjectUpdate PROPERTIES + RUN_SERIAL 1 TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT} WORKING_DIRECTORY ${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate DEPENDS ExternalProjectUpdateSetup ) diff --git a/Tests/CSharpLinkFromCxx/.gitattributes b/Tests/CSharpLinkFromCxx/.gitattributes new file mode 100644 index 0000000..57a39049 --- /dev/null +++ b/Tests/CSharpLinkFromCxx/.gitattributes @@ -0,0 +1 @@ +UsefulManagedCppClass.* -format.clang-format diff --git a/Tests/CSharpLinkFromCxx/CMakeLists.txt b/Tests/CSharpLinkFromCxx/CMakeLists.txt new file mode 100644 index 0000000..9a1a993 --- /dev/null +++ b/Tests/CSharpLinkFromCxx/CMakeLists.txt @@ -0,0 +1,19 @@ +# Take a C# shared library and link it to a managed C++ shared library +cmake_minimum_required(VERSION 3.10) +project (CSharpLinkFromCxx CXX CSharp) + +add_library(CSharpLibrary SHARED UsefulCSharpClass.cs) + +# we have to change the default flags for the +# managed C++ project to build +string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) + +# The C# project is a dependency of the C++/CLI project +add_library(ManagedCppLibrary SHARED UsefulManagedCppClass.cpp UsefulManagedCppClass.hpp) +target_compile_options(ManagedCppLibrary PRIVATE "/clr") +target_link_libraries(ManagedCppLibrary PUBLIC CSharpLibrary) + +# Main executable for the test framework +add_executable(CSharpLinkFromCxx CSharpLinkFromCxx.cs) +target_link_libraries(CSharpLinkFromCxx PRIVATE ManagedCppLibrary) diff --git a/Tests/CSharpLinkFromCxx/CSharpLinkFromCxx.cs b/Tests/CSharpLinkFromCxx/CSharpLinkFromCxx.cs new file mode 100644 index 0000000..31a74eb --- /dev/null +++ b/Tests/CSharpLinkFromCxx/CSharpLinkFromCxx.cs @@ -0,0 +1,16 @@ +using System; +using CSharpLibrary; + +namespace CSharpLinkFromCxx +{ + internal class CSharpLinkFromCxx + { + public static void Main(string[] args) + { + Console.WriteLine("Starting test for CSharpLinkFromCxx"); + + var useful = new UsefulManagedCppClass(); + useful.RunTest(); + } + } +} diff --git a/Tests/CSharpLinkFromCxx/UsefulCSharpClass.cs b/Tests/CSharpLinkFromCxx/UsefulCSharpClass.cs new file mode 100644 index 0000000..749e57d --- /dev/null +++ b/Tests/CSharpLinkFromCxx/UsefulCSharpClass.cs @@ -0,0 +1,12 @@ +using System; + +namespace CSharpLibrary +{ + public class UsefulCSharpClass + { + public string GetSomethingUseful() + { + return "Something Useful"; + } + } +} diff --git a/Tests/CSharpLinkFromCxx/UsefulManagedCppClass.cpp b/Tests/CSharpLinkFromCxx/UsefulManagedCppClass.cpp new file mode 100644 index 0000000..9468812 --- /dev/null +++ b/Tests/CSharpLinkFromCxx/UsefulManagedCppClass.cpp @@ -0,0 +1,15 @@ +#include "UsefulManagedCppClass.hpp" + +namespace CSharpLibrary +{ + UsefulManagedCppClass::UsefulManagedCppClass() + { + auto useful = gcnew UsefulCSharpClass(); + m_usefulString = useful->GetSomethingUseful(); + } + + void UsefulManagedCppClass::RunTest() + { + Console::WriteLine("Printing from Managed CPP Class: " + m_usefulString); + } +} diff --git a/Tests/CSharpLinkFromCxx/UsefulManagedCppClass.hpp b/Tests/CSharpLinkFromCxx/UsefulManagedCppClass.hpp new file mode 100644 index 0000000..def7cea --- /dev/null +++ b/Tests/CSharpLinkFromCxx/UsefulManagedCppClass.hpp @@ -0,0 +1,16 @@ +using namespace System; + +namespace CSharpLibrary +{ + public ref class UsefulManagedCppClass + { + public: + + UsefulManagedCppClass(); + void RunTest(); + + private: + + String^ m_usefulString; + }; +} diff --git a/Tests/CompileFeatures/default_dialect.c b/Tests/CompileFeatures/default_dialect.c index 4debd94..2b4627c 100644 --- a/Tests/CompileFeatures/default_dialect.c +++ b/Tests/CompileFeatures/default_dialect.c @@ -1,6 +1,6 @@ #if DEFAULT_C11 -#if __STDC_VERSION__ != 201112L +#if __STDC_VERSION__ < 201112L #error Unexpected value for __STDC_VERSION__. #endif #elif DEFAULT_C99 diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index 64a07f0..5eff6b9 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -236,3 +236,17 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 8) deploymeny_target_test(${SDK}) endforeach() endif() + +function(XcodeDependOnZeroCheck) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeDependOnZeroCheck-build) + set(RunCMake_TEST_NO_CLEAN 1) + + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(XcodeDependOnZeroCheck) + run_cmake_command(XcodeDependOnZeroCheck-build ${CMAKE_COMMAND} --build . --target parentdirlib) + run_cmake_command(XcodeDependOnZeroCheck-build ${CMAKE_COMMAND} --build . --target subdirlib) +endfunction() + +XcodeDependOnZeroCheck() diff --git a/Tests/RunCMake/XcodeProject/XcodeDependOnZeroCheck-build-stdout.txt b/Tests/RunCMake/XcodeProject/XcodeDependOnZeroCheck-build-stdout.txt new file mode 100644 index 0000000..92c9a29 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeDependOnZeroCheck-build-stdout.txt @@ -0,0 +1 @@ +BUILD AGGREGATE TARGET ZERO_CHECK diff --git a/Tests/RunCMake/XcodeProject/XcodeDependOnZeroCheck.cmake b/Tests/RunCMake/XcodeProject/XcodeDependOnZeroCheck.cmake new file mode 100644 index 0000000..d759a65 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeDependOnZeroCheck.cmake @@ -0,0 +1,4 @@ +set(CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY TRUE) +project(XcodeDependOnZeroCheck CXX) +add_subdirectory(zerocheck) +add_library(parentdirlib foo.cpp) diff --git a/Tests/RunCMake/XcodeProject/zerocheck/CMakeLists.txt b/Tests/RunCMake/XcodeProject/zerocheck/CMakeLists.txt new file mode 100644 index 0000000..4adde99 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/zerocheck/CMakeLists.txt @@ -0,0 +1,2 @@ +project(subproject) +add_library(subdirlib ../foo.cpp) |