В последнее время со сборкой JDK в Windows всё стало хорошо и приятно, поэтому поделюсь радостью и распишу, как это делается.

Каждый второй, кто пытается собрать что-то под Windows, получет глубокую психологическую травму, и заранее ожидает от сборки следующих эмоций:



Что касается JDK, если не сходить с пряничной дорожки, делать в точности как в этой инструкции, проблем не будет. Возможные проблемы обозначены в тексте.

Общий смысл происходящего: устанавливаем компиляторы (JDK8, Visual Studio 2013), среду сборки (GNU/Cygwin) и набор стандартных пакетов для неё, собираем из исходников Freetype, заливаем репозиторий JDK, configure, make, java -version.

Мы будем собирать Java и C++ (раз вы читаете эту статью, то, наверное, уже в курсе), поэтому на микроволновке лучше сборкой не заниматься. Нужна рабочая станция или ноутбук с нормальным процессором, и, желательно, SSD вместо жесткого диска для сборочной директории проекта. Кроме сборки, какое-то время потратится на скачивание исходника и установку Visual Studio.

Понадобится подключение к интернету и права администратора Windows. Проблемы пользователей корпоративной инфраструктуры, где всего этого нет, здесь не рассматриваются.

  1. Устанавливаем JDK8


    для бута.

    Ссылка на загрузку.

  2. Устанавливаем Visual Studio 2013


    (версия Express подойдёт).

    Ссылка на загрузку. Если вы устанавливаете полную версию, то при установке вам дадут выбор компонентов: достаточно установить только те компоненты, которые относятся к C++ и Windows SDK.

    При установке Express, никакого выбора не будет — к счастью, оно само устанавливает именно то, что нам нужно. Это выглядит как-то так:




    После установки, обязательно нужно перезагрузить операционную систему.

    Важно: нужно установить именно Visual Studio 2013. Не ниже потому, что о версии 2013 говорится в Build Readme. Не выше потому, что если попробовать провести сборку с установленной Visual Studio 2015, то сборщик JDK будет видеть компилятор, но будет ломаться с ошибкой:

    C compiler cannot create executables

    Если заглянуть в config.log, становится понятна причина:

    LINK : fatal error LNK1104: cannot open file 'LIBCMT.lib'

    Если тупо сделать

    export LINK="/NODEFAULTLIB:libcmt.lib"

    то оно развалится:

    unresolved external symbol mainCRTStartup.

    Если кто-то в комментариях знает, как безболезненно починить эту ошибку и запуститься на 2015, буду очень благодарен. Неприятно быть залоченным на устаревшую версию компилятора, даже если она бесплатная.

  3. Устанавливаем Cygwin.


    Ссылка на загрузку.

    Важно: сейчас принято использовать msys2 вместо Cygwin. К сожалению, сборка JDK тут же упадет с ошибкой:

    configure: error: /usr/bin/bash /x/git/openjdk9/common/autoconf/build-aux/config.sub x86_64-pc-msys failed

    Если попытаться прописать msys так же, как там прописан Cygwin, то ошибка меняется:

    unsupported operating system msys

    Если какой-нибудь герой в комменатриях расскажет, как правильно прописать msys, это было бы здорово.

  4. Устанавливаем пакеты для Cygwin

    , описанные в Build Readme.

    В скобках указана категория пакета, после знака "—" ради чего мы это ставим.
    Назначение каждого экзешника можно почитать в мане, но чтобы собрать этого знать не нужно.

    • binutils (devel) – ar.exe
    • make (devel) — make.exe
    • m4 (interpreters) — m4.exe
    • cpio (utils) — cpio.exe
    • gawk (base, interpreters) — gawk.exe
    • file (base) — file.exe
    • zip (archive) — zip.exe
    • unzip (archive) — unzip.exe
    • procps-ng (system) — free.exe


    Для возмущенных таким большим набором зависимостей — скажите спасибо, что не заставили устанавливать Python и Ruby! :)

    Для тех, кто ни разу не сталкивался с Cygwin пара замечаний:
    • Установка пакетов выглядит как-то так:

    • Существует множество пакетов, например, со словом binutils в названии.
      Нужно выбирать пакет, в точности по буквам совпадающий с названием из списка, соответствующий группе из списка. (Конечно, если вы точно знаете что делаете, ваша воля :) )
    • Принадлежность пакетов к группам в Cygwin время от времени меняется. В частности, группы, перечисленные в этом списке уже не совпадают с группами из Build Readme. Если группы из списка не существует – выберите подходящую (и напишите мне личное сообщение, чтобы я обновил эту инструкцию).
    • При установке, вас попросят указать установочные директории. Постарайтесь установить в путь с как можно более коротким имененем, например: C:/cygwin и C:/cygpack. Или вообще c:/cw и c:/cp. Это поможет избежать ошибок с излишне длинными именами файлов, которые не может обработать проводник Windows (NTFS уже иногда может их обрабатывать, а Проводник – еще нет).
    • После изначальной установки, в самом Cygwin нет никакого гуя для управления пакетами. Чтобы установить дополнительные пакеты, нужно заново запустить setup.exe. Эта программа не будет устанавливать Cygwin с нуля, а только докачает нужное. Между перезапусками путь до директорий сохраняется.
    • Выбор зеркала влияет на скорость, но нам нужно скачать очень мало пакетов, поэтому что выбирать — в среднем всё равно. Выбирайте самое первое зеркало в списке.
    • Гуй для установки пакетов немного странный, но вы разберетесь :)
      • Как только вы вписали в поле поиска имя пакета, соответствующий список перерисовывается автоматически – enter жать не нужно.
      • Чтобы установить пакет, нужно много раз прокликать кнопку со статусом (стрелочки замкнутые в уробороса с надписью skip или какой-то еще), чтобы надпись статуса поменялась на версию пакета, которая будет устанавливаться
      • Иногда инсталлятору становится разными способами плохо. Don’t panic. Если установка повисла посередине, то самый простой способ всё вернуть назад — удалить C:/Cygwin, или куда вы там его устанавливаете. Лучше не надеяться, что проверяльщик чексумм битых недокачанных пакетов сможет найти поломку, устраните её полным удалением самостоятельно.


  5. Качать make отдельно не нужно


    В прошлых инструкциях часто предполагалось скачать и прописать свой make. По новейшим наблюдениям, делать этого не имеет смысла, того make что установился пакетом в Cygwin — вполне достаточно.

    Более того, на официальном сайте лежит устаревшая версия make, поэтому с ней вы получите ошибку типа:

    The specified make (by MAKE=/cygdrive/c/Program Files (x86)/GnuWin32/bin/make.exe) is not GNU make 4.0 or newer.

    То есть, make вам придется или собирать вручную, или искать уже собранный на сомнительных файлопомойках, как когда-то мы подбирали на них rpm’ки.

    Если собственный make вам действительно нужен, то чтобы его использовать, нужно прописать в configure параметр MAKE=/путь/до/make.exe. Да, другие параметры начинаются на --, например --with-freetype, а вот MAKE должен быть именно в таком виде.

  6. DirectX SDK устанавливать не нужно


    Если оно вам действительно нужно (Java 3D?), вы об этом знаете, и знаете что делать. Здесь инструкций не будет.

  7. Собираем FreeType


    Собирать FreeType обязательно, даже если очень не хочется и лично вам не нужно.

    1. Ссылка на загрузку.

      Там две группы загрузок: две вверху (Complete package и Sources), и шесть пониже (Binaries… Original source). Элемент Sources есть в обеих группах. Нам нужно скачать зипник элемента Sources из второй группы.

      Замечание: Качает сто лет, что делать? Ничего не поделаешь, это Сорсфордж. В момент отображения таймера загрузки попробуйте успеть щелкнуть по ссылке try another mirror и выберите что-нибудь во Франции. Французы не жмотятся на скорость.

    2. Создаем директорию src/freetype/2.3.5/freetype-2.3.5/lib

    3. Внутри директории src/freetype/2.3.5/freetype-2.3.5/builds/win32/visual лежит солюшен для Студии.

    4. Открываем. Если у вас несколько Студий, то от греха подальше лучше открыть в 2013. Сборку с 2015 пробовал, она тоже работает.

    5. При открытии солюшена Студия попросит one-way upgrade. Соглашаемся (если отображается несколько элементов в списке – соглашаемся для всех).

    6. После этого Студия может намертво повиснуть, перестав заодним отображаться и в Диспетчере. Задач Windows. Тут на помощь приходит Sysinternals Process Explorer:
      technet.microsoft.com/ru-ru/sysinternals/processexplorer.aspx

      Нужно найти в дереве devenv.exe, и вначале убить всех его потомков. После этого можно убить и сам devenv.exe (до этого он просто не реагирует на команду умереть).

    7. Идем в Configuration Manager, в выпадашке Platform выбираем New, New platform: x64, Copy settings from: Win32, OK, Close.







    8. Там же, выбираем тип сборки – Release Multithreaded (по умолчанию стоит Debug)



    9. В Solution Explorer, правой кнопкой на проект freetype, properties.



    10. Указываем Output Directory: src/freetype/2.3.5/freetype-2.3.5/lib (директория указана относительно корня скачанного FreeType). Проверяем, что configuration type выставлен в Static library (.lib).



    11. Закрываем окно freetype Property Pages. Собираем проект через Build > Build solution.



    12. Теперь нужно поменять сборку с lib на dll.

      Повторяем действия:

      В Solution Explorer, правой кнопкой на проект freetype, properties. Указываем Output Directory: src/freetype/2.3.5/freetype-2.3.5/lib. Проверяем, что configuration type выставлен в Dynamic library (.dll)

      Закрываем окно freetype Property Pages. Собираем проект через Build > Build solution.

    13. Открываем директорию src/freetype/2.3.5/freetype-2.3.5/lib в Проводнике и проверяем состав файлов: freetype.dll, freetype.lib, freetype.exp.

      Ключевой факт тут такой: теперь у нас в одной корневой директории (src/freetype/2.3.5/freetype-2.3.5) лежат и инклуды (src/freetype/2.3.5/freetype-2.3.5/include), и библиотеки (src/freetype/2.3.5/freetype-2.3.5/lib).

    14. Готово! Теперь у нас есть жалкие 600 килобайт, ради которых мы мучались последние десять минут.
  8. Заливаем исходники JDK из репозитория


    1. Загружаем и устанавливаем Mercurial (TortoiseHg): tortoisehg.bitbucket.org/download/index.html

    2. Загружаем расширение trees для Mercurial

      Файл:

      gist.githubusercontent.com/olegchir/8267049ed48f7975aa8ef7d7c1515349/raw/fbe90ac1c639f6c209bc7cebbdcc7ebbd848c734/trees.py

      Запоминаем, куда скачали (например: C:/opt/trees.py)

      Важно! Согласно инструкциям отсюда:

      openjdk.java.net/projects/code-tools/trees

      Мы должны были бы загружать вот этот файл:

      hg.openjdk.java.net/code-tools/trees/raw-file/tip/trees.py

      К сожалению, на момент написания статьи, интеграция этого экстеншена с новой версией Mercurial сломана. Есть следующий баг, с приложенным патчем:

      bugs.openjdk.java.net/browse/CODETOOLS-7901672

      Чтобы вам не патчить trees самостоятельно, я пропатчил его, и выложил здесь:

      gist.githubusercontent.com/olegchir/8267049ed48f7975aa8ef7d7c1515349/raw/fbe90ac1c639f6c209bc7cebbdcc7ebbd848c734/trees.py

      В будущем, когда этот тикет будет закрыт, стоит использовать основную версию. Если вы читаете эту инструкцию, когда тикет уже закрыт – напишите мне, я исправлю этот пункт.

    3. Создаем файл .hgrc в домашнем каталоге пользователя (%USERPROFILE%\.hgrc).

      Так как Windows плохо относится к созданию файлов, начинающихся на точку, проще всего открыть консоль Cygwin и выполнить команду:

      touch /cygdrive/c/Users/olegchir/.hgrc

      Внутри файла пишем:

      [extensions]
      purge =
      trees = C:\opt\trees.py
      

      Слеши в пути до py-файла – обратные.

    4. Открываем консоль (cmd.exe), переходим в директорию, где хотим хранить исходники (cd C:\git)

    5. Клонируем репозиторий:

      hg tclone http://hg.openjdk.java.net/jdk9/dev 9dev

      Это займет весьма много времени.



      Важно! В будущем ссылка может измениться. Смотреть новую ссылку можно здесь: openjdk.java.net/guide/repositories.html

      Важно! Постарайтесь установить в путь с как можно более коротким имененем, например: C:/hg. Это поможет избежать ошибок с излишне длинными именами файлов, которые не может обработать проводник Windows (NTFS уже иногда может их обрабатывать, а Проводник – еще нет). Поможет не попасть в глупую ситуацию, когда репозиторий вы уже склонировали, а удалить его — еще не можете.

      Неприятненько. При возникновении ошибки «abort: stream ended unexpectedly». Вначале попробуйте перезапустить hg tclone еще несколько раз. Если ошибка продолжает повторятся, то вам предстоит муторная ручная работа. Запомните, какой проект не выгружался до конца (например, langtools). Перезапустите всё с таким аргументом:

      hg tclone -r 100 http://hg.openjdk.java.net/jdk9/dev 9dev

      Это загрузит только 100 ченжсетов и даст возможность операции tclone завершиться.
      Сразу после этого перейдите в директорию проекта, который не докачался (например, langtools), и выполните hg tpull -u 1000.

      И дальше добавляйте по 1000 ченжсетов:

      hg tpull -u 1000
      hg tpull -u 2000
      hg tpull -u 3000

      Когда ревизии закончатся – нужно перейти в корень (9dev), и выполнить там команду “hg tpull -u” (без указания количества ревизий).

      Если после этого упадёт тот же проект – перейдите в него назад, и с более маленьким шагом докачайте оставшиеся ревизии совсем точно до конца, вернитесь в корень и повторите hg tpull -u без аргументов.

      Если после этого упадёт другой проект – переходим в его директорию, и повторяем пока всё не склонируется до конца.


  9. Собираем JDK


    1. Открываем консоль Cygwin (НЕ cmd.exe), переходим в директорию со склонированными исходниками.
    2. Выполняем команду:

      ./configure --enable-debug --with-target-bits=64 --with-boot-jdk=/cygdrive/c/opt/Java/jdk1.8.0_111 --with-freetype=/cygdrive/c/my/opt/java/freetype-2.3.5-1-src/src/freetype/2.3.5/freetype-2.3.5

      пути до файлов должны совпадать с теми, что мы получили в ходе выполнения инструкции:
      --with-boot-jdk указывает на директорию, куда вы загрузили JDK8
      --with-freetype указывает на директорию внутри исходников freetype, где есть поддиректории include и lib, и в lib вы собрали .dll и .lib с 64-битным фритайпом

      пути до файлов обязаны быть не родными, а начинаться с /cygdrive.
    3. Долго ждем, пока сконфигурится. Ошибок быть не должно.

      Единственная ожидаемая ошибка — при использовании Visual Studio Express:

      Cannot locate a valid Visual Studio or Windows SDK installation on disk

      Обычно её можно исправить небольшим грязным хаком. Заходим в директорию установки MSVS (обычно это C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC).

      Видим что там нет диерктории amd64, зато есть x86_amd64.
      Копируем её с новым названием: amd64.

      Заходим внутрь amd64, и копируем файл vcvarsx86_amd64.bat с новым именем: vcvars64.bat
      Перезапускаем configure с новым параметром: --with-tools-dir:

      ./configure --enable-debug --with-target-bits=64 --with-boot-jdk=/cygdrive/c/opt/Java/jdk1.8.0_111 --with-freetype=/cygdrive/c/my/opt/java/freetype-2.3.5-1-src/src/freetype/2.3.5/freetype-2.3.5 --with-tools-dir="/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 12.0/VC/bin/amd64"

    4. В результате выполнения configure видим такой текст:



      Configuration summary:
      * Debug level: fastdebug
      * HS debug level: fastdebug
      * JDK variant: normal
      * JVM variants: server
      * OpenJDK target: OS: windows, CPU architecture: x86, address length: 64
      * Version string: 9-internal+0-adhoc.olegchir.openjdk9 (9-internal)

      Tools summary:
      * Environment: cygwin version 2.6.1(0.305/5/3) (root at /cygdrive/c/cygwin)
      * Boot JDK: java version «1.8.0_111» Java(TM) SE Runtime Environment (build 1.8.0_111-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode) (at /cygdrive/c/opt/Java/jdk1.8.0_111)
      * Toolchain: microsoft (Microsoft Visual Studio 2013)
      * C Compiler: Version 18.00.40629 (at /cygdrive/c/progra~2/micros~2.0/vc/bin/amd64/cl)
      * C++ Compiler: Version 18.00.40629 (at /cygdrive/c/progra~2/micros~2.0/vc/bin/amd64/cl)

      Build performance summary:
      * Cores to use: 8
      * Memory limit: 20447 MB
    5. Выполняем команду: make
    6. Долго ждем, пока соберется. В этот момент у компьютера тратится очень много ресурсов – стоит переключиться на использование другого компьютера, или сходить попить чаю.
  10. Проверяем запуск


    Внутри диретктории с исходниками должна появиться директория builds/windows-x86_64-normal-server-fastdebug

    С помощью консоли (cmd.exe) заходим в каталог типа:
    X:\git\openjdk9\build\windows-x86_64-normal-server-fastdebug\jdk\bin

    И выполняем команду: java -version

    Должна быть распечатана версия 9-internal.



  11. Troubleshooting


    In open source no one can hear your scream

    image

  12. PROFIT

Поделиться с друзьями
-->

Комментарии (20)


  1. pmcode
    07.01.2017 17:47
    -6

    Мой опыт сборки под Windows резко закончился на необходимости скачивать 6 гигов компилятора для сборки Atom. Спасибо, после вашей статьи теперь это окончательное табу :) Все-таки задница именно то место, которым данная ОС повернута к айтишникам.
    А зачем компилять самому? Есть же снапшоты. Или они совсем древние?


    1. olegchir
      07.01.2017 19:00
      +5

      Чтобы ковыряться в JDK, собирать с изменениями, и таким образом проверять предположения.


    1. OnYourLips
      07.01.2017 22:08
      +2

      ОС не при чем, дело в отсутствии средств управления зависимостями для С и C++.
      В языках, где они есть, проблемы нет (кроме сборки нативных пакетов для ruby, nodejs и т.д., но тут проблема снова в C и C++).

      Если вы под Linux будете собирать зависимости сами, а не использовать dev-пакеты, которые вам собрали ментейнеры дистрибутивов, то будете страдать абсолютно так же. Попробуйте собрать свежую версию чего либо под старым дистрибутивом (dev-пакеты будет устаревшими и не подойдут) — удивитесь.


    1. maniacscientist
      08.01.2017 04:12
      -3

      Все знают что винда — это пускалка игрушек


  1. maaGames
    07.01.2017 18:03
    +2

    > Если кто-то в комментариях знает, как безболезненно починить эту ошибку и запуститься на 2015
    Этот косяк часто бывает, когда проект апгрейдится со старый версий. Нужно в путях проекта добавить пути до библиотек компилятора. И до хедеров и исходников и исполняемых файлов. Там вообще всё очень странно и запутано: с одними и теми же параметрами у меня компилировался debug и не компилировался release, пока не подобрал правильные пути (в моём случае на вин7 пришлось указывать пути до sdk 8.1). В общем, если поколдовать, то нужная библиотека найдётся.


  1. jerry_kiwi
    07.01.2017 18:58
    +2

    Осталось понять, зачем весь вышеописанный производственный подвиг вообще нужен:)


    1. olegchir
      07.01.2017 19:01
      +2

      Ну например для того, чтобы без перезагрузки ноутбука иметь возможность альт-табнуться в Overwatch и сыграть партию-другую :)


      1. jerry_kiwi
        07.01.2017 19:26
        +5

        ну т.е. по сути высококачественный высокопрофессиональный онанизм.


      1. maniacscientist
        11.01.2017 20:07
        +1

        KVM? Qemu с пробросом? Не заносить деньгу однополым любовникам, чьи менеджеры сказали что версия для линукса не нужна?


  1. Siemargl
    07.01.2017 19:35
    +7

    Сложность использования неудивительна. Ведь системе сборки Autoconf больше 25 лет и она обросла не просто мхом, а уже и такой плесенью, в которой свой разум завелся.

    Вот при портировании однажды я удивился файлу configure всего то из 23100 строк.


  1. PastorGL
    07.01.2017 19:46
    +3

    Cygwin? Да ну его в пень :(

    Интереснее было бы попробовать скрестить ужа с ежом, и собрать на десятке из WSL окружения. Вот это было бы колдунство. По крайней мере, чисто теоретически в последних insider preview такое должно быть возможно, там добавили возможность вызова Win32 бинарей из Linux usermode (и виндовый PATH в нём тоже доступен).


  1. ZaMaZaN4iK
    07.01.2017 20:19
    +4

    Что люди только не вытворяют, лишь бы GNU\Linux не пользоваться :)


    1. olegchir
      07.01.2017 20:32
      +3

      Ждал этого комментария. :).


    1. rPman
      07.01.2017 21:15

      вы можете дать инструкцию по кросскомпиляции jdk из linux под win32?
      а то java эта именно та вещь которая нужна не только под linux :)


      1. olegchir
        07.01.2017 21:30
        +1

        не могу, нет надобности, у меня все целевые ОС на реальном железе

        а вообще, вам зачем? Кросскомпилированное особо не поотлаживаешь, для релизной модифицированной сборки как явления редкого вполне можно поставить винду в виртуалку, для релизной ванильной сборки — уже есть готовые сборки (https://jdk9.java.net/download/)


  1. varanio
    07.01.2017 20:41
    -2

    А зачем самому собирать из исходников?


  1. vlanko
    07.01.2017 21:15

    А сколько примерно времени компилится на 8 ядрах?


    1. olegchir
      07.01.2017 21:41
      +1

      12 минут — полная пересборка на ноутбучном i7-4710HQ 2.5GHz и Samsung SSD 750 EVO (заполнение на 2/3)


  1. Massacre
    07.01.2017 22:38
    -1

    Лучше б под mingw сделали. Это естественней.


  1. SamVimes
    08.01.2017 09:44
    +1

    Собирал недавно Project Valhalla (по сути JDK9 + несколько JEP'ов), никаких профитов не заметил, в основном всё на стадии work in progress (а так хотелось ValueType попробовать). Собирал, кстати, на стареньком Sony Vaio (правда с дебианом, а не виндой), всего за полчаса собралось.