======= Compilando a versão 3.1_rc3 =======
O [[http://wz2100.net|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 {{arquivo:meuend.png?130x0}}
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 >::swap(std::list >&)':/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 >::_M_insert(std::_List_iterator, 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 >::_M_transfer(std::_List_iterator, std::_List_iterator, std::_List_iterator)':/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 >::_M_insert(std::_List_iterator, 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 >::_M_erase(std::_List_iterator)':/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 >::_M_insert(std::_List_iterator, 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 >::_M_insert(std::_List_iterator, 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 >::_M_erase(std::_List_iterator)':/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 >::_M_erase(std::_List_iterator)':/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 >::_M_insert(std::_List_iterator, 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 >::_M_insert(std::_List_iterator, 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 >::_M_erase(std::_List_iterator)':/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 >::_M_insert(std::_List_iterator, 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 >::_M_erase(std::_List_iterator)':/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***Stop in /dados/download/warzone2100-3.1_rc3-ok_sem_rede/src.***Stop in /dados/download/warzone2100-3.1_rc3-ok_sem_rede/src.***Stop in /dados/download/warzone2100-3.1_rc3-ok_sem_rede.***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**.