Android studio compile JNI problem ninja: fatal: couldn't open nul solution

  In the past few days, when compiling the same text trime input method, I encountered an unsolvable problem. I searched the Internet and found no answer. Is it true that no one has encountered a similar problem. The problem description is as follows:

D:\project\andriod\trime-develop\app\src\main\jni\CMakeLists.txt : C/C++ debug|x86 : CMake Error at C:/Users/Administrator/AppData/Local/Android/Sdk/cmake/3.18.1/share/cmake-3.19/Modules/CMakeTestCCompiler.cmake:68 (message):
  The C compiler

    "C:/Users/Administrator/AppData/Local/Android/Sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: D:/project/andriod/trime-develop/app/.cxx/cmake/debug/x86/CMakeFiles/CMakeTmp
    
    Run Build Command(s):C:\Users\Administrator\AppData\Local\Android\Sdk\cmake\3.18.1\bin\ninja.exe 
    cmTC_3c0a9 && ninja: fatal: couldn't open nul

So I found the CMakeTestCCompiler.cmake file and found that the following code reported an error:

  file(WRITE ${
    
    CMAKE_BINARY_DIR}${
    
    CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c
    "#ifdef __cplusplus\n"
    "# error \"The CMAKE_C_COMPILER is set to a C++ compiler\"\n"
    "#endif\n"
    "#if defined(__CLASSIC_C__)\n"
    "int main(argc, argv)\n"
    "  int argc;\n"
    "  char* argv[];\n"
    "#else\n"
    "int main(int argc, char* argv[])\n"
    "#endif\n"
    "{ (void)argv; return argc-1;}\n")
  #message(FATAL_ERROR "hello world")
  try_compile(CMAKE_C_COMPILER_WORKS ${
    
    CMAKE_BINARY_DIR}
    ${
    
    CMAKE_BINARY_DIR}${
    
    CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c
    OUTPUT_VARIABLE __CMAKE_C_COMPILER_OUTPUT)
  # Move result from cache to normal variable.
  set(CMAKE_C_COMPILER_WORKS ${
    
    CMAKE_C_COMPILER_WORKS})
  unset(CMAKE_C_COMPILER_WORKS CACHE)
  __TestCompiler_restoreTryCompileTargetType()
  if(NOT CMAKE_C_COMPILER_WORKS)
    PrintTestCompilerResult(CHECK_FAIL "broken")
    file(APPEND ${
    
    CMAKE_BINARY_DIR}${
    
    CMAKE_FILES_DIRECTORY}/CMakeError.log
      "Determining if the C compiler works failed with "
      "the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
    string(REPLACE "\n" "\n  " _output "${__CMAKE_C_COMPILER_OUTPUT}")
    message(FATAL_ERROR "hello world, The C compiler\n  \"${CMAKE_C_COMPILER}\"\n"
      "is not able to compile a simple test program.\nIt fails "
      "with the following output:\n  ${_output}\n\n"
      "CMake will not be able to correctly generate this project.")

  The hello world in the message command was added by me to locate the problem. The file command writes the test code into testCCompiler.c, and the try_compile command compiles it. If it succeeds, the value of CMAKE_C_COMPILER_WORKS is true. It's such a simple test code that reports an error! !
  So I downloaded the ninja code from github, found the subprocess-win32.cc file and found the place where the error was reported as follows:

bool Subprocess::Start(SubprocessSet *set, const string &command)
{
    
    
        HANDLE child_pipe = SetupPipe(set->ioport_);

        SECURITY_ATTRIBUTES security_attributes;
        memset(&security_attributes, 0, sizeof(SECURITY_ATTRIBUTES));
        security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
        security_attributes.bInheritHandle = TRUE;
        // Must be inheritable so subprocesses can dup to children.必须是可继承的,以便子进程可以复制到子进程
        // HANDLE nul = CreateFileA("D:\testCCompiler.c", GENERIC_READ,
        HANDLE nul = CreateFileA("NUL", GENERIC_READ,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        &security_attributes, OPEN_EXISTING, 0, NULL);
        if (nul == INVALID_HANDLE_VALUE)
                Fatal("hello world, couldn't open nul");

  I found that the first parameter of the CreateFileA function was actually NUL, and I thought that Google is a scam. So I changed it to D:\testCCompiler.c and found that it was wrong. At this time, there is nothing to do and cry! !
  When compiling ninja, it is obviously good. Compiling with gcc is also successful, and compiling with msvc is no problem. Why does compiling on android studio fail? I wonder if the cmake version of ndk is too low, and it is useless to upgrade to 3.18.1. So the file in the local cmake 3.9 is replaced by the file in ndk and the result of recompilation is still the same.
  It is speculated that when compiling ninja with local cmake, make is used but ninja is not used, and android studio uses ninja, so the error will occur. By this time there was nothing to be done. There are only two ways now, one is to fix the ninja problem, and the other is to replace ninja with make. I am new to Android development and I am not familiar with many things.
  Copy the ninja.exe in cmake under ndk to the bin folder of the independently installed cmake, and replace make with ninja, it still doesn't work, the output is as follows:

PS D:\projectcode\ninja-master\build_ninja> cmake -G Ninja ..
-- The C compiler identification is GNU 8.1.0
-- The CXX compiler identification is GNU 8.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - failed
-- Check for working C compiler: C:/mingw64/bin/gcc.exe
-- Check for working C compiler: C:/mingw64/bin/gcc.exe - broken
CMake Error at E:/Program Files/CMake/share/cmake-3.19/Modules/CMakeTestCCompiler.cmake:68 (message):
  The C compiler

    "C:/mingw64/bin/gcc.exe"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: D:/projectcode/ninja-master/build_ninja/CMakeFiles/CMakeTmp

    Run Build Command(s):E:/PROGRA~2/CMake/bin/ninja.exe cmTC_753f8 && ninja: fatal: couldn't open nul

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:6 (project)

-- Configuring incomplete, errors occurred!
See also "D:/projectcode/ninja-master/build_ninja/CMakeFiles/CMakeOutput.log".
See also "D:/projectcode/ninja-master/build_ninja/CMakeFiles/CMakeError.log".
PS D:\projectcode\ninja-master\build_ninja>

If not, you can only change the platform and get it on ubuntu.


#################################################### ##################
  I have been struggling with this issue for many days. If the ninja: fatal: couldn't open nul problem is not resolved, I cannot proceed to the following problems. It's not the problem with google's ninja, it's the problem with win10. It is no problem to switch to win7. According to the answer on the Internet, it should be that C:\Windows\System32\drivers\null.sys is damaged, so I replaced null.sys, but it did not solve it. Executing the following command says that the specified service is not installed.

C:\Windows\System32\drivers>sc query Null
[SC] EnumQueryServicesStatus:OpenService 失败 1060:

指定的服务未安装。

It is no problem to switch to win7

Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。

C:\Windows\system32>sc query null

SERVICE_NAME: null
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

C:\Windows\system32>

NUL should be a device or service, the following is found on the Internet:
Windows设备名称 "aux","com1","com2","prn","con","nul"等,因为这些名字都属于设备名称,等价于一个 DOS 设备,如果我们把文件命名为这些名字,Windows 就会误以为发生重名,所以会提示“不能创建同名的文件”etc.

  So I changed the place where the error was reported in the subprocess-win32.cc file in the ninja code HANDLE nul = CreateFileA(“NUL”, GENERIC_READ to
HANDLE nul = CreateFileA(“con”, GENERIC_READ unexpectedly succeeded.

bool Subprocess::Start(SubprocessSet *set, const string &command)
{
    
    
        HANDLE child_pipe = SetupPipe(set->ioport_);

        SECURITY_ATTRIBUTES security_attributes;
        memset(&security_attributes, 0, sizeof(SECURITY_ATTRIBUTES));
        security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
        security_attributes.bInheritHandle = TRUE;
        // Must be inheritable so subprocesses can dup to children.必须是可继承的,以便子进程可以复制到子进程
        // HANDLE nul = CreateFileA("D:\testCCompiler.c", GENERIC_READ,
        HANDLE nul = CreateFileA("con", GENERIC_READ,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        &security_attributes, OPEN_EXISTING, 0, NULL);
        if (nul == INVALID_HANDLE_VALUE)
                Fatal("hello world, couldn't open nul");

Although the problem is solved, it may cause other bugs because of this problem if it is not completely solved.


#################################################### #########

Finally solved the problem completely today.

  I downloaded several null.sys on the Internet to replace the original C:\Windows\System32\drivers\null.sys, but the results were all unsuccessful. Be sure to execute the following two commands, otherwise the null.sys file cannot be deleted, and permission is required.

PS D:\projectcode\ninja-master\build_ninja> takeown /f C:\Windows\System32\drivers\null.sys

成功: 此文件(或文件夹): "C:\Windows\System32\drivers\null.sys" 现在由用户 "YANGSAIL\Administrator" 所有。
PS D:\projectcode\ninja-master\build_ninja> icacls C:\Windows\System32\drivers\null.sys /grant administrators:F

Manually delete null.sys, download the win10 operating system to the virtual machine and install it, copy null.sys to the local system C:\Windows\System32\drivers and execute the sc command again as follows:

D:\projectcode\ninja_test>sc query null

SERVICE_NAME: null
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

D:\projectcode\ninja_test>

It worked!
Keep the place where the error is reported in the subprocess-win32.cc file in the ninja code HANDLE nul = CreateFileA(“NUL”, recompile and generate ninja.exe to replace E:\CMake\bin\ninja.exe, use ninja.exe to compile the ninja project as follows :

PS D:\projectcode\ninja-master\build_ninja\ninja-master\build_ninja> ninja -f build.ninja
[8/8] Linking CXX executable ninja_test.exe
PS D:\projectcode\ninja-master\build_ninja\ninja-master\build_ninja>

success! !

Recompiling the trime input method is also successful.
Explain that ninja: fatal: couldn't open nul was completely solved, happy!

Guess you like

Origin blog.csdn.net/yangjia_cheng/article/details/122111118