Build issues on Windows 10
Closed this issue · 11 comments
When I try to call ngrest
or ngrest build
to start a service on Windows 10, I notice a couple quirks in the build process. First, the ngrest
bash script (invoked from ngrest.cmd
on Windows) does not seem to override my default CMake generator (Visual Studio project files) as it is supposed to. This appears to be due to the following code in the script's build()
function definition:
if [ $OS = MSYS ]
then
CMAKE_FLAGS+=" '-GUnix Makefiles' -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc"
fi
cmake $CMAKE_FLAGS $PROJECT_DIR >cmake.log || return $?
The generator argument gets ignored for some reason, and CMake proceeds as if it were generating a Visual Studio project. If I slightly modify the code as follows, then it generates the expected Unix Makefiles:
if [ $OS = MSYS ]
then
CMAKE_GENERATOR="Unix Makefiles"
cmake -G"$CMAKE_GENERATOR" -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc $PROJECT_DIR >cmake.log || return $?
else
cmake -DCMAKE_BUILD_TYPE=DEBUG $PROJECT_DIR >cmake.log || return $?
fi
I think the issue had something to do with the space in the generator name. A similar change might be advisable in the definition for build_package()
:
if [ $OS = MSYS ]
then
CMAKE_GENERATOR="Unix Makefiles"
cmake -G"$CMAKE_GENERATOR" ${CMAKE_FLAGS:-} "$2" >cmake-build.log
else
cmake ${CMAKE_FLAGS:-} "$2" >cmake-build.log
fi
#[ $OS != MSYS ] || CMAKE_FLAGS="'-GUnix Makefiles' ${CMAKE_FLAGS:-}"
#cmake "${CMAKE_FLAGS:-}" "$2" >cmake-build.log
The other quirk I noticed was that when I try to run ngrest(.cmd)
from a standard command prompt, I run into the following error when the script is running the make
command on the generated Makefile
:
Cannot create temporary file in C:\WINDOWS\: Permission denied
I'm not sure if this is something that I could easily change through some setting, but by default, make
seems to try putting temporary files in the WINDOWS
directory by default. I can get around this if I run the ngrest
command from a command prompt as an administrator, but I was curious if there was any simpler way to deal with this problem. If not, then it might be useful to add a remark about this to the "Create a new project" section of the readme.
Significantly, this issue causes the same problems for the basic installation on Windows. The problem in this case occurs on lines 114-121 of scripts/inst
:
echo "Configuring ngrest for the build..."
if [ $OS = MSYS ]
then
# supress platform warnings
touch /usr/share/cmake-$(cmake --version | sed '1{s/cmake version //;q}')/Modules/Platform/$(uname -s).cmake 2>/dev/null || true
CMAKE_FLAGS="${CMAKE_FLAGS:-} '-GUnix Makefiles' -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc"
fi
cmake ${CMAKE_FLAGS:-} ../ngrest >cmake-build.log
By changing these lines to the followig, the inst
script called from MSYS2 works as expected:
echo "Configuring ngrest for the build..."
if [ $OS = MSYS ]
then
# supress platform warnings
touch /usr/share/cmake-$(cmake --version | sed '1{s/cmake version //;q}')/Modules/Platform/$(uname -s).cmake 2>/dev/null || true
CMAKE_GENERATOR="Unix Makefiles"
cmake ${CMAKE_FLAGS:-} -G"$CMAKE_GENERATOR" -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc ../ngrest >cmake-build.log
else
cmake ${CMAKE_FLAGS:-} ../ngrest >cmake-build.log
fi
The version of the inst
script at http://bit.ly/ngrest may need to be updated accordingly. Unfortunately, I haven't been able to test if this works yet; running inst
directly from the MSYS2 MinGW 64-bit terminal gives me a "permission denied" error when the script tries to rename the ngrest
directory temporarily.
I'm sorry but it the windows support was not completed.
BTW, try starting the script from your home.
Also there is an option to run it under Ubuntu for Windows.
If I open up a new MSYS2 MinGW 64-bit terminal and try to run inst
from the home location, I still get the same "permission denied" error when the script invokes the mv
command.
It's good to know that Windows support isn't completed yet; I would have spent a lot of frustrating time trying to figure out what was going wrong, so thank you for letting me know ahead of time! I have an Ubuntu machine, so it will probably be easiest for me to develop on that.
The Permission error is a very strange error. It says you don't have permission to rename directory in your own home directory?
Try removing that directory manually and re-run installation script. Run this from MinGW terminal:
rm -rf $APPDATA/ngrest/ngrest $HOME/.ngrest
and then start usual installation process.
Also if you say you have cmake installed from visual studio - it wouldn't work because it configured for visual studio but it is not supported. Only cmake with WinGW gcc is supported.
Ah, I see what my problem was. I was getting the "permission denied" error because I was trying to call the inst
script in the $APPDATA/ngrest/ngrest
directory after I'd edited it; the mv
command didn't work because the inst
script was trying to move the directory that contains it. If I modify the script as outlined above, then copy it from $APPDATA/ngrest/ngrest/scripts
to $HOME
and run it from there (as I would if I was using the wget
command), then everything works.
I'm happy to say that the changes to the bash script also work as I hoped. The problem isn't that I have cmake
installed from Visual Studio; even if I change my PATH
so that the version of cmake
packaged in mingw64/bin
is the version I use, it defaults to generating Visual Studio Projects unless a different generator (e.g., Unix Makefiles
) is specified. My point is that when you try to specify a different generator in the inst
script (and the ngrest
script) with something like
CMAKE_FLAGS="${CMAKE_FLAGS:-} '-GUnix Makefiles' -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc"
...
cmake ${CMAKE_FLAGS:-} ../ngrest
cmake
doesn't parse the -G
argument the way you expect it to. It just ignores it, and if it detects a Windows machine with Visual Studio installed, it will default to generating a Visual Studio project instead of a Makefile. Rather than surrounding the -G
argument with single quotes, you need to place the Unix Makefiles
argument within quotes. But because of the space in the name, it doesn't quite work if you try to do it in a single line like you have here. I had to define a variable (CMAKE_GENERATOR
) that contained the generator string and then escape that in the cmake
call, with something like
cmake ${CMAKE_FLAGS:-} -G"$CMAKE_GENERATOR" -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc ../ngrest >cmake-build.log
Once I did that, the Makefile was correctly generated, and the installation process completed.
I'm also curious about the naming convention of ngrest
libraries on Windows. On lines 42-48 of ngrest/CMakeFiles.txt
, you appear to use the following lines to strip the Unix lib
prefix and .a
suffix from the generated libraries:
if (MINGW)
add_definitions(-D_WIN32_WINNT=0x0501)
set(CMAKE_SHARED_LIBRARY_PREFIX "")
set(CMAKE_SHARED_MODULE_PREFIX "")
set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")
set(CMAKE_SHARED_MODULE_SUFFIX ".dll")
endif()
This seems to work for the libraries placed in the deploy/bin
directory, but not for the ones placed in deploy/lib
. Is this the intended behavior?
As I understand under Windows any dynamic library must be placed into the same dir as executable.. Unlike linux to link the dynamic library you must link .a file instead.. So guess that's correct..
That makes sense. The shared libraries seem to be getting written correctly, then. Apart from my suggested changes to the cmake
calls in ngrest
and inst
, I don't have anything else to add to this issue.
Ok, I think I fixed it, can you please re-test?
I just re-tested it. The installation completely successfully, and ngrest
is generating Unix Makefiles for services as expected. Thanks!
Great! Thank you.