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.
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.
É 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
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.
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 problema de usar mais de uma versão de gcc é que a biblioteca lstdcencontrada 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: /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<nowiki>***</nowiki>Stop in /dados/download/warzone2100-3.1_rc3-ok_sem_rede/src.<nowiki>***</nowiki>Stop in /dados/download/warzone2100-3.1_rc3-ok_sem_rede/src.<nowiki>***</nowiki>Stop in /dados/download/warzone2100-3.1_rc3-ok_sem_rede.<nowiki>***</nowiki>Stop in /dados/download/warzone2100-3.1_rc3-ok_sem_rede.
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.