Portál AbcLinuxu, 30. dubna 2025 12:44
Tento blog byl smazán autorem
Tiskni
Sdílej:
ccmake
nebo cmake-gui
a nastav si to tam.
Ale o tom linuxáci nepřemýšlej, protože ti mají bash i python v každé distribuci ve výchozím stavu nainstalovaný a je jim ukradené, že některý systém (obzvláště ten od MS) to tak nemá.Proč by Linuxáci měli vůbec řešit nějaké problémy Windows?
> Ale o tom linuxáci nepřemýšlej, protože ti mají bash i python v každé distribuci ve výchozím stavu nainstalovaný cygwin i msys mají bash i python taky ve výchozím stavu nainstalovaný.
Abych řekl pravdu, cmake beru jako magii. Absolutně se v něm nevyznám. Když něco potřebuji, tak si musím najít, jak se to dělá jinde a pak to s mírnými úpravami použít.
No, já přímo v C/C++ naštěstí dělat nemusím, takže mě to nemusí vůbec trápit. Ale! Instaloval jsem nějakej program přes MacPorty a ten hajzl vývojář používá cmake. Takže kvůli jedný blbině jsem musel stáhnout a zkompilovat cmake a jeho závislosti.
A jak tak čtu tu ukázku, jsem nesmírně vděčný za Apache Ant.
Já je nepoužívám právě proto, že vyžadují nastavení editoru. Zkus pročítat nějaký složitější kód na klasickém terminálu 80 na 24. Ano, můžeš namítnout, že si mám zvětšit xterm
, ale bohužel já UNIX mám, ale ostatní mají PuTTY. A jen proto, že potřebuji rychle něco najít nebo opravit, nebudu jim přenastavovat úplně všechno (včetně připadných dalších programů). Takhle mám zdrojáče připravené pro všechna prostředí. Tak proto.
No 80x24 je des, ale používanie tabov môže byť práve na takýchto hrúzach lepšie. Ak si nastavím šírku tabu povedzme 2 znaky zmestí sa mi na terminál viac, ako keď mi niekto vnucuje odsadenie 4 medzerami.
Len pre zaujímavosť rovnako ako xterm sa dá zväčšiť okno PuTTY.
Nastavenie zobrazovania whitespace je väčšinou veľmi triviálna (napr. vo vim-e je to 1 krátky príkaz).
V prílohe je môj terminál s úbohým rozlíšením 80x24, na screenshote vidno taby a prebytočné medzery (1 príkaz na nastavenie oboch súčasne ;) ).
No 80x24 je des, ale používanie tabov môže byť práve na takýchto hrúzach lepšie. Ak si nastavím šírku tabu povedzme 2 znaky zmestí sa mi na terminál viac, ako keď mi niekto vnucuje odsadenie 4 medzerami.
Mně osobně taby ani mezery až tak nevadí, přizpůsobím se když je potřeba, ale co mi vadí je vzájemné míchání. Když to jeden dělá tak, druhý jinak, tak mám část kódu odsazenou na dva tabulátory, část na čtyři mezery a něco třeba na osm mezer. Bohužel u velkých projektů se to málokdy podaří uhlídat. Vývoj trvá několik let, pak se několik let opravují chyby, dodělávají nové funkce, pracují na tom mraky programátorů s různými zkušenostmi, většinou ani nedostanou dokumentaci a na nějaký styl kódu se moc nehraje. Hlavně, že to funguje
Když se ke mně dostane taková hrůza, tak to většinou musím přeformátovat, jinak se v tom nevyznám.
Patrně jsi opomněl, že se nejedná o mé prostředí, ale o prostředí druhých. Kvůli tomu, že já jsem na něco zvyklý, nebudu jim všechno přenastavovat, že?
naopak mezery poskytují konsistentní formátování za každých okolností
Keď človek nie je úplný magor tak je formátovanie tabmi konzistentné za každých okolností (bez ohľadu na editor, aj v notepade .. teda keby som používal konce riadkov ako MS). Na odsadenie medzerami si musím nastaviť editor tak aby bol prispôsobený na počet medzier ktoré sú v zdrojovom kóde použité ako odsadenie aby som po stlačení backspace mohol zmenšiť odsadenie o správny počet medzier. Pri použití tabov backspace za každých okolností v každom editore zmenší odsadenie. Jediné čo vidím nekonzistentné je rôzna šírka tabulátora [čo je aj tak väčšinou 4 znaky, nehovoriac o tom, že takmer vždy (aj v krčme) mám so sebou vlastný notebook na ktorom robím radšej].
Nemyslím si. Má to i své výhody. Například takové dynamické generování build scriptů za běhu buildu. Takhle mám XSLT transformačku, která z lidského XML vygeneruje Antí hnus. Kdybych toto měl dělat pro nějaký programovací build engine, musel bych řešit gramatiky, parsery, generátory a já nevím co všechno.
Uznávám, že je to silně nezvyklé, že to na provní pohled může působit jako WTF, ale jsou případy, kdy to prostě na plný čáře vyhrává… Já bych to být tebou tak kategoricky neodsuzoval.
Kdybych toto měl dělat pro nějaký programovací build engine, musel bych řešit gramatiky, parsery, generátory a já nevím co všechno.Nikoliv, stačí použít API
Jasněé. A proč to rovnou nenapsat v byte kódu. A nejlépe rovnou zazipovaný v jaru.
Které například?
Jako výhodu cmake vidím hlavně v tom, že tam není obludný skript configure, který měl i u jednoduchého projektu klidně 1MB.
Které například?třeba kglobalaccel se mi tak jeví ... a podotýkám, že to mluvím o prvním pokusu a ne o následných rekompilacích se zapojením ccache (protože se mi ta blbost aktuálně nenainstaluje :-/, tak běhů s ccache jsem viděl dost, a tam je to rychlejší znatelně)
Máš jen 4.2.67, nebo máš i paralelně 4.2.1?
Máš jen 4.2.67, nebo máš i paralelně 4.2.1?ted mam XFCE z instalacniho CD, neb testovaci stroj mi zhebnul
Aha. Já mám totiž 4.2.1 a potřeboval jsem vyzkoušet aktuální verzi gwenview. Tak jsem odmaskoval gwenview, kdelibs a ještě pár balíku a nahodil gwenview z 4.2.67. To sice šlapalo, ale instalace kipi-pluginu selhala, protože závislosti byly v 4.2.1. Takže mi z toho vychází buď 4.2.1 nebo 4.2.67, dohromady to asi nebude jen tak
BTW: a myslíš si, že s autotools by to bylo rychlejší, nebo snad srovnatelně rychlé?
BTW: a myslíš si, že s autotools by to bylo rychlejší, nebo snad srovnatelně rychlé?nemyslím ... a btw, ty myslíš, že cmake bude za těch N let, až to bude stejně staré, jako nyní autotools, stejně rychlé jako současná verze?
Nejsem věštec, ale klidně by cmake mohlo být ještě rychlejší.
Configure skript mi běží někdy i půl minuty, cmake ani nepoznám.njn, a mě zase cmake někdy běží klidně i půl minuty
Jinak čistě z uživatelského hlediska je podle mě zase lepší používat cmake. Když se podívám, kolik těch autotools verzí musím mít nainstalovaných, tak je mi z toho zle:)hm, jako kdyby cmake občas taky nevyžadovalo přesnou verzi ...
> Když se podívám, kolik těch autotools verzí musím mít nainstalovaných
A proc jich mas tolik nainstalovanych?
Pro normalni kompilaci ze zdrojaku (vyuzivajici autotools) by nemely byt autotools potreba. Ty jsou treba akorat tak pri kompilaci software z vyvojarskeho CVS (ci jinych nereleasovanych zdrojaku) nebo v pripade, kdy autor neumi udelat zdrojakovy balicek. Nebo kdyz jsi sam vyvojar, pak ti ale nic nebratni ve svych projektech prejit na jednu verzi.
Jj, syntaxe je des... V KDE je aspon pekne, ze je napsanych milion ruznych cmake modulu, funkci atd., takze i slozitejsi veci se daji delat jednoduse... Horsi pokud si clovek chce napsat vlastni ne KDE ci dostane do rukou jiny projekt, ktery to ma zmrsene... I kdyz i rucni prekladani by bylo lepsi nez Autotools! Naposledy jsem bojoval s Gnashem...
A budeme mit dalsi moloch ala autotools... Proste je trebas si zvyknout a basta...
S většinou připomínek souhlasím, ale nějak zvlášť mě nepálí i když CMake používám. Syntax mi nevadí, číst se to dá, upravovat taky a většinou toho zas tak moc není. Z hlavy ty funkce není potřeba znát, stejně je napíšu jednou a příště až u dalšího projektu, mezitím bych zapomenul cokoli. Co mě mrzí mnohem víc je nic moc dokumentace. Nikdy z ní nedokážu vyčíst co potřebuju nebo jak se co používá, ať už šlo o trivialitu jako zapnutí -Wall pro gcc, nebo něco složitějšího, jako linkování programu s Qt a prohnání souborů 'moc'em. Ale když jsem to někde našel v příkladu, tak to tak hrozné není. Používá se to fajn, když už si to člověk jednou hezky nastaví.
Na debug definice používám tohle:
OPTION(project_DEBUG "Build the project with debugging code" OFF)
IF(project_DEBUG)
SET(CMAKE_BUILD_TYPE Debug)
SET_SOURCE_FILES_PROPERTIES(${project_SOURCES} COMPILE_FLAGS -DDEBUG)
ELSE(project_DEBUG)
SET(CMAKE_BUILD_TYPE Release)
ENDIF(project_DEBUG)
Defaultně je pak debug vypnutý ("OFF" v prvním řádku), vývojář si ho může natrvalo zapnout pomocí 'make edit_cache' a přepnutím příslušného flagu.
Tak tak, tiež mi k CMake chýba poriadna dokumentácia. Minule keď som musel robiť v jave som musel siahnuť po obyčajných makefile súboroch (keďže podpora javy v CMake vôbec nie je zdokumentovaná).
CMake mimochodom podporuje niečo ako CMAKE_CXX_FLAGS_RELEASE, CMAKE_CXX_FLAGS_DEBUG, dá sa to využiť napr.
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -Wall -DNDEBUG") set(CMAKE_CXX_FLAGS_DEBUG "-O2 -ggdb -Wall -DDEBUG") if(CMAKE_BUILD_TYPE MATCHES Debug) message(STATUS "Configured to compile including full debug information in the executables") else(CMAKE_BUILD_TYPE MATCHES Debug) message(STATUS "Configured to compile including debug information in the executables") set(CMAKE_BUILD_TYPE Release) endif(CMAKE_BUILD_TYPE MATCHES Debug)
Minule keď som musel robiť v jave som musel siahnuť po obyčajných makefile súboroch
Pro příště: Apache Ant. Vzhledem k tomu, že v Javě neděláš, tak zkus příště NetBeans. Ty za tebe ten build.xml
vygenerují. A ten se dá dost dobře ohnout. Možná bych o tom mohl něco víc napsat…
No, tak to naprosto chápu. Pro pár řádek bych se s Antem taky moc ne… to, no — neobtěžoval.
Pravdu povediac nemám chuť písať xml kvôli programom typu "hello world" rovnako ako sa mi nechce čakať 10x dlhšie na štart IDE než na štart kompletného systému a štart odľahčeného "IDE".Jenže zatímco make spouští pro každý soubor
javac
, ant
defaultně kompiluje všechno v jednom. A podle mých zkušeností je i pro poměrně malé programy overhead opakovaného spouštění javac
nesnesitelně velký. No a na vytvoření jednoduchého build.xml
není potřeba spuštět těžkotonážní IDE Můžeš to prosím trošku rozvést?
Build je proces, a proces se popisuje programem
Tento argument s dovolením neberu. Proces se popisuje diagramem (například v UML). Jen určité typy procesů se dají implementovat programem. A zrovna ten proces sestavení programu nemusí být implementován programem. Na ten Gant a Gradle jsem se díval a moc mě to nepřesvědčilo. Ale asi jsem jen moc zvyklý na Ant… Ale uznávám, že je to spíš akademická diskuze.
IF ( ENABLE_AUTOTOOLS )
BLABLALBA
ELSE ( ENABLE_AUTOTOOLS )
BLBABLABLA
ENDIF ( ENABLE_AUTOTOOLS )
lze take zapsat jako:
IF ( ENABLE_AUTOTOOLS )
BLABLALBA
ELSE ()
BLBABLABLA
ENDIF ()
je jen na uzivateli zda to zapne. Treba me se ta nutnost libi pac si nemusim psat komentare co je to za blok kodu.Když to tak čtu, existuje vůbec někdo kdo má rád autotools?
Ja taky.
Už celkem dlouho používám cmake jako hlavní generátor makefiles a projektů pro IDE. Občas, když na něco nemůžu přijít si řákám, je tento systém opravdu tak skvělý, jak nám prezentují jeho zastánci? Prostředí KDE udělalo CMake určitě pěknou reklamu, osobně jsem autotools rád neměl nikdy, takže se vývojářům KDE ani nedivím a teď musí být šťastní jako blechy. Jenže když vidím tu syntax cmake, tak si často říkám, je toto právě to co vývojáři chtějí?
Seznamovat s cmake asi nemá cenu. Programátoři v C/C++ na tento systém určitě už narazili a buď ho přijali nebo zavrhli. Já jsem byl jeden z těch, kdo tento systém přijal. Cítím se asi podobně jako vývojáři KDE - cokoliv je lepší než autotools. Jenže jak doba plyne, tak začínám tu syntax nenávidět. Připadá mi, že místo toho, aby autoři cmake použili něco smysluplného, tak museli vymyslet něco totálně jiného a celkem komplikovaného.
Následuje malý příklad mini-projektu v cmake (jedná se o cmake projekt pro knihovnu AsmJit):
cmake_minimum_required(VERSION 2.6) Project(AsmJit C CXX) Set(ASMJIT_DIR ".") Set(ASMJIT_BASE_SOURCES ${ASMJIT_DIR}/AsmJit/AsmJitAssemblerX86X64.cpp ${ASMJIT_DIR}/AsmJit/AsmJitCpuInfo.cpp ${ASMJIT_DIR}/AsmJit/AsmJitLock.cpp ${ASMJIT_DIR}/AsmJit/AsmJitLogger.cpp ${ASMJIT_DIR}/AsmJit/AsmJitLoggerX86X64.cpp ${ASMJIT_DIR}/AsmJit/AsmJitLoggerX86X64Dump.cpp ${ASMJIT_DIR}/AsmJit/AsmJitMemoryManager.cpp ${ASMJIT_DIR}/AsmJit/AsmJitSerializerX86X64.cpp ${ASMJIT_DIR}/AsmJit/AsmJitUtil.cpp ${ASMJIT_DIR}/AsmJit/AsmJitVirtualMemory.cpp ) Set(ASMJIT_BASE_HEADERS ${ASMJIT_DIR}/AsmJit/AsmJit.h ${ASMJIT_DIR}/AsmJit/AsmJitAssembler.h ${ASMJIT_DIR}/AsmJit/AsmJitAssemblerX86X64.h ${ASMJIT_DIR}/AsmJit/AsmJitBuild.h ${ASMJIT_DIR}/AsmJit/AsmJitConfig.h ${ASMJIT_DIR}/AsmJit/AsmJitCpuInfo.h ${ASMJIT_DIR}/AsmJit/AsmJitDefs.h ${ASMJIT_DIR}/AsmJit/AsmJitDefsX86X64.h ${ASMJIT_DIR}/AsmJit/AsmJitLock.h ${ASMJIT_DIR}/AsmJit/AsmJitLogger.h ${ASMJIT_DIR}/AsmJit/AsmJitLoggerX86X64.h ${ASMJIT_DIR}/AsmJit/AsmJitMemoryManager.h ${ASMJIT_DIR}/AsmJit/AsmJitSerializer.h ${ASMJIT_DIR}/AsmJit/AsmJitSerializerX86X64.h ${ASMJIT_DIR}/AsmJit/AsmJitUtil.h ${ASMJIT_DIR}/AsmJit/AsmJitVirtualMemory.h ${ASMJIT_DIR}/AsmJit/AsmJitWarningsPop.h ${ASMJIT_DIR}/AsmJit/AsmJitWarningsPush.h ) Set(ASMJIT_COMPILER_SOURCES ${ASMJIT_DIR}/AsmJit/AsmJitCompilerX86X64.cpp ) Set(ASMJIT_COMPILER_HEADERS ${ASMJIT_DIR}/AsmJit/AsmJitCompiler.h ${ASMJIT_DIR}/AsmJit/AsmJitCompilerX86X64.h ) Include(FindThreads) If(CMAKE_THREAD_LIBS_INIT) Link_Libraries(${CMAKE_THREAD_LIBS_INIT}) EndIf(CMAKE_THREAD_LIBS_INIT) Include_Directories(${ASMJIT_DIR}) If(${CMAKE_BUILD_TYPE} STREQUAL "debug") Add_Definitions(-DDEBUG) EndIF(${CMAKE_BUILD_TYPE} STREQUAL "debug") Add_Library(AsmJit SHARED ${ASMJIT_BASE_SOURCES} ${ASMJIT_BASE_HEADERS} ${ASMJIT_COMPILER_SOURCES} ${ASMJIT_COMPILER_HEADERS}) Link_Libraries(AsmJit) Add_Executable(testcompiler ${ASMJIT_DIR}/test/testcompiler.cpp ) Add_Executable(testcpu ${ASMJIT_DIR}/test/testcpu.cpp ) Add_Executable(testjit ${ASMJIT_DIR}/test/testjit.cpp ) Add_Executable(testjumptable ${ASMJIT_DIR}/test/testjumptable.cpp ) Add_Executable(testmemorymanager ${ASMJIT_DIR}/test/testmemorymanager.cpp ) Add_Executable(testopcode ${ASMJIT_DIR}/test/testopcode.cpp ) Add_Executable(testrewrite ${ASMJIT_DIR}/test/testrewrite.cpp ) Add_Executable(testvariables ${ASMJIT_DIR}/test/testvariables.cpp )
Ještě než narazím na věci co mi vadí proberu základy. Hned ze začátku pomocí cmake_minimum_required(VERSION 2.6)
říkám, že chci minimální verzi cmake 2.6, pokud máte starší verzi, zobrazí se warning a buď skript projde, nebo ne.
Jako další věc co je nutné udělat je vytvořit projekt,
Project(AsmJit C CXX)
znamená, že vytvářím projekt, který používá C a C++ překladač. Zde bych chtěl upozornit na první problém. Pokud vytvoříte jen C++ projekt (CXX) a použijete později například Include(FindThreads)
, tak váš skript skončí chybou (protože FindThreads potřebuje C překladač).
Následuje seznam souborů v projektu. Pro přidání souborů rád používám něco jako Set(ASMJIT_DIR ".")
, abych si usnadnil případnou refaktorizaci (zatím bylo potřeba 1x). Soubory se často rozdělujou na zdrojové a hlavičkové, protože ty hlavičkové je v linuxu možné pomocí make install nainstalovat (ukázkový skript to ale neobsahuje).
Až po sem je skript celkem přímočarý. Následuje část:
Include(FindThreads) If(CMAKE_THREAD_LIBS_INIT) Link_Libraries(${CMAKE_THREAD_LIBS_INIT}) EndIf(CMAKE_THREAD_LIBS_INIT)
Která se mi nelíbí. Začnu tím jednodušším - člověk si musí pamatovat 2 věci k tomu, aby udělal jednoduchou detekci - Include(FindThreads) a CMAKE_THREAD_LIBS_INIT. Druhá věc co mi vadí je kód pro vytváření podmínek. Ukončovat podmínku pomocí EndIf() a vevnitř ji ještě zopakovat, kde to jsme?
Poslední věc co bych této části vytkl je to, že já už jsem z toho tak zmatený, že se mi stále daří udělat chybu v ${} (zapomenu na ${} nebo to tam dám navíc). Jasně, je to moje nepozornost, ale prostě se mi to stává.
Pokračujeme :) Dnes jsem doplňoval tuto věc:
If(${CMAKE_BUILD_TYPE} STREQUAL "debug") Add_Definitions(-DDEBUG) EndIF(${CMAKE_BUILD_TYPE} STREQUAL "debug")
Při pohledu na ten kód je celkem jasné, co to dělá (přidá definici DEBUG pokud je build nastavený na debug). Zajímalo by mě, jestli je toto ta pravá cesta, a kolik lidí používající cmake by to napsalo z fleku bez použití manuálu. CMAKE_BUILD_TYPE proměnná se mi zdá jako jediná věc, co je na tomto kódu v pohodě. Podmínka je podle mě strašná, místo ${CMAKE_BUILD_TYPE} STREQUAL "debug"
by se v jiném jazyce dalo napsat třeba CMAKE_BUILD_TYPE == "debug"
. Vím, že je to hodně podobné, ale není vám to bližší?
Ten zbytek kódu podle mě není třeba komentovat (vytvoření sdílené knihovny a testovacích aplikací).
V tomto zápisku mi jde hlavně o to, že cmake se používá asi nejvíc mezi C/C++ programátory (nebo ne?) a ta syntaxe mi přijde v této oblasti nepřirozená. Nejde mi jen o to, že to vypadá jinak, ale zkuste si v tom napsat něco složitějšího - funkci, která má vstupy a výstup a zkuste si tu funkci používat. Nebylo by rozumnější používat něco, co používá skriptování blízké k C/C++? Třeba ten poslední příklad by se v pseudo-javascriptu dal napsat takto (objekty jsem si vymyslel, nic takového neexistuje):
if (Global.buildType == "debug") { Global.definitions.append("DEBUG"); }
Kdyby existovalo něco takového, tak bych asi neváhal ani sekundu:) Nejde mi jen o tu syntax, ale i o koncepci. Kdybych chtěl nějakou definici testovat, tak by stačilo napsat třeba takovou podmínku if (Global.definitions.contains("DEBUG") ...
. Kdybych šel ještě dál, tak si myslím, že pomocí EcmaScriptu by se daly psát i komplikovanější pluginy, třeba i na vytvoření makefiles a project IDE files. Radši ani nemluvím o tom, že podporu pro EcmaScript mají různé IDE přímo v sobě, takže kontrola syntaxe nebo našeptávání by mohla ještě víc zrychlit tvorbu skriptů.
Pokud používáte cmake, zkuste mi odpovědět v anketě, výsledky mě zajímají:)
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.