conan icon indicating copy to clipboard operation
conan copied to clipboard

[question] How to properly set preprocessor flags in conan2 profiles to crosscompile autotools-based recipes

Open ericriff opened this issue 1 year ago • 3 comments

What is your question?

In order to crosscompile for arm32 I've set up this profile

[settings]
os=Linux
arch=armv7hf
compiler=gcc
compiler.version=11
compiler.libcxx=libstdc++11
build_type=Release

[conf]
tools.build:compiler_executables = {"cpp": "arm-poky-linux-gnueabi-g++", "c": "arm-poky-linux-gnueabi-gcc"}
# Don't quote this https://github.com/conan-io/conan/issues/16914
tools.build:sysroot = /opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi
tools.build:cflags = ["-march=armv7-a", "-mthumb", "-mfpu=neon", "-mfloat-abi=hard", "-fstack-protector-strong"]
tools.build:cxxflags = ["-march=armv7-a", "-mthumb", "-mfpu=neon", "-mfloat-abi=hard", "-fstack-protector-strong"]

# CMake won't set CMAKE_SYSTEM_PROCESSOR unless SYSTEM_NAME is also set
tools.cmake.cmaketoolchain:system_name = "Linux"
tools.cmake.cmaketoolchain:system_processor = "armv7"

This works fine for CMake-based recipes but consistently fails for all autotools-based ones with a rather cryptic message

conan create recipes/apr/all/ --version 1.7.4 -pr:b x86_64 -pr:h arm32
<...>
checking whether arm-poky-linux-gnueabi-gcc accepts -g... yes
checking for arm-poky-linux-gnueabi-gcc option to enable C11 features... none needed
checking how to run the C preprocessor... /lib/cpp

The config.log throws some light into the isue:

configure:6658: checking how to run the C preprocessor
configure:6684: arm-poky-linux-gnueabi-gcc -E  -DNDEBUG conftest.c
In file included from /opt/arm32-sdk/sysroots/x86_64-pokysdk-linux/usr/lib/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/11.3.0/include-fixed/syslimits.h:7,
                 from /opt/arm32-sdk/sysroots/x86_64-pokysdk-linux/usr/lib/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/11.3.0/include-fixed/limits.h:34,
                 from conftest.c:9:
/opt/arm32-sdk/sysroots/x86_64-pokysdk-linux/usr/lib/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/11.3.0/include-fixed/limits.h:203:75: error: no include path in which to search for limits.h
  203 | #include_next <limits.h>                /* recurse down to the real one */
      |                                                                           ^

This type of error usually means that --sysroot was not set. Since there is no tools.build:cppflags to set preprocessor flags, I used the old workflow and set an env variable

[buildenv]
CPPFLAGS=--sysroot=/opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi

This took me further, but now the preprocessor complains about hard-float / soft-float stuff

configure:6658: checking how to run the C preprocessor
configure:6684: arm-poky-linux-gnueabi-gcc -E --sysroot=/opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi -DNDEBUG conftest.c
In file included from /opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi/usr/include/gnu/stubs.h:40,
                 from /opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi/usr/include/features.h:514,
                 from /opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi/usr/include/bits/libc-header-start.h:33,
                 from /opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi/usr/include/limits.h:26,
                 from /opt/arm32-sdk/sysroots/x86_64-pokysdk-linux/usr/lib/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/11.3.0/include-fixed/limits.h:203,
                 from /opt/arm32-sdk/sysroots/x86_64-pokysdk-linux/usr/lib/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/11.3.0/include-fixed/syslimits.h:7,
                 from /opt/arm32-sdk/sysroots/x86_64-pokysdk-linux/usr/lib/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/11.3.0/include-fixed/limits.h:34,
                 from conftest.c:9:
/opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi/usr/include/gnu/stubs-32.h:7:11: fatal error: gnu/stubs-soft.h: No such file or directory
    7 | # include <gnu/stubs-soft.h>
      |           ^~~~~~~~~~~~~~~~~~

This means that the preprocessor is not getting tools.build:cflags either. So I updated my env variable and now it works

[buildenv]
CPPFLAGS=-march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -fstack-protector-strong --sysroot=/opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi
  1. Is there a reason why tools.build:cflags are not passed to the preprocessor?
  2. Is there a reason why tools.build:cppflags flags doesn't exists?
  3. What's the appropiate way of setting these flags? Using an env variable for the pre processor flags and conan-native configs for the C/C++ flags seems odd.

I tried to get creative and set these flags and the sysroot as part of the tools.build:compiler_executables which made autotools-based recipes happy but broke cmake-based ones

tools.build:compiler_executables = {"cpp": "arm-poky-linux-gnueabi-g++ -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -fstack-protector-strong --sysroot=/opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi", "c": "arm-poky-linux-gnueabi-gcc -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -fstack-protector-strong --sysroot=/opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi"}
tools.build:compiler_executables = {"cpp": "arm-poky-linux-gnueabi-g++", "c": "arm-poky-linux-gnueabi-gcc"}
conan create recipes/gtest/all/ --version 1.15.0 -pr:b x86_64 -pr:h arm32
<...>
-- The C compiler identification is unknown
CMake Error at CMakeLists.txt:2 (project):
  The CMAKE_C_COMPILER:

    arm-poky-linux-gnueabi-gcc -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -fstack-protector-strong --sysroot=/opt/arm32-sdk/sysroots/armv7at2hf-neon-poky-linux-gnueabi

  is not a full path and was not found in the PATH.

  Tell CMake where to find the compiler by setting either the environment
  variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
  the compiler, or to the compiler name if it is in the PATH.

Thanks in advance.

Have you read the CONTRIBUTING guide?

  • [X] I've read the CONTRIBUTING guide

ericriff avatar Sep 05 '24 21:09 ericriff

Hi @ericriff

Thanks for your question.

I understand that we are talking here mostly about AutootoolsToolchain. This generator has a definition of CPPFLAGS with:

env.append("CPPFLAGS", ["-D{}".format(d) for d in self.defines])

That is, only adding the explicit preprocessor definitions.

This is mostly consistent with the inputs that we provide to CMakeToolchain So the truth is there hasn't been the use case so far, the tools.build:cflags|cxxflags are really intended for compiler flags for C/C++ compilers, but not for preprocessor.

The inputs that you specify above:

CPPFLAGS=-march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -fstack-protector-strong --sysroot=

doesn't seem valid preprocessor flags, at least in the GNU toolchain: https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html, I am not sure the preprocessor should get those, I think the issue might be something different?

memsharded avatar Sep 24 '24 22:09 memsharded

On that link you shared, you'll find that --sysroot is valid.

In addition to the options listed here, there are a number of options to control search paths for include files documented in [Options for Directory Search](https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html).

And without them, the AutoTools based recipes fail to find the right preprocessor as detailed on my first post.

ericriff avatar Sep 25 '24 16:09 ericriff

I "validated" these options are valid by just adding an obviously fake one and verified it complains

$ arm-poky-linux-gnueabi-cpp -mfoo
arm-poky-linux-gnueabi-cpp: error: unrecognized command-line option ‘-mfoo’

Yet is happy about my options

$ arm-poky-linux-gnueabi-cpp -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -fstack-protector-strong --sysroot=<path>

ericriff avatar Sep 25 '24 16:09 ericriff