Skip to content

.cmake Adaptor (detection modules)? #83

Closed
@htfy96

Description

@htfy96

The main reason why I still stick to CMake is its builtin modules which provide compiler detection/package search/etc. It is unnecessary to reinvent the wheels, so I was wondering is it possible to provide (at least kind of) .cmake support and wrap these modules into xmake utilities?

Activity

waruqi

waruqi commented on May 10, 2017

@waruqi
Member

xmake also provide these features, so I don't intend to wrap them.

ghost

ghost commented on May 10, 2017

@ghost

Compiler detection of xmake is perfect

"Package search" is working on the way. You could have a look branch repo

Thanks for caring 😃

htfy96

htfy96 commented on May 10, 2017

@htfy96
Author

Thanks for reply. I'm just a little bit worried that there might be a lot more to do than you think. Take C++ as an example, we may need:

  • feature test: whether this compiler supports variadic template, or is it claimed supported but actually buggy?
  • compiler detection: we may be running clang frontend of MSVC, and many other corner cases
  • compiler*platform-specific options: including sanitize/floating point accuracy/etc.

Supporting .cmake may reduce some kind of work, I guess.

ghost

ghost commented on May 10, 2017

@ghost

I'd like to have a quick look into it this week

waruqi

waruqi commented on May 11, 2017

@waruqi
Member

@htfy96 You can use option to detect types, includes, funcs, links, cflags, ldflags and etc ..

for example:

option("test")
    add_define_if_ok("ENABLE_TEST")
    add_ctypes("wchar_t")
    add_cincludes("setjmp.h")
    add_cfuncs("sigsetjmp", "setjmp") 
--  add_cfuncs("sigsetjmp((void*)0, 0)")
--  add_cfuncs("sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}")
    add_links("pthread")

target("demo")
    add_options("test")
    ...

It will detect wchat_t, "setjmp.h", libpthread.a and sigsetjmp.

The demo target will define -DENABLE_TEST and link -lpthread if all tests are passed

waruqi

waruqi commented on May 11, 2017

@waruqi
Member

And you can add add_cxflags("-fsanitize=address", "-ftrapv") directly.

If compiler does not support these flags, It will ignore it automatically.

waruqi

waruqi commented on May 11, 2017

@waruqi
Member

xmake will detect msvc on windows by default automatically. If you want to use other compiler, you can set it manually. for example:

$ xmake f --cc=clang --cxx=clang --ld=clang
$ xmake

And it will detect clang, gcc, .. on linux/macos.

htfy96

htfy96 commented on May 11, 2017

@htfy96
Author

@waruqi

IIUC, according to your example xmake currently has no plan for builtin feature detection based on compiler version, instead, it provides basic utilities like add_cxxfuncs to allow custom detection. The main drawbacks of the absence of builtin has_variadic_template/support_cxx_11 include:

  • We have to compile during configuration for many times if we have a lot of orthogonal features to detect
  • Some feature detections are not as simple as add_cfuns(sigsetjmp((void*)0, 0) and requires heavy templates and domain knowledge

Actually I'm more willing to see something like enable_sanitize_address which adds proper flags for every compiler supporting this feature. Hard-coded/compiler-dependent flags are not encouraged from my perspective, and I want to completely eliminate these in my build scripts.

I'm referring to Clang/C2 frontend of MSVC. Take a look into CMake's patch set, and you'll find that checking _MSC_VER is not enough.

waruqi

waruqi commented on May 11, 2017

@waruqi
Member

@htfy96 Yes, xmake currently has no plan for builtin feature detection based on compiler version.

We have to compile during configuration for many times if we have a lot of orthogonal features to detect

This is only configured and detected once

Some feature detections are not as simple as add_cfuns(sigsetjmp((void*)0, 0) and requires heavy templates and domain knowledge

This is not a problem, the detection rules can be improved more flexibly.

Hard-coded/compiler-dependent flags

xmake takes the gcc flags as the standard and will map to other compiler flags smartly.

So these flags (-fsanitize=addres, -fomit-frame-pointer) are not hard-coded/compiler-dependent, you can see #71

About enable_sanitize_address , why not do the testing directly in the code?

#if (defined(__has_feature) && __has_feature(address_sanitizer)) || \
        defined(__SANITIZE_ADDRESS__)
...
#endif
htfy96

htfy96 commented on May 11, 2017

@htfy96
Author

@waruqi
Thanks for detailed reply. One more question, how can I switch flags based on whether a code snippet can compile without error? For example, I want to detect constexpr support:

option("test_cxx11_constexpr")
    add_defines_if_ok("CXX11_CONSTEXPR")
    add_cxxfuncs("has_cxx11_constexpr{ constexpr int f(int x) { return x ? x+f(x-1) : 0; } constexpr int x = f(5); static_assert(x == 15); ")

option("test_cxx14_constexpr")
    add_defines_if_ok("CXX14_CONSTEXPR")
    add_cxxfuncs("has_cxx14_constexpr{ constexpr int f(int x) { int sum=0; for (int i=0; i<=x; ++i) sum += i; return sum; } constexpr int x = f(5);  static_assert(x == 15);")

This doesn't seem to work. Older compilers do not support __has_feature

ghost

ghost commented on May 11, 2017

@ghost

Actually I'm more willing to see something like enable_sanitize_address

Now for flags adding, xmake uses gcc flags mapping

Advantage:

  • easier to remember

Disadvantage:

  • Some flags are not mapped yet. See automatic linker detection #71 I wanna to add a flag for coverage but -coverage is not mapped. And compilers are difficult so some flags cannot be implemented on some compiler

I agree with generic flags like what you said as a second choice

ghost

ghost commented on May 11, 2017

@ghost

A good problem @htfy96

Seems that not supported yet, right? @waruqi

htfy96

htfy96 commented on May 11, 2017

@htfy96
Author

And consider this case: user specified -fsanitize=address in xmake.lua, but actually the machine is running an older version of C2 on MSVC(e.g. Clang/C2 in MSVC14 Update 1) which has not sanitize support. How do you deal with such kind of issue?

The initiative of this issue is that compatibility/detection is extremely difficult. Manual checking could be very time-consuming and complicated. It is difficult to implement your own compiler database like CMake from scratch as well, since if you want to support N compilers, each of which has K versions, and you have P features to check, the database will soon balloons to N * K * P. Therefore, the best choice in this case is to adapt existing CMake databases.

waruqi

waruqi commented on May 11, 2017

@waruqi
Member

@htfy96 add_cxxfuncs and add_cfuncs only used to detect if the function interface exists. I will add add_cxxsnippets() to detect other feature support in the future, for example:

option("constexpr")
    add_csnippets("...")
    add_cxxsnippets("constexpr int f(int x) { int sum=0; for (int i=0; i<=x; ++i) sum += i; return sum; } constexpr int x = f(5);  static_assert(x == 15);")
waruqi

waruqi commented on May 11, 2017

@waruqi
Member

And consider this case: user specified -fsanitize=address in xmake.lua, but actually the machine is running an older version of C2 on MSVC(e.g. Clang/C2 in MSVC14 Update 1) which has not sanitize support. How do you deal with such kind of issue?

If has not sanitize support, add_cxflags("-fsanitize=addres") will be ignored automatically when building project

38 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @waruqi@htfy96

        Issue actions

          .cmake Adaptor (detection modules)? · Issue #83 · xmake-io/xmake