View Issue Details [ Jump to Notes ] | [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
0015259 | CMake | CMake | public | 2014-11-21 08:10 | 2015-05-04 09:05 | ||||
Reporter | Alexander Markert | ||||||||
Assigned To | Brad King | ||||||||
Priority | normal | Severity | minor | Reproducibility | always | ||||
Status | closed | Resolution | fixed | ||||||
Platform | x86_64 | OS | Windows | OS Version | Windows 7 | ||||
Product Version | |||||||||
Target Version | CMake 3.1 | Fixed in Version | CMake 3.1 | ||||||
Summary | 0015259: Source file properties are lost, if the name of the file is not specified case sensitive. | ||||||||
Description | If you add a source file and the file name is not specified case sensitive, then CMake corrects the name - that is ok. But if you specify additional properties for the file via SET_SOURCE_FILES_PROPERTIES, the settings are lost! This is only true for CMake 3.1.0, CMake 3.0.2 worked fine. | ||||||||
Steps To Reproduce | Add a source file with a name, which is not case sensitive and set an additional propery via SET_SOURCE_FILES_PROPERTIES. Example of CMakeLists.txt: # Name is actually WarningsAsError.cpp, but warningaserror.cpp is used SET(FileWarningAsError warningaserror.cpp) SET(Files main.cpp ${FileWarningAsError}) # option /WX is lost SET_SOURCE_FILES_PROPERTIES(${FileWarningAsError} PROPERTIES COMPILE_FLAGS "/WX") ADD_EXECUTABLE(CaseInsensitive ${Files}) | ||||||||
Additional Information | Please find attached a configuration file and a batch file, which generated the given projects with CMake 3.1.0 and CMake 3.0.2. The paths to CMake have to be adjusted in CallCMake.bat. | ||||||||
Tags | No tags attached. | ||||||||
Attached Files | DummyProject.7z [^] (760 bytes) 2014-11-21 08:10 | ||||||||
Relationships | |
Relationships |
Notes | |
(0037245) Brad King (manager) 2014-11-21 09:43 |
FWIW, CMake never intended to support wrong-case specification of file names. Such projects would not work on case-sensitive filesystems. Still, this looks like a regression since it worked in 3.0. If we are going to disallow this, it would need to be done with a policy. |
(0037249) Ben Boeckel (developer) 2014-11-21 12:57 |
Unable to reproduce on OS X. Testing on Windows bisects down to: commit d38423ecc4105d8339b7461130b964f3c69e8847 Author: Stephen Kelly <steveire@gmail.com> Date: Mon Mar 17 17:49:38 2014 +0100 cmTarget: Add a method to obtain list of filenames for sources. as being the culprit. |
(0037250) Ben Boeckel (developer) 2014-11-21 13:05 |
A simple revert doesn't work and isn't simple. Source files now depend on the configuration, so I'm going to try avoiding the std::string function as a fix. |
(0037251) Ben Boeckel (developer) 2014-11-21 13:20 |
Looks like the bad commit was partially reverted at: commit 92e2fbe103c6ffc3af1189d0450493488c65baaa Author: Stephen Kelly <steveire@gmail.com> Date: Sat Apr 5 11:41:58 2014 +0200 cmGeneratorTarget: Trace cmSourceFile objects instead of strings. This reverses the decision in commit d38423ec (cmTarget: Add a method to obtain list of filenames for sources., 2014-03-17). The cmSourceFile based API is preferred because that avoids creation of many cmSourceFileLocation objects for matching strings, and the result is cached by cmTarget. but the bad behavior stuck around. Inspecting history around this commit. |
(0037252) Ben Boeckel (developer) 2014-11-21 14:01 |
So one comparing the reverse diff of the original breaking commit and the partial revert shows this: # Reverse of d38423ecc4105d8339b7461130b964f3c69e8847 // Make sure this file is in the target. - this->Target->AddSource(name); + this->Target->AddSourceFile(sf); # From 92e2fbe103c6ffc3af1189d0450493488c65baaa // Make sure this file is in the target. - this->Target->AddSource(name); + this->Target->AddSource(sf->GetFullPath()); Which has since been changed by: commit 4f1c71fdd25f33bd0cdeb2b705723db02f8fddf4 Author: Stephen Kelly <steveire@gmail.com> Date: Wed Apr 9 01:32:14 2014 +0200 cmTarget: Add all sources traced from custom commands at once. The AddSource method accepts one file and tries to avoiding adding it to the sources-list of the target if it already exists. This involves creating many cmSourceFileLocation objects for matching on existing files, which is an expensive operation. Avoid the searching algorithm by appending the new sources as one group. Generate-time processing of source files will ensure uniqueness. Add a new AddTracedSources for this purpose. The existing AddSources method must process the input for policy CMP0049, but as these source filenames come from cmSourceFile::GetFullPath(), we can forego that extra processing. into: - // Make sure this file is in the target. - this->Target->AddSource(sf->GetFullPath()); + // Make sure this file is in the target at the end. + this->NewSources.push_back(sf->GetFullPath()); and now calls cmTarget::AddTracedSources. It seems that AddSourceFile has been removed because now source files are tracked by strings to accommodate generator expressions properly. There might be an easier fix in getting cmTarget::GetSourceFiles(std::vector<cmSourceFile*>) to not call down to the std::vector<std::string> version, but there's a lot of code in there I'm not intimately familiar with. I admit that this whole trail might be only related and not the actual problem though, but it is certainly the most promising I can get from it. |
(0037254) Stephen Kelly (developer) 2014-11-22 05:48 |
Getting back to commit d38423ecc4105d8339b7461130b964f3c69e8847 Author: Stephen Kelly <steveire@gmail.com> Date: Mon Mar 17 17:49:38 2014 +0100 cmTarget: Add a method to obtain list of filenames for sources. What is it about that commit which causes the test to fail? Is there some case handling in the old code path which is not in the new code path? |
(0037255) Ben Boeckel (developer) 2014-11-22 11:09 |
My best guess is the difference between AddSource(fname) and AddSourceFile(sf) because we don't do case-insensitive name comparisons…for the path components on case-insensitive file systems (e.g., I don't know how things work with NTFS-on-Linux). I can try and break down that commit on Monday. |
(0037269) Ben Boeckel (developer) 2014-11-24 14:37 |
I was unable to get it to work by reverting hunks from that patch by anything short of reverting the entire patch. This includes using cmSourceFile for the API and using GetFullPath for string-y parts or using cmMakefile::GetSource to get a cmSourceFile* from a string. I tried making the queues have cmSourceFile* which using strings elsewhere, using cmTarget::AddSourceFile while using strings elsewhere, and turning strings back into cmSourceFile* for use around the cmTarget APIs. |
(0037270) Ben Boeckel (developer) 2014-11-24 14:48 |
If we can't get this fixed, my proposal for a policy (which won't avoid a backwards-incompat break, but at least makes noises about the issue): Add a policy which warns when source file properties are set on files which are not used during the build. This should catch improper logic for source files which have properties but aren't part of a target (probably a logic error) and this case. This should warn in the OLD case and error in the NEW case; no behavior change for either side. The open question I have is whether to do this *just* for CMake's built-in properties or also do so for user properties (though a query on it should prevent the warning). The downside would be that CMake would have to store a cmBacktrace for each source file property to indicate where it was set. |
(0037271) Stephen Kelly (developer) 2014-11-25 08:02 |
It should be possible to fix this by finding out how the old codepath accepted the code. Somewhere in CMake there must be a case-insensitive comparison, or use of some WIN32 filesystem API, or some point where the wrong-case name is converted to a correct-case name. I don't have the Windows access to track this down. If we find that, we might be able to find the right place to do a similar conversion for a policy implementation. In the old codepath, the sources of a target are stored as cmSourceFile*s early during configure-time, and in the new codepath they are stored as strings and converted to cmSourceFile* at generate-time. The API for getting the cmSourceFile from the string should be the same (cmMakefile::GetOrCreateSource), so I don't really see why the behavior is any different. Maybe the cmSourceFile created while executing set_source_files_properties is not found during generate time by GetOrCreateSource? |
(0037281) Ben Boeckel (developer) 2014-11-25 14:23 |
So with this setup: on disk: - NeedDef.c name give to set_source_files_properties: - needdef.c name given to the target: - needdef.c it worked in 3.0. With master, however, the *generate* step now asks for a cmSourceFile by its full, on-disk cased, path (this is probably why OS X works: we don't find the proper case there) and doesn't find the one with the properties set on it because cmSourceFileLocation::Matches uses the user-given casing for the file when searching. This is also why if the property name and the target name didn't match in case, it failed to work even in 3.0. Now bisecting with this new test case. |
(0037282) Stephen Kelly (developer) 2014-11-25 14:42 |
Ah, so being a full path is relevant? So the CMake 3.0 and earlier behavior with SET(FileWarningAsError warningaserror.cpp) SET(Files main.cpp ${FileWarningAsError}) SET_SOURCE_FILES_PROPERTIES(${FileWarningAsError} PROPERTIES COMPILE_FLAGS "/WX") ADD_EXECUTABLE(CaseInsensitive ${Files}) is different to SET(FileWarningAsError ${CMAKE_CURRENT_SOURCE_DIR}/warningaserror.cpp) SET(Files main.cpp ${FileWarningAsError}) SET_SOURCE_FILES_PROPERTIES(${FileWarningAsError} PROPERTIES COMPILE_FLAGS "/WX") ADD_EXECUTABLE(CaseInsensitive ${Files}) ? |
(0037283) Ben Boeckel (developer) 2014-11-25 15:15 |
So that new test bisects down to the same commit :/ . The problem seems to be that the cmSourceFileLocation stores the user-specified casing, not the actual casing on-disk and previously, using cmSourceFile would boil down to asking about the on-disk casing via GetFullPath whereas now with the strings, we create sources according to the user-specified casing, but then query on the actual casing. Testing with a full path given in the CMakeLists.txt doesn't change anything about the results. |
(0037284) Ben Boeckel (developer) 2014-11-25 15:53 |
Here is a diff which fixes the original broken commit (d38423ecc4105d8339b7461130b964f3c69e8847). It no longer cleanly applies (since cmTarget::GetSourceFiles has been rewritten): ======== diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 834f9fd..0296877 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -710,7 +710,7 @@ void cmTargetTraceDependencies::FollowName(std::string const& name) { this->CurrentEntry->Depends.push_back(sf); } - this->QueueSource(sf->GetFullPath()); + this->QueueSource(name); } } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 0866d10..5e14fe0 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -551,7 +551,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files) const si = sourceFiles.begin(); si != sourceFiles.end(); ++si) { - files.push_back((*si)->GetFullPath()); + files.push_back((*si)->GetLocation().GetName()); } } ======== I expect Mantis to screw up the formatting, but I don't see a way to attach a file? For anyone who sees this before it expires: http://paste.fedoraproject.org/154051/48802141/ [^] |
(0037302) Brad King (manager) 2014-11-26 14:24 |
As stated in 0015259:0037245, using the wrong case for sources was never intended to work or documented. Now that we've dug into this, it appears to have worked only due to a subtle idiosyncrasy of the old implementation. After the refactoring needed to enable the target SOURCES features in 3.1 it does not appear to be possible to reproduce the old behavior easily. I don't want to add a bunch of complicated/subtle logic to the new implementation that may introduce other bugs just to support this old bug. It is easy for projects to fix their CMake code to use the correct case when naming sources, and the fixed code will still work just as well in older CMake versions. IMO the cost of trying to support this old bug with compatibility code in CMake is too high to be worthwhile compared to just fixing the individual projects with such typos in their code. |
(0037303) Brad King (manager) 2014-11-26 14:43 |
I've updated the 3.1 release notes to explicitly mention that projects depending on the old behavior should be fixed: Help: Add 3.1 release note about source file name casing http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ea1afd84 [^] |
(0037304) Brad King (manager) 2014-11-26 16:12 |
Re 0015259:0037302: On second thought, it may be possible to make this continue to work. Although the code paths need to do lookups that they didn't do before, we can make those lookups work despite case differences. We already normalize the case of the directory component of file locations. Now we just need to compare the names in a case-insensitive way when working on operating systems using case-insensitive filesystems: diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx index 1c2454e..004fd1f 100644 --- a/Source/cmSourceFileLocation.cxx +++ b/Source/cmSourceFileLocation.cxx @@ -216,7 +216,8 @@ bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc) // Both extensions are similarly ambiguous. Since only the old fixed set // of extensions will be tried, the names must match at this point to be // the same file. - if(this->Name.size() != loc.Name.size() || this->Name != loc.Name) + if(this->Name.size() != loc.Name.size() || + !cmSystemTools::ComparePath(this->Name, loc.Name)) { return false; } |
(0037305) Brad King (manager) 2014-11-26 17:11 |
Re 0015259:0037304: I've committed the patch here: Fix lookup of source names after conversion to their actual case http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=84d124e8 [^] and merged for testing. |
(0037322) Brad King (manager) 2014-12-01 09:13 |
I've queued the fix for inclusion in the next 3.1 release candidate. |
(0038680) Robert Maynard (manager) 2015-05-04 09:05 |
Closing resolved issues that have not been updated in more than 4 months. |
Notes |
Issue History | |||
Date Modified | Username | Field | Change |
2014-11-21 08:10 | Alexander Markert | New Issue | |
2014-11-21 08:10 | Alexander Markert | File Added: DummyProject.7z | |
2014-11-21 09:35 | Brad King | Assigned To | => Ben Boeckel |
2014-11-21 09:35 | Brad King | Status | new => assigned |
2014-11-21 09:35 | Brad King | Target Version | => CMake 3.1 |
2014-11-21 09:43 | Brad King | Note Added: 0037245 | |
2014-11-21 12:57 | Ben Boeckel | Assigned To | Ben Boeckel => Stephen Kelly |
2014-11-21 12:57 | Ben Boeckel | Note Added: 0037249 | |
2014-11-21 13:05 | Ben Boeckel | Note Added: 0037250 | |
2014-11-21 13:05 | Ben Boeckel | Status | assigned => acknowledged |
2014-11-21 13:20 | Ben Boeckel | Note Added: 0037251 | |
2014-11-21 14:01 | Ben Boeckel | Note Added: 0037252 | |
2014-11-22 05:48 | Stephen Kelly | Note Added: 0037254 | |
2014-11-22 11:09 | Ben Boeckel | Note Added: 0037255 | |
2014-11-24 14:37 | Ben Boeckel | Note Added: 0037269 | |
2014-11-24 14:48 | Ben Boeckel | Note Added: 0037270 | |
2014-11-25 08:02 | Stephen Kelly | Note Added: 0037271 | |
2014-11-25 14:23 | Ben Boeckel | Note Added: 0037281 | |
2014-11-25 14:42 | Stephen Kelly | Note Added: 0037282 | |
2014-11-25 15:15 | Ben Boeckel | Note Added: 0037283 | |
2014-11-25 15:53 | Ben Boeckel | Note Added: 0037284 | |
2014-11-26 14:24 | Brad King | Note Added: 0037302 | |
2014-11-26 14:24 | Brad King | Assigned To | Stephen Kelly => |
2014-11-26 14:24 | Brad King | Status | acknowledged => resolved |
2014-11-26 14:24 | Brad King | Resolution | open => won't fix |
2014-11-26 14:24 | Brad King | Target Version | CMake 3.1 => |
2014-11-26 14:43 | Brad King | Note Added: 0037303 | |
2014-11-26 16:09 | Brad King | Status | resolved => acknowledged |
2014-11-26 16:09 | Brad King | Resolution | won't fix => open |
2014-11-26 16:12 | Brad King | Note Added: 0037304 | |
2014-11-26 16:13 | Brad King | Target Version | => CMake 3.1 |
2014-11-26 17:11 | Brad King | Note Added: 0037305 | |
2014-11-26 17:18 | Brad King | Note View State: 0037304: private | |
2014-11-26 17:18 | Brad King | Note View State: 0037304: public | |
2014-12-01 09:13 | Brad King | Note Added: 0037322 | |
2014-12-01 09:13 | Brad King | Assigned To | => Brad King |
2014-12-01 09:13 | Brad King | Status | acknowledged => resolved |
2014-12-01 09:13 | Brad King | Resolution | open => fixed |
2014-12-01 09:13 | Brad King | Fixed in Version | => CMake 3.1 |
2015-05-04 09:05 | Robert Maynard | Note Added: 0038680 | |
2015-05-04 09:05 | Robert Maynard | Status | resolved => closed |
Issue History |
Copyright © 2000 - 2018 MantisBT Team |