Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIndows CMake: work with non-MSVC compilers too #493

Merged
merged 15 commits into from
Nov 26, 2021

Conversation

scivision
Copy link
Contributor

@scivision scivision commented Nov 4, 2021

fixes #492

This was tested with GCC, Clang, and Intel oneAPI on Windows.

adds numerous tests as in Autotools-based builds.

This is also the foundation for using CMake on any platform instead of autotools.

Avoids the constant full rebuilding by using configure_file() instead of explicit file()

@scivision
Copy link
Contributor Author

scivision commented Nov 4, 2021

The WinCmake CI appears to be missing the files I added. Is it extracting some autotools-generated source archive I need to add the new files to a manifest of?

@bgoglin
Copy link
Contributor

bgoglin commented Nov 4, 2021

Your files are missing because they are not in make dist (generated by automake on one Unix CI slave before passing the resulting tarball to many different CI slaves). For contrib/windows/private_config.h.in, move it to contrib/windows-cmake/, it will be auto-added (contrib/windows/ is only for the MSVC solution). For tests/hwloc/CMakeLists.txt, add it to EXTRA_DIST at the end of tests/hwloc/Makefile.am

@scivision scivision force-pushed the win32-gcc branch 3 times, most recently from c4cdc4d to e7eed0c Compare November 4, 2021 13:23
@scivision
Copy link
Contributor Author

OK now it works in Jenkins too

@bgoglin
Copy link
Contributor

bgoglin commented Nov 5, 2021

Thanks. Can you actually run the tests from contrib/ci.inria.fr/job-1-wincmake.bat ?

/entry:mainCRTStartup is needed for lstopo-win with MSVC but we also need -mwindows instead when building with other compilers (it works with gcc, I don't know about icc on windows). The idea is that lstopo-win is a native windows program (only opens the lstopo window) while lstopo and lstopo-no-graphics use a console and then run lstopo inside it.

On the cosmetic side, can you use a real email instead of scivision@users.noreply.github.com in your signed-off-by lines? And prefix your commit first lines with "windows-cmake:" instead of "windows:" or nothing.

Also add a sentence saying that you don't use stop using windows/private_config.h anymore but your own private_config.h.in for CMake.

Put "fixes" near the __cpuidex line in the commit message too.

Finally, I am not very familiar with CMake and I'll likely forget about all the details within a month. Hence I'd like a bit more explanation in either the commit log or in the CMakeLists.txt. Maybe explain why/how you use target_include_directories, add_library, target_link_library, target_compile_definitions instead of set_target_properties.

Comment on lines +33 to +51
set(HWLOC_X86_32_ARCH)
set(HWLOC_X86_64_ARCH)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
set(HWLOC_X86_32_ARCH)
set(HWLOC_X86_64_ARCH)
set(HWLOC_X86_32_ARCH "")
set(HWLOC_X86_64_ARCH "")

you want to set them empty and not unset previous values correct?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know about the CMake syntax but they should be either 1 or undefined in the end, not empty.

Copy link
Contributor

@Neumann-A Neumann-A Nov 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you want to have them undefined? Be aware that user might pass -DHWLOC_X86_64_ARCH=1 via the CMake command line. If you don't want that you need to define the variable in local scope.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we change this behavior for CMake, we have to change in configure and in the MSVC solution, and update several code paths using those macros. That's possible, but outside of this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting them empty in CMake script gives a known state (undefined in header file). Setting them without any argument is akin to boolean false, which is interpreted by #cmakedefine statement in the *.h.in files as undefined header.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting them without any argument is akin to boolean false, which is interpreted by #cmakedefine statement in the *.h.in files as undefined header.

Setting them to "" also achieves that. The CMake docs say:

"depending on whether VAR is set in CMake to any value not considered a false constant by the if() command."

If docs:

"False if the constant is 0, , the empty string, or ends in the suffix -NOTFOUND"

@bgoglin:

If we change this behavior for CMake, we have to change in configure and in the MSVC solution, and update several code paths using those macros. That's possible, but outside of this PR.

I don't want people to pass -DHWLOC_X86_64_ARCH=1 via the cmd line. I just mentioned it that you might need consider that and set(HWLOC_X86_64_ARCH) vs set(HWLOC_X86_32_ARCH "") have different behavior in this case.

@scivision scivision force-pushed the win32-gcc branch 5 times, most recently from 69bda5d to 66722aa Compare November 7, 2021 06:09
@scivision
Copy link
Contributor Author

It looks like the GUIs work without the -mwindows for GCC ?

@bgoglin
Copy link
Contributor

bgoglin commented Nov 7, 2021

It looks like the GUIs work without the -mwindows for GCC ?

Yes, the GUI works, but there are two versions: lstopo opens a console that launches the GUI. lstopo-win is a native windows program that directly launches the GUI without opening a console first. That's what -mwindows does in gcc mingw/cygwin and /entry:mainCRTStartup in MSVC. Not sure it exists for ICC. If not, there are other ways to configure this.

@scivision
Copy link
Contributor Author

scivision commented Nov 7, 2021

OK thanks by using Windows Start>Run menu I can confirm that -mwindows opens GUI without a console, while omitting that flag also opens a console on invocation. This is for MSYS2/MinGW GCC.

However, Clang silently accepts -mwindows but it has no effect--a console window still opens.

CMake has a target property WIN32_EXECUTABLE that automatically sets the correct flags for this instead--which works for Clang etc.

@scivision scivision force-pushed the win32-gcc branch 4 times, most recently from 9a8ab88 to f5e0b99 Compare November 7, 2021 16:18
@bgoglin
Copy link
Contributor

bgoglin commented Nov 7, 2021

I see that you're conditionally adding some backends to the build. Note sure if you saw that it requires to update the the array of components in static-components.h. OpenCL and libXML lines just look like others. The order doesn't matter:
&hwloc_opencl_component,
&hwloc_xml_libxml_component,

@scivision
Copy link
Contributor Author

scivision commented Nov 7, 2021

so static-components.h should become dynamically configured and use #ifdef conditions in it?

best practice to use absolute reference for relative paths

Signed-off-by: Michael Hirsch <michael@scivision.dev>
Signed-off-by: Michael Hirsch <michael@scivision.dev>
Signed-off-by: Michael Hirsch <michael@scivision.dev>
Signed-off-by: Michael Hirsch <michael@scivision.dev>
@scivision
Copy link
Contributor Author

yes I just rebased on master for convenience. I think there were some naming/stylistic topics noted above, and the desire to make a CMake and Pkg-config script, but they might be handled in another PR to avoid further overloading this PR?

Naming targets with a "lib" prefix is unconventional for CMake and
causes unexpected file naming. Instead, we set
CMAKE_*_LIBRARY_PREFIX to name libhwloc.* consistently across
platforms

Signed-off-by: Michael Hirsch <michael@scivision.dev>
scivision and others added 10 commits November 15, 2021 17:10
Signed-off-by: Michael Hirsch <michael@scivision.dev>
Signed-off-by: Michael Hirsch <michael@scivision.dev>
Signed-off-by: Michael Hirsch <scivision@users.noreply.github.com>
Signed-off-by: Michael Hirsch <michael@scivision.dev>
Signed-off-by: Michael Hirsch <michael@scivision.dev>
Signed-off-by: Michael Hirsch <michael@scivision.dev>
Signed-off-by: Michael Hirsch <michael@scivision.dev>
Signed-off-by: Michael Hirsch <michael@scivision.dev>

Co-authored-by: Alexander Neumann <30894796+Neumann-A@users.noreply.github.com>
Signed-off-by: Michael Hirsch <michael@scivision.dev>
Signed-off-by: Michael Hirsch <michael@scivision.dev>
@bgoglin
Copy link
Contributor

bgoglin commented Nov 16, 2021

yes I just rebased on master for convenience. I think there were some naming/stylistic topics noted above, and the desire to make a CMake and Pkg-config script, but they might be handled in another PR to avoid further overloading this PR?

Yes, feel free to keep pkg-config for another PR later.

@bgoglin
Copy link
Contributor

bgoglin commented Nov 17, 2021

Are we ready for merge then?

3 questions from the non-windows guy:

  • I get hwloc.lib instead of libhwloc.lib in our MSVC builds, does this matter anyhow?
  • we don't get any DLL because only static libraries are built by default? that's OK for external projects that will link to hwloc?
  • are usual warnings enabled during the build (the equivalent of -Wall, etc)? I usually see some warnings when building on Windows, but I don't see any here.

@Neumann-A
Copy link
Contributor

I get hwloc.lib instead of libhwloc.lib in our MSVC builds, does this matter anyhow?

the autotool build will also generated hwloc.lib

we don't get any DLL because only static libraries are built by default? that's OK for external projects that will link to hwloc?

just set https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html to ON via the cmake cmd line (e.g. -DBUILD_SHARED_LIBS=ON)?

are usual warnings enabled during the build (the equivalent of -Wall, etc)?

Warning flags don't belong in build scripts. They belong in the toolchain files or should be set via the cmake cmd line.

@bgoglin
Copy link
Contributor

bgoglin commented Nov 17, 2021

I get hwloc.lib instead of libhwloc.lib in our MSVC builds, does this matter anyhow?

the autotool build will also generated hwloc.lib

I don't know about MSVC but current GCC builds generate libhwloc.lib. But that's not the question anyway. The question is whether it's normal.

we don't get any DLL because only static libraries are built by default? that's OK for external projects that will link to hwloc?

just set https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html to ON via the cmake cmd line (e.g. -DBUILD_SHARED_LIBS=ON)?

Again, I want to know if that's normal and fine for most external projects.

are usual warnings enabled during the build (the equivalent of -Wall, etc)?

Warning flags don't belong in build scripts. They belong in the toolchain files or should be set via the cmake cmd line.

Default flags should be sane. Building with GCC without -Wall would be insane. What are the default flags?

@Neumann-A
Copy link
Contributor

The question is whether it's normal.

depends on your view. I would say for windows not having the lib prefix is normal. (there is already a .lib suffix ...)

Again, I want to know if that's normal and fine for most external projects.

It doesn't matter. Projects which require shared libraries due to e.g. license issues can simply pass -DBUILD_SHARED_LIBS=ON. (or do you supply prebuild libraries?)

Default flags should be sane. Building with GCC without -Wall would be insane. What are the default flags?

Again depends on the view. -Wall might be useful for you as a developer of hwloc but for consumers of the library building hwloc with Wall is meaningless. If the build is successful it is assumed that the library can be used without issues. Default flags on linux for cmake are mainly defined by the environment or given via the cmd line or a toolchain.

@bgoglin
Copy link
Contributor

bgoglin commented Nov 17, 2021

We supplied prebuilt libraries until now because building was difficult. We may stop at some point in the future since things are much easier now.

@scivision
Copy link
Contributor Author

scivision commented Nov 17, 2021

target naming

We can make the library file prefix "lib" with MSVC as well, but this is unconventional for MSVC.
It's up to project preference.
It's a simple option in CMake to do this. CMake default is for all compilers except MSVC to have library filename prefix "lib".

shared/static

We could set BUILD_SHARED_LIBS, a special CMake variable, to the desired default. The default is false, which makes static hwloc.

Compiler flags

There are a few different philosophies on this. My personal practice is to have CMake script contain the per-compiler flags for Debug and Release, etc. selected by if(CMAKE_C_COMPILER_ID ...) elseif(...)

Another approach is with CMakePresets.json, to specify variables like CC and CFLAGS. This is a simple way to specify sets of configurations to use from CI.

@bgoglin
Copy link
Contributor

bgoglin commented Nov 25, 2021

@scivision I am going to merge this later today unless somebody complains. I am thinking of releasing 2.7 with this very soon because we have many additional changes for Windows that don't deserve to wait several months before public release.

@scivision
Copy link
Contributor Author

scivision commented Nov 25, 2021

OK Brice--I think this is a good milestone as we've incorporated many helpful improvements suggested by yourself and Alexander. Certainly can be more done to improve in the future.

@bgoglin bgoglin merged commit 69dd7f8 into open-mpi:master Nov 26, 2021
@scivision scivision deleted the win32-gcc branch November 26, 2021 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CMake: non-MSVC builds fail because MSVC CPUIDEX is used instead of x86 asm
3 participants