Skip to content

Building libcmaes on Windows 11 with Visual Studio 2022 #245

@chobby

Description

@chobby

I recently attempted to build libcmaes on Windows 11 using Visual Studio 2022 (MSVC) and encountered several issues. After resolving them, I wanted to share the complete build process for other Windows users.

  • Windows 11
  • Visual Studio 2022
  • vcpkg package manager
  • CMake

Steps

1. Install Dependencies using vcpkg

First, install the required dependencies using vcpkg:

vcpkg install eigen3:x64-windows
vcpkg install glog:x64-windows
vcpkg install gflags:x64-windows

2. Modify CMakeLists.txt

The original CMakeLists.txt needs to be modified to support MSVC compiler flags. Locate the compiler flags section and replace it with the following:

if(MSVC)
    # MSVC compiler flags
    set(CMAKE_CXX_FLAGS "/W4")
    set(CMAKE_CXX_FLAGS_DEBUG "/Zi /Od")
    set(CMAKE_CXX_FLAGS_RELEASE "/O2")
else()
    # GCC/Clang compiler flags
    set(CMAKE_CXX_FLAGS "-Wall -Wextra")
    set(CMAKE_CXX_FLAGS_DEBUG "-g")
    set(CMAKE_CXX_FLAGS_RELEASE "-O3")
endif()

3. Modify eigenmvn.h

The file include/libcmaes/eigenmvn.h needs to be modified to properly handle std::normal_distribution with MSVC. Locate the scalar_normal_dist_op class and replace it with the following implementation:

    template<typename Scalar>
      class scalar_normal_dist_op
      {
private:
    void swap(scalar_normal_dist_op &other) {
      std::swap(rng, other.rng);
      std::swap(norm, other.norm);
    }
public:
	static std::mt19937 rng;                        // The uniform pseudo-random algorithm
	mutable std::normal_distribution<Scalar> norm; // gaussian combinator
	
    scalar_normal_dist_op() : norm(Scalar(0), Scalar(1)) {}

    scalar_normal_dist_op(const scalar_normal_dist_op& other)
        : norm(other.norm) {
    }

    scalar_normal_dist_op& operator=(const scalar_normal_dist_op& other) {
        if (this != &other) {
            norm = other.norm;
        }
        return *this;
    }

    scalar_normal_dist_op(scalar_normal_dist_op&& other) noexcept
        : norm(std::move(other.norm)) {
    }

    scalar_normal_dist_op& operator=(scalar_normal_dist_op&& other) noexcept {
        if (this != &other) {
            norm = std::move(other.norm);
        }
        return *this;
    }

	template<typename Index>
	inline const Scalar operator() (Index, Index = 0) const { return norm(rng); }
	inline void seed(const uint64_t &s) { rng.seed(s); }
      };

    template<typename Scalar>
      std::mt19937 scalar_normal_dist_op<Scalar>::rng;
      
    template<typename Scalar>
      struct functor_traits<scalar_normal_dist_op<Scalar> >
      { enum { Cost = 50 * NumTraits<Scalar>::MulCost, PacketAccess = false, IsRepeatable = false }; };
    

4. Build the Library

Now you can build the library:

# Create and enter build directory
mkdir build
cd build

# Configure with CMake
cmake .. -DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake -DLIBCMAES_BUILD_TESTS=OFF -DLIBCMAES_BUILD_PYTHON=OFF -DLIBCMAES_USE_OPENMP=OFF -G "Visual Studio 17 2022" -A x64

# Build the library
cmake --build . --config Release

Replace [path to vcpkg] with your actual vcpkg installation path.

Key Changes Summary

  1. Compiler Flags: Added MSVC-specific compiler flags in CMakeLists.txt to handle the -Wextra flag issue.

  2. Dependencies: Used vcpkg for managing dependencies (eigen3, glog, gflags) instead of manual installation.

  3. MSVC Compatibility: Modified the scalar_normal_dist_op class in eigenmvn.h to:

    • Add proper constructors and assignment operators
    • Handle std::normal_distribution correctly
    • Ensure compatibility with MSVC's requirements

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions