CMake Generator Error: Failure to Convert include_directories(...) See attached ZIP file

Support Team:

My code development is being blocked by the CMake Generator, which fails to generate any Unix Makefiles code from “include_directories” found in the CMakeLists.txt source.

Can anybody help figure out what is wrong? Many have tried and all have failed.

See the attached files and thoroughly read the "Include_Attachment.rtf” file to understand the Error that CMake is making.

If you cannot handle the attached ZIP file, then I can put all the files individually in my next email.

Thanks,
Garry Anderson.

Include_Archive.zip (12.9 KB)

This is the nth time you’ve posted this same question. What has been insufficient about the answers in the other threads where you’ve posted about this problem?

Hi Ben:

Please read this posting completely and correctly.

Nobody has read my postings correctly. Any replies have taken off on tangents because of their failure to read the question and understand the problem. For example, the question asked what can be done to make the Generator put something in the generated “makefile” that effectively reproduces the CMake “include_directories(…)” command. Answers have ranged from putting “include_directories” in the makefile (which does not work because “include_directories” is not a “make” command - it is a “cmake” command), to something must be wrong with my CMakeLists.txt file (essentially stating that the Microsoft Azure build system is faulty, even though it Azure works correctly with their CMake and Microsoft would not make such a mistake).

I have just tested my theory that the CMake Generator is failing to convert the “include_directories(…)” command by running the Generator with and without the “include_directories” command, and comparing the generated Unix “makefiles” and found them to be identical, thus proving my case the CMake Generator is at fault. It does not put any INC_FOLDER information into the generated “makefile”.

Some replies suggest using “include_directories” in makefile because those minds are thinking that “cmake” is being used in my case, even though my postings clearly state that “make makefile” is being used and it fails because some INC_FOLDERS are missing.

Other replies state that there is no equivalent for “include_directories” in “make” commands, thus any directories to be included must be done with -I on command line. This requires about 141 changes to projects to add -I somewhere (I don’t know where since there is no CFLAGS in the “makefile”). If this be the case, then the Generator should put CFLAGS with -I included when it generates the “makefiles” thus indicating there is an oversight in Generator design and/or operation.

One reply even stated that he was not going to look at my “CMakeLists.txt” or generated “makefile”, most likely because it was too much trouble or too difficult.

Also as I have mentioned before, a Generated “readme.md” file states that the INC_FOLDERS have been exported as global variables (within the CMake scope), but when CMake terminates so does the scope of these global variables, hence, any subsequent “make makefile” does not find any INC_FOLDERS and fails for that reason. Clearly, this is another oversight in Generator design and/or implementation to use a so-called “global variables” that disappear when CMake terminates. They are only global while CMake is running. This approach will never work for any subsequent “make makefile” operation. It is the wrong approach to use “global variables” to make these INC_FOLDERS available for the generated “makefile” to use. It will never work.

I think what I am seeing here is a lack of understanding of the scope of the problem by the community, and a gross failure to read my postings completely and correctly. So what good is a forum where none of the replies so far has even understood the problem or suggested a solution that works?

Perhaps you know somebody in the forum who actually knows how the Generator works and how to solve this problem. I find it hard to believe that I am the first one to find this Error in the Generator.

Sorry but I a getting very frustrated with this CMake community. I have reached out to Microsoft and they don’t take responsibility for CMake. They directed me to the CMake Discourse forums. I think the situation is hopeless.

Garry.

Creating new postings with the same information is not the way to resolve that problem.

Microsoft is not infallible. However, typically, problems are in the CMakeLists.txt files. And what is “Azure build system”? The CI infrastructure?

Use message(<args to include_directories>) to see what is going on. Or cmake --trace-expand (though that has much more information and message is more precise here). The variable you are passing to include_directories is probably empty. That means there’s nothing for CMake to do, hence the lack of a difference.

I see in your CMakeLists.txt:

include_directories(${MACRO_UTILS_INC_FOLDER})
include_directories(${UMOCK_C_INC_FOLDER})

Where are these variables supposed to come from? I see find_package above, but are you instead using the ones embedded via add_subdirectory? If the latter, the variables need to be visible at the scope you’re using them at. I’d trace back to see where they are defined and what scope they have.

If you’re doing add_subdirectory, there’s no such thing. I suspect they have a terminology problem; that variable likely only appears in their exported package file which means you need find_package for it.

No. CMake needs to know the variables when it runs. It puts everything it knows about into the generated files. There is no environment exported between the two. There’s no way to do so reliably.

CMake has been doing fine for 20+ years. Things aren’t behaving as you assume they can or must, but that doesn’t mean they’re broken.

I think my previous reply here gathered the problem correctly: the variable is not available at the scope you’re expecting. I suspect the readme you reference is about the find_package code it installs, not when it is used via add_subdirectory. That reply could have had more detail, but your response to it went off on a different direction (AFAICT).

Can you please have CMake output what is in those variables at the point of the include_directories? If they are empty as I suspect, I would recommend using cmake --trace-expand to find out where they are set/used in the subdirectory. You’ll then need to elevate their scope (set(var "${var}" CACHE INTERNAL "doc") would do it) so that they are visible at the top-level of the CMake code.

I know enough about how it works to diagnose this. There are some who know the Makefiles generator specifically more than I, but it’d be hard to find many with more overall knowledge of CMake’s build strategies and data flows.

Hi Ben:

Thanks for your detailed reply. As there is a lot of ground to cover, let’s go through it in pieces.

First, Azure is Microsoft’s competition to Amazon Web Services (AWS). It is their Cloud solution and is very popular in the Microsoft world. People who want to make IoT solutions have several choices, two of which are Azure and AWS. For this work, we have chosen Azure.

Azure provides complete IoT support with their Software Development Kit for Azure solutions (available on GitHub) called “Azure-IoT-SDK-C” for C-Language development. See here: https://github.com/Azure/azure-iot-sdk-c. When one clones the SDK package, it is self-contained and can be built with Visual Studio (I am using 2017 release). The SDK includes 70 projects that provide different solutions for the user to choose. Using VS2017, I build the “solutions” file (SLN file) that builds all 70 projects without error via their CMakeLists.txt files, so all their 70 top-level CMakeLists.txt files are working. From the list of 70 projects, I select one project to be the active project then use VS2017 to make that project active within all solutions. When I run the “active” project, it works correctly, thus I am quite confident that their solution for my active project is correct and complete. There are no compile errors or warnings. Everything is ready-to-go and works as a Windows application.

The MACRO_UTILS_INC_FOLDER definition is created when VS2017 compiles the projects, and the definition ends up in the “CMakeCache.txt” file as follows:

MACRO_UTILS_INC_FOLDER:INTERNAL=C:/az-iot/deps/azure-macro-utils-c/inc

From this “CMakeCache.txt” definition, the folder definition is used by the CMake build process, and it works. So, the definition is available to the Generator if it looks into this “CMakeCache.txt” file, so maybe that is where the error begins. The value of MACRO_UTILS_INC_FOLDER is passed correctly when using VS2017, which uses the CMake build system, and thus uses the Cache.txt files. Does the Generator not use the Cache files that CMake originally created?

I could try your suggestion for “message()” if you think that will help, but where do I put that in the code? The INC_FOLDER value already is resolved in the Cache.txt file. I don’t know how the CMake system works with VS2017, but somehow it does because it creates a working EXE file.

So I guess the next question is how do I include the CMakeCache.txt file into the Generator, so I access everything that was cached by the VS build operation?

I will attache the CMakeCache.txt file if I can figure out how to do that. From looking at this Cache.txt file, I think the whole thing needs to be considered by the Generator.

Thanks,
Garry.

CMakeCache.txt (66.4 KB)

It does. However, local variables shadow cached variables. There may be a local variable with an empty value floating around.

Right beside the include_directories:

message("MACRO_UTILS_INC_FOLDER: -->${MACRO_UTILS_INC_FOLDER}<--")

CMake reads it at the beginning of processing. It can be built up/changed during processing and then at the end, it is written back out as of the state at the end. The actual makefiles don’t care about it other than to tell CMake to rerun if it changes (which then rewrite the makefiles with the new changes).

Hi Ben:

Thanks for the assistance for placing the “message” command.

I put two of them in, as suggested with one for each INC_FOLDER, then captured the Generate output, which shows the directories are correct. One problem solved.

The I ran the top-level “make” command and got some errors about some “/WX: No such file or directory”. I have no clue about this. Can you help?

See the attached Log.txt file.

Thanks again,
Garry.

Make_Command_Log_Error.txt (1.3 KB)

If the directories work now, but not on CI, then you have a first vs. subsequent configure difference. That will require tracing down how the variables are defined and how they are set. Some cache variable interactions behave oddly on the first configure unfortunately :frowning: . I’ve been trying to fix them, but they’re tricky cases a lot of the time.

Could you run make VERBOSE=1 to see the full compilation command?

Sure.

Here is top-level make VERSOSE=1 capture log

Make_Command_Log_Error_Verbose.txt (2.3 KB)

Oh, this is mingw. Someone is adding Windows-like flags assuming Windows means MSVC. I’d search for who is adding that and change the condition from if (WIN32) to if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") (or something along those lines).

Hi Ben:

The original Azure SDK is based upon Windows platform, so that may be where WIN32 comes from.

The final destination for the code is an ARM micro controller, compiled by Eclipse - Wiced tools, on embedded hardware platform.

My first step is to get the Generator to compile the Azure library to compile with Eclipse on Windows platform. After I get the Generator to compile and only find errors related to WinRTOS and WinSockets, then I have to change them to FreeRTOS and WicedSockets.

I have not found a compile switch to use FreeRTOS instead of WinRTOS. The same goes for sockets.

Thanks for your suggestion about looking for WIN32. I will see what I can find.

Garry.

umock-c has the problem: