MantisBT - CMake
View Issue Details
0015164CMakeCMakepublic2014-09-19 01:102015-03-02 08:57
Janne Rönkkö 
 
normalmajoralways
closedno change required 
WindowsWindows 77
CMake 3.0.2 
 
0015164: Relative Value for CMAKE_TOOLCHAIN_FILE Does Not Work Under PowerShell
The toolchain file is not handled properly under PowerShell if the toolchain file path is relative.

The issues (I have noticed so far):
- CMAKE_SYSTEM_NAME is not set properly
- There is warnings about include with empty file name (this seems to be the reason that at least CMAKE_SYSTEM_NAME is not set correctly)

The issue is present at least in versions 3.0.0-3.0.2 (these are the version I tested).
In PowerShell:
unzip project.zip
cd project
mkdir build
cmake -DCMAKE_TOOLCHAIN_FILE=../../toolchain.cmake -G Ninja ..

On PowerShell with relative path:
=================================

PS C:\Users\janne\project\build> cmake -DCMAKE_TOOLCHAIN_FILE=../../toolchain.cmake -G Ninja ..
CMake Warning (dev) at build/CMakeFiles/3.0.2/CMakeSystem.cmake:6 (include):
  include() given empty file name (ignored).
Call Stack (most recent call first):
  CMakeLists.txt:3 (project)
This warning is for project developers. Use -Wno-dev to suppress it.

-- The C compiler identification is GNU 4.7.3
-- The CXX compiler identification is GNU 4.7.3
-- Check for working C compiler using: Ninja
CMake Warning (dev) at C:/Users/janne/project/build/CMakeFiles/3.0.2/CMakeSystem.cmake:6 (include):
  include() given empty file name (ignored).
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Check for working C compiler using: Ninja -- works
-- Detecting C compiler ABI info
CMake Warning (dev) at C:/Users/janne/project/build/CMakeFiles/3.0.2/CMakeSystem.cmake:6 (include):
  include() given empty file name (ignored).
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Detecting C compiler ABI info - done
-- Check for working CXX compiler using: Ninja
CMake Warning (dev) at C:/Users/janne/project/build/CMakeFiles/3.0.2/CMakeSystem.cmake:6 (include):
  include() given empty file name (ignored).
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Check for working CXX compiler using: Ninja -- works
-- Detecting CXX compiler ABI info
CMake Warning (dev) at C:/Users/janne/project/build/CMakeFiles/3.0.2/CMakeSystem.cmake:6 (include):
  include() given empty file name (ignored).
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Detecting CXX compiler ABI info - done
CMake system name: Windows
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/janne/project/build

## Note the line "CMake system name: Windows"

On PowerShell with absolute path:
=================================

PS C:\Users\janne\project\build> cmake -DCMAKE_TOOLCHAIN_FILE=C:/users/janne/toolchain.cmake -G Ninja ..
-- The C compiler identification is GNU 4.7.3
-- The CXX compiler identification is GNU 4.7.3
-- Check for working C compiler using: Ninja
-- Check for working C compiler using: Ninja -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler using: Ninja
-- Check for working CXX compiler using: Ninja -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
CMake system name: Linux
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/janne/project/build


On cmd.exe with relative path:
==============================

C:\Users\janne\project\build>cmake -DCMAKE_TOOLCHAIN_FILE=../../toolchain.cmake -G Ninja ..
-- The C compiler identification is GNU 4.7.3
-- The CXX compiler identification is GNU 4.7.3
-- Check for working C compiler using: Ninja
-- Check for working C compiler using: Ninja -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler using: Ninja
-- Check for working CXX compiler using: Ninja -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
CMake system name: Linux
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/janne/project/build

On cmd.exe with absolute path:
==============================

C:\Users\janne\project\build>cmake -DCMAKE_TOOLCHAIN_FILE=C:/users/janne/toolchain.cmake -G Ninja ..
-- The C compiler identification is GNU 4.7.3
-- The CXX compiler identification is GNU 4.7.3
-- Check for working C compiler using: Ninja
-- Check for working C compiler using: Ninja -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler using: Ninja
-- Check for working CXX compiler using: Ninja -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
CMake system name: Linux
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/janne/project/build
No tags attached.
zip project.zip (813) 2014-09-19 01:10
https://public.kitware.com/Bug/file/5259/project.zip
Issue History
2014-09-19 01:10Janne RönkköNew Issue
2014-09-19 01:10Janne RönkköFile Added: project.zip
2014-09-19 08:58Brad KingNote Added: 0036832
2014-09-21 23:51Janne RönkköNote Added: 0036837
2014-09-22 08:53Brad KingNote Added: 0036841
2014-09-22 10:35Janne RönkköNote Added: 0036842
2014-09-22 10:43Brad KingNote Added: 0036843
2014-09-22 10:53Janne RönkköNote Added: 0036844
2014-09-22 11:27Janne RönkköNote Added: 0036845
2014-09-22 12:41Janne RönkköNote Added: 0036847
2014-09-22 12:57Brad KingNote Added: 0036848
2014-09-22 13:03Janne RönkköNote Added: 0036850
2014-09-22 13:10Brad KingStatusnew => resolved
2014-09-22 13:10Brad KingResolutionopen => no change required
2014-09-22 13:10Brad KingAdditional Information Updatedbug_revision_view_page.php?rev_id=1578#r1578
2015-03-02 08:57Robert MaynardNote Added: 0038130
2015-03-02 08:57Robert MaynardStatusresolved => closed

Notes
(0036832)
Brad King   
2014-09-19 08:58   
The code that uses the CMAKE_TOOLCHAIN_FILE value and possibly converts it to a full path is here:

 http://www.cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/CMakeDetermineSystem.cmake;hb=v3.0.2#l89 [^]

Try adding local debugging message() commands there to see the value before and after this code.
(0036837)
Janne Rönkkö   
2014-09-21 23:51   
The CMAKE_TOOLCHAIN_FILE is not defined when the file is evaluated when relative path is used.

The code in CMakeDetermineSystem.cmake was:

message( "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}" )
if(CMAKE_TOOLCHAIN_FILE)
  message( "CMAKE_TOOLCHAIN_FILE: '${CMAKE_TOOLCHAIN_FILE}'" )
  # at first try to load it as path relative to the directory from which cmake has been run
  include("${CMAKE_BINARY_DIR}/${CMAKE_TOOLCHAIN_FILE}" OPTIONAL RESULT_VARIABLE _INCLUDED_TOOLCHAIN_FILE)
  if(NOT _INCLUDED_TOOLCHAIN_FILE)
     # if the file isn't found there, check the default locations
     include("${CMAKE_TOOLCHAIN_FILE}" OPTIONAL RESULT_VARIABLE _INCLUDED_TOOLCHAIN_FILE)
  endif()

  if(_INCLUDED_TOOLCHAIN_FILE)
    set(CMAKE_TOOLCHAIN_FILE "${_INCLUDED_TOOLCHAIN_FILE}" CACHE FILEPATH "The CMake toolchain file" FORCE)
  else()
    message(FATAL_ERROR "Could not find toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
    set(CMAKE_TOOLCHAIN_FILE "NOTFOUND" CACHE FILEPATH "The CMake toolchain file" FORCE)
  endif()
else()
  message( "CMAKE_TOOLCHAIN_FILE not defined" )
endif()
message( "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}" )


And the output for the commands:

PS C:\Users\janne\project\build> cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=c:/users/janne/toolchain.cmake ..
CMAKE_SYSTEM_NAME:
CMAKE_TOOLCHAIN_FILE: 'c:/users/janne/toolchain.cmake'
CMAKE_SYSTEM_NAME: Linux
-- The C compiler identification is GNU 4.7.3
-- The CXX compiler identification is GNU 4.7.3
-- Check for working C compiler using: Ninja
-- Check for working C compiler using: Ninja -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler using: Ninja
-- Check for working CXX compiler using: Ninja -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
CMake system name: Linux
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/janne/project/build


PS C:\Users\janne\project\build> cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../toolchain.cmake ..
CMAKE_SYSTEM_NAME:
CMAKE_TOOLCHAIN_FILE not defined
CMAKE_SYSTEM_NAME:
CMake Warning (dev) at build/CMakeFiles/3.0.2/CMakeSystem.cmake:6 (include):
  include() given empty file name (ignored).
Call Stack (most recent call first):
  CMakeLists.txt:3 (project)
This warning is for project developers. Use -Wno-dev to suppress it.

-- The C compiler identification is GNU 4.7.3
-- The CXX compiler identification is GNU 4.7.3
-- Check for working C compiler using: Ninja
CMake Warning (dev) at C:/Users/janne/project/build/CMakeFiles/3.0.2/CMakeSystem.cmake:6 (include):
  include() given empty file name (ignored).
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Check for working C compiler using: Ninja -- works
-- Detecting C compiler ABI info
CMake Warning (dev) at C:/Users/janne/project/build/CMakeFiles/3.0.2/CMakeSystem.cmake:6 (include):
  include() given empty file name (ignored).
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Detecting C compiler ABI info - done
-- Check for working CXX compiler using: Ninja
CMake Warning (dev) at C:/Users/janne/project/build/CMakeFiles/3.0.2/CMakeSystem.cmake:6 (include):
  include() given empty file name (ignored).
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Check for working CXX compiler using: Ninja -- works
-- Detecting CXX compiler ABI info
CMake Warning (dev) at C:/Users/janne/project/build/CMakeFiles/3.0.2/CMakeSystem.cmake:6 (include):
  include() given empty file name (ignored).
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Detecting CXX compiler ABI info - done
CMake system name: Windows
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/janne/project/build
(0036841)
Brad King   
2014-09-22 08:53   
Strange. Let's try a small isolated test case. Try the following session:

$ cat test.cmake
message(STATUS "CMAKE_TOOLCHAIN_FILE=[${CMAKE_TOOLCHAIN_FILE}]")
$ cmake -DCMAKE_TOOLCHAIN_FILE=../../toolchain.cmake -P test.cmake
-- CMAKE_TOOLCHAIN_FILE=[../../toolchain.cmake]

ported to PowerShell.
(0036842)
Janne Rönkkö   
2014-09-22 10:35   
PS C:\Users\janne\test> gc .\test.cmake

message(STATUS "CMAKE_TOOLCHAIN_FILE=[${CMAKE_TOOLCHAIN_FILE}]")


PS C:\Users\janne\test> cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake -P test.cmake
-- CMAKE_TOOLCHAIN_FILE=[]

PS C:\Users\janne\test> cmake -DCMAKE_TOOLCHAIN_FILE=c:/users/janne/toolchain.cmake -P test.cmake
-- CMAKE_TOOLCHAIN_FILE=[c:/users/janne/toolchain.cmake]

PS C:\Users\janne\test> cmake -DCMAKE_TOOLCHAIN_FILE=..\toolchain.cmake -P test.cmake
-- CMAKE_TOOLCHAIN_FILE=[]
(0036843)
Brad King   
2014-09-22 10:43   
Re 0015164:0036842: It looks like something may be mangling the argument. If you can build CMake from source to debug this, the main() entry point is here:

 http://www.cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmakemain.cxx;hb=v3.0.2#l163 [^]

You could print out the original arguments to see what is different.
(0036844)
Janne Rönkkö   
2014-09-22 10:53   
A bit more testing:

PS C:\Users\janne> cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -P test.cmake
CMake Error: Error processing file: test.cmake

PS C:\Users\janne> cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -P test/test.cmake
-- CMAKE_TOOLCHAIN_FILE=[toolchain]

PS C:\Users\janne> cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -P test\test.cmake
-- CMAKE_TOOLCHAIN_FILE=[toolchain]


Here you can see that toolchain.cmake has transformed to toolchain. Testing that in a bit more details gives you this:

PS C:\Users\janne\test> type .\test.cmake

message(STATUS "VAR1=[${VAR1}]")
message(STATUS "VAR2=[${VAR2}]")
message(STATUS "VAR3=[${VAR3}]")
PS C:\Users\janne\test> cmake -DVAR1=.value1 -DVAR2=..\foo -DVAR3=foo..bar -P test.cmake
-- VAR1=[]
-- VAR2=[]
-- VAR3=[foo]


So everything up to first dot stays in the variable but everything starting from the first dot is removed.

I compiled the following program (that prints all the args) with VisualStudio 2010:
#include <iostream>
int main(int argc, char** argv)
{
  for( int i = 0; i < argc; ++i )
  {
    std::cout << "Arg " << i << ": " << argv[i] << std::endl;
  }
  return 0;
}

Running that on PowerShell yields expected results:
PS C:\Users\janne\project\b> .\print-args.exe first .second thi.rd
Arg 0: C:\Users\janne\project\b\print-args.exe
Arg 1: first
Arg 2: .second
Arg 3: thi.rd



... I'll compile CMake myself and add some debug prints as you asked.
(0036845)
Janne Rönkkö   
2014-09-22 11:27   
Ok, so the original ac and av do get the values incorrectly:

PS C:\Users\janne\test> C:\Users\janne\cmake\build\inst\bin\cmake.exe -DVAR1=val.ue -P .\test.cmake
Original arguments:
- Arg 0: C:\Users\janne\cmake\build\inst\bin\cmake.exe
- Arg 1: -DVAR1=val
- Arg 2: .ue
- Arg 3: -P
- Arg 4: .\test.cmake


I had the following code there:
int main(int ac, char const* const* av)
{
  std::cerr << "Original arguments:" << std::endl;
  for( int i = 0; i < ac; ++i )
  {
    std::cerr << "- Arg " << i << ": " << av[i] << std::endl;
  }
// snip...
(0036847)
Janne Rönkkö   
2014-09-22 12:41   
This issue is most probably PowerShell issue.

An example using the print-args program I already used earlier:

PS C:\Users\janne\project\b> .\print-args.exe -DVAR1=value..1 value.2 var3=val3 /DVAR4=val.4 -val.5 -var6:val.6 -var.7:val7
Arg 0: C:\Users\janne\project\b\print-args.exe
Arg 1: -DVAR1=value
Arg 2: ..1
Arg 3: value.2
Arg 4: var3=val3
Arg 5: /DVAR4=val.4
Arg 6: -val
Arg 7: .5
Arg 8: -var6:val.6
Arg 9: -var
Arg 10: .7:val7

Apparently if argument starts with minus (-) the argument is split from the first dot (UNLESS the value has colon before the dot).


You can work around this behaviour in PowerShell by using double quotes:

PS C:\Users\janne\project\b> .\print-args.exe "-DVAR1=foo.bar"
Arg 0: C:\Users\janne\project\b\print-args.exe
Arg 1: -DVAR1=foo.bar


So giving toolchain file like this works: cmake "-DCMAKE_TOOLCHAIN_FILE=../../toolchain.cmake"

I tried to search the Internet for clarification why PowerShell does this but so far I have not found anything.

You could solve this issue by using slash (/) instead of minus (-) on Windows like the native Windows tools do. With slash there is no issue with arguments like /DVAR=value.txt. As a Linux user I would prefer minus instead of slash for the arguments but having spent hours wondering why the toolchain is not working I'd like to have some kind of clean solution.
(0036848)
Brad King   
2014-09-22 12:57   
Re 0015164:0036847: Okay, we can't use '/' for options because they will look like paths (even on Windows, it can be a root-less path that assumes the current drive root). IMO using double quotes is the best solution.

BTW, if you're looking for a better shell than "cmd" on Windows, MSYS bash (perhaps from msysGit) in a "Console2" terminal is nice.
(0036850)
Janne Rönkkö   
2014-09-22 13:03   
I have mostly used cygwin under Windows but it has some downsides (like CMake finding cygwin version of different tools) so I have started to use as much native Windows tools as possible when building software on Windows. And some developers working for my client also use cmd.exe (and will probably use PowerShell at some point) so I have been using those tools also to see that everything works with native Windows tools also.

I agree that using double quotes is the best solution. At least there is now this bug that tells what the issue is if someone is using PowerShell and sets some values.


By the way, having two (or more) minuses on the argument does not trigger this behaviour, i.e. --DVAR=value.txt is seen as expected by the called program.

Thanks for your time while solving this issue. For me it's OK to close this bug as invalid or such as the issue is in PowerShell (or in me as I do not know how to use PowerShell...)
(0038130)
Robert Maynard   
2015-03-02 08:57   
Closing resolved issues that have not been updated in more than 4 months.