Compilando o Warzone2100 no FreeBSD

De Cartola

Tabela de conteúdo

Compilando a versão 3.1_rc3

O warzone2100 já está portado para o FreeBSD há algum tempo, mas em geral o pessoal demora um pouco para atualizar a versão. Resolvi então compilar a versão 3.1_rc3 do jogo e depois de alguns percalços resolvi compartilhar aqui o que fiz, pois não é tarefa muito óbvia. Em caso de dúvidas, críticas e sugestões entre em contato comigo pelo email

O FreeBSD onde esta compilação foi feita foi um 9.1-RC1.

Pré-requisitos

Usei o gcc versão 4.6 e 4.8 com sucesso e creio que o 4.2 não é compatível com a compilação. Não sei a partir de que versão de gcc já é possível compilar, mas fica aí essa dica.

A instalação de cada versão de gcc extra fica independente da outra. Fiquei no final com o original que veio com o sistema (4.2) e com os outros dois que acabei instalando (4.6 e 4.8). Ao compilar um programa você pode usar variáveis ambiente para escolher o que quer.

 setenv CC gcc46
 setenv CXX gcc46++

É necessário instalar o shell bash também. Pode fazê-lo via pacotes ou ports, como preferir, desde que esteja instalado.

Demais pré-requisitos podem ser necessários e você vai perceber a necessidade deles na configuração da compilação. Instale a medida que for vendo as mensagens de que tais programas não foram encontrados.

Acertando o ambiente

É necessário definir outras variáveis ambiente que vão fazer o configurador encontrar as dependências instaladas:

 setenv LDFLAGS "-L/usr/lib -L/usr/local/lib"

Crie um arquivo vazio, senão a compilação irá parar com um erro

 touch lib/framework/wzconfig_moc.cpp

Acerte o caminho do bash no script que será executado. No script build_tools/autorevision.sh a primeira linha que vem é

 #!/bin/bash

Edite o arquivo e converta-a para

 #!/usr/local/bin/bash

pois este é o caminho onde o bash é instalado no FreeBSD.

Acerte o programa que propiciará a conexão de rede para jogos online. Edite o arquivo lib/netplay/netsocket.cpp e, a partir da linha 1402, remova 3 linhas. As 3 linhas a serem removidas são mostradas abaixo:

 #ifdef AI_V4MAPPED
       flags             |= AI_V4MAPPED;
 #endif


Configurando

Com tudo isso feito inicie o processo:

 ./configure

Possivelmente você obterá erros de bibliotecas ou dependências não encontradas. Providencie a instalação delas a medida que isso ocorrer e repita o comando acima até que tenha sucesso.

Por fim o configurador criará as configurações necessárias, mesmo finalizando com uma mensagem de aviso sobre a distribuição. Pelo que entendi é uma mensagem destinada à compilação em ambientes Windows, então pode ignorar.

Compilando

Seguindo o processo inicie a compilação:

 make

Ainda não consegui fazer a compilação ter sucesso até o fim. Lá no final, na última etapa para linkar os objetos ocorrerá um erro fatal. Não tema! Pra tudo na vida tem uma solução.

O erro fatal por conta dos gcc's instalados

O problema de usar mais de uma versão de gcc é que a biblioteca lstdc++ encontrada por padrão mesmo pelas novas versões instaladas é a original. A única maneira que encontrei, por enquanto, para resolver isso é executar manualmente a última etapa de compilação colocando parâmetros nos locais corretos para que a lstdc++ encontrada seja a correspondente ao compilador usado. O erro indica que o compilador não encontrou algumas referências a objetos:

 

astar.o: In function `std::list<PathBlockingMap, std::allocator<PathBlockingMap> >::swap(std::list<PathBlockingMap, std::allocator<PathBlockingMap> >&)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1213: undefined reference to `std::__detail::_List_node_base::swap(std::__detail::_List_node_base&, std::__detail::_List_node_base&)'

astar.o: In function `std::list<PathfindContext, std::allocator<PathfindContext> >::_M_insert(std::_List_iterator<PathfindContext>, PathfindContext const&)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1551: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'

astar.o: In function `std::list<PathfindContext, std::allocator<PathfindContext> >::_M_transfer(std::_List_iterator<PathfindContext>, std::_List_iterator<PathfindContext>, std::_List_iterator<PathfindContext>)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1543: undefined reference to `std::__detail::_List_node_base::_M_transfer(std::__detail::_List_node_base*, std::__detail::_List_node_base*)'

astar.o: In function `std::list<PathBlockingMap, std::allocator<PathBlockingMap> >::_M_insert(std::_List_iterator<PathBlockingMap>, PathBlockingMap const&)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1551: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'

design.o: In function `std::list<DROID_TEMPLATE, std::allocator<DROID_TEMPLATE> >::_M_erase(std::_List_iterator<DROID_TEMPLATE>)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1567: undefined reference to `std::__detail::_List_node_base::_M_unhook()'

design.o: In function `std::list<DROID_TEMPLATE, std::allocator<DROID_TEMPLATE> >::_M_insert(std::_List_iterator<DROID_TEMPLATE>, DROID_TEMPLATE const&)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1551: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'

fpath.o: In function `std::list<PATHRESULT, std::allocator<PATHRESULT> >::_M_insert(std::_List_iterator<PATHRESULT>, PATHRESULT const&)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1551: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'

fpath.o: In function `std::list<PATHJOB, std::allocator<PATHJOB> >::_M_erase(std::_List_iterator<PATHJOB>)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1567: undefined reference to `std::__detail::_List_node_base::_M_unhook()'

fpath.o: In function `std::list<PATHRESULT, std::allocator<PATHRESULT> >::_M_erase(std::_List_iterator<PATHRESULT>)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1567: undefined reference to `std::__detail::_List_node_base::_M_unhook()'

fpath.o: In function `std::list<PATHJOB, std::allocator<PATHJOB> >::_M_insert(std::_List_iterator<PATHJOB>, PATHJOB const&)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1551: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'

scriptvals.o: In function `std::list<INTERP_VAL*, std::allocator<INTERP_VAL*> >::_M_insert(std::_List_iterator<INTERP_VAL*>, INTERP_VAL* const&)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1551: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'

scriptvals.o: In function `std::list<INTERP_VAL*, std::allocator<INTERP_VAL*> >::_M_erase(std::_List_iterator<INTERP_VAL*>)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1567: undefined reference to `std::__detail::_List_node_base::_M_unhook()' ../lib/netplay/libnetplay.a(netqueue.o): In function `std::list<NetMessage, std::allocator<NetMessage> >::_M_insert(std::_List_iterator<NetMessage>, NetMessage const&)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1551: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)' ../lib/netplay/libnetplay.a(netqueue.o): In function `std::list<NetMessage, std::allocator<NetMessage> >::_M_erase(std::_List_iterator<NetMessage>)': /usr/local/lib/gcc48/include/c++/bits/stl_list.h:1567: undefined reference to `std::__detail::_List_node_base::_M_unhook()'

collect2: error: ld returned 1 exit status

*** [warzone2100] Error code 1

Stop in /dados/download/warzone2100-3.1_rc3-ok_sem_rede/src.

*** [all] Error code 1

Stop in /dados/download/warzone2100-3.1_rc3-ok_sem_rede/src.

*** [all-recursive] Error code 1

Stop in /dados/download/warzone2100-3.1_rc3-ok_sem_rede.

*** [all] Error code 1

Stop in /dados/download/warzone2100-3.1_rc3-ok_sem_rede.

Pouco antes do erro de compilação apresentado podemos ver uma linha gigante com o comando utilizado. É necessário copiá-la e colocá-la num arquivo para editarmos. A linha que obtive foi essa:

 g++48 -g -Wno-enum-compare -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wcast-align -Wwrite-strings \
 -Wpointer-arith -Wno-format-security -I/usr/local/include/qt4/QtNetwork -I/usr/local/include/qt4/QtScript -DQT_SHARED \
 -I/usr/local/include/qt4 -I/usr/local/include/qt4/QtCore -fstack-protector  -lz -rdynamic \
 -L/usr/lib -L/usr/local/lib -o warzone2100 action.o advvis.o  ai.o astar.o atmos.o aud.o  baseobject.o bridge.o bucket3d.o \
 challenge.o cheat.o clparse.o  cluster.o cmddroid.o combat.o  component.o configuration.o console.o  data.o design.o \
 difficulty.o  display3d.o display.o drive.o  droid.o e3demo.o edit3d.o  effects.o feature.o fpath.o  frontend.o function.o \
 game.o  gateway.o geometry.o group.o  hci.o ingameop.o init.o  intdisplay.o intelmap.o intimage.o  intorder.o keybind.o \
 keyedit.o  keymap.o level_lexer.o levels.o  lighting.o loadsave.o loop.o  main.o map.o mapdisplay.o  mapgrid.o mechanics.o \
 message.o  miscimd.o mission.o move.o  multibot.o multigifts.o multiint.o  multijoin.o multilimit.o multimenu.o  multiopt.o \
 multiplay.o multistat.o  multistruct.o multisync.o objects.o  objmem.o oprint.o order.o  pointtree.o power.o projectile.o \
 qtscript.o qtscriptfuncs.o radar.o  random.o raycast.o research.o  scores.o scriptai.o scriptcb.o  scriptextern.o scriptfuncs.o \
 scriptobj.o scripttabs.o scriptvals.o  scriptvals_lexer.o scriptvals_parser.o  selection.o seqdisp.o stats.o  structure.o \
 template.o terrain.o  text.o texture.o transporter.o  version.o visibility.o warcam.o  warzoneconfig.o wavecast.o wrappers.o \
 ../lib/widget/libwidget.a  ../lib/sequence/libsequence.a  ../lib/sound/libsound.a  ../lib/script/libscript.a  ../lib/netplay \
 /libnetplay.a  ../lib/ivis_opengl/libivis_opengl.a  ../lib/gamelib/libgamelib.a  ../lib/framework/libframework.a  ../lib \
 /exceptionhandler/libexceptionhandler.a  ../3rdparty/miniupnpc/libminiupnpc.a  ../3rdparty/quesoglc/libquesoglc.a   ../lib \
 /sdl/libsdl.a -L/usr/local/lib -lintl -L/usr/local/lib -liconv -R/usr/local/lib -L/usr/local/lib -Wl,-rpath,/usr/local/lib -lSDL \
 -pthread  -lphysfs -L/usr/local/lib -lpng15 -lvorbisfile -lvorbis -lm -L/usr/local/lib -logg -lvorbis -lm -L/usr/local/lib \
 -logg  -ltheora -L/usr/local/lib -logg -L/usr/local/lib -lopenal -L/usr/local/lib -lfribidi  -L/usr/local/lib -lfreetype  \
 -L/usr/local/lib -lfontconfig  -lpthread -lGL -lGLU -lGLEW -lGL -lGLU  -lQtNetwork -lQtScript -L/usr/local/lib/qt4 -lQtCore \
 -lGLEW -lX11 -lXrandr  -lz -rdynamic -L/usr/lib -L/usr/local/lib -L/usr/local/lib/gcc48 -lstdc++

A linha originalmente é uma só, sem as contra-barras que coloquei ali. É que achei melhor partir a linha aqui por questões de legibilidade. A solução que encontrei foi copiar a linha para um arquivo texto, por exemplo, tmp.txt, e editá-lo, inserindo o seguinte trecho nele:

 -L/usr/local/lib/gcc48 -lstdc++

acho que esse trecho deve ser inserido antes de qualquer outro parâmetro "-L", então minha linha ficou como abaixo:

 g++48 -g -Wno-enum-compare -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wcast-align -Wwrite-strings \
 -Wpointer-arith -Wno-format-security -I/usr/local/include/qt4/QtNetwork -I/usr/local/include/qt4/QtScript -DQT_SHARED \
 -I/usr/local/include/qt4 -I/usr/local/include/qt4/QtCore -fstack-protector  -lz -rdynamic -L/usr/local/lib/gcc48 -lstdc++ \
 -L/usr/lib -L/usr/local/lib -o warzone2100 action.o advvis.o  ai.o astar.o atmos.o aud.o  baseobject.o bridge.o bucket3d.o \
 challenge.o cheat.o clparse.o  cluster.o cmddroid.o combat.o  component.o configuration.o console.o  data.o design.o \
 difficulty.o  display3d.o display.o drive.o  droid.o e3demo.o edit3d.o  effects.o feature.o fpath.o  frontend.o function.o \
 game.o  gateway.o geometry.o group.o  hci.o ingameop.o init.o  intdisplay.o intelmap.o intimage.o  intorder.o keybind.o \
 keyedit.o  keymap.o level_lexer.o levels.o  lighting.o loadsave.o loop.o  main.o map.o mapdisplay.o  mapgrid.o mechanics.o \
 message.o  miscimd.o mission.o move.o  multibot.o multigifts.o multiint.o  multijoin.o multilimit.o multimenu.o  multiopt.o \
 multiplay.o multistat.o  multistruct.o multisync.o objects.o  objmem.o oprint.o order.o  pointtree.o power.o projectile.o \
 qtscript.o qtscriptfuncs.o radar.o  random.o raycast.o research.o  scores.o scriptai.o scriptcb.o  scriptextern.o scriptfuncs.o \
 scriptobj.o scripttabs.o scriptvals.o  scriptvals_lexer.o scriptvals_parser.o  selection.o seqdisp.o stats.o  structure.o \
 template.o terrain.o  text.o texture.o transporter.o  version.o visibility.o warcam.o  warzoneconfig.o wavecast.o wrappers.o \
 ../lib/widget/libwidget.a  ../lib/sequence/libsequence.a  ../lib/sound/libsound.a  ../lib/script/libscript.a  ../lib/netplay \
 /libnetplay.a  ../lib/ivis_opengl/libivis_opengl.a  ../lib/gamelib/libgamelib.a  ../lib/framework/libframework.a  ../lib \
 /exceptionhandler/libexceptionhandler.a  ../3rdparty/miniupnpc/libminiupnpc.a  ../3rdparty/quesoglc/libquesoglc.a   ../lib \
 /sdl/libsdl.a -L/usr/local/lib -lintl -L/usr/local/lib -liconv -R/usr/local/lib -L/usr/local/lib -Wl,-rpath,/usr/local/lib -lSDL \
 -pthread  -lphysfs -L/usr/local/lib -lpng15 -lvorbisfile -lvorbis -lm -L/usr/local/lib -logg -lvorbis -lm -L/usr/local/lib \
 -logg  -ltheora -L/usr/local/lib -logg -L/usr/local/lib -lopenal -L/usr/local/lib -lfribidi  -L/usr/local/lib -lfreetype  \
 -L/usr/local/lib -lfontconfig  -lpthread -lGL -lGLU -lGLEW -lGL -lGLU  -lQtNetwork -lQtScript -L/usr/local/lib/qt4 -lQtCore \
 -lGLEW -lX11 -lXrandr  -lz -rdynamic -L/usr/lib -L/usr/local/lib -L/usr/local/lib/gcc48 -lstdc++

Esse arquivo deve ser colocado no sub diretório "src". Você então vai até ele, já com o arquivo lá:

 cd src

E executa a compilação:

 sh tmp.txt

O jogo será compilado até o fim e o arquivo binário executável chamado warzone2100 deve aparecer nessa pasta. Já é possível testar se tudo deu certo chamando ele:

 ./warzone2100

Instalando

Você pode depois instalar essa versão no sistema. Eu pessoalmente preferi não instalar, já que é possível rodá-la de onde foi compilada. Assim mantenho o sistema "limpo" aguardando pelo port oficial.

Para instalar é necessário estar na raiz da compilação. Se você estava no diretório "src" volte um nível acima:

 cd ..

Em seguida faça a instalação:

 make install

mas lembre-se que para instalar é preciso ser root.

Ferramentas pessoais
Anúncio