Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

CMake is nice. Or not?

I am play­ing with CMake. Specif­i­cal­ly, I am try­ing to re­place the sim­plis­tic hand­made Make­files for my RA-­Plu­g­ins projec­t.

The parts about de­tect­ing li­braries and con­di­tion­al­ly com­pil­ing plug­ins based on what you have were sur­pris­ing­ly easy!

Un­til I ran in­to ... man pages.

Here is a Make­file that would build all the man­pages for the plu­g­in­s:

MANPAGES=plugins-ra.8 authchecks.8 rcptchecks.8
man: \$(MANPAGES)
%.8: %.man.txt
      txt2man -t \${basename $< .man.txt} < $< > $@

As you can see... triv­ial. All I need to do in or­der to add a man page is add what­ev­er.8 to the list, and it will be cre­at­ed from what­ev­er.­man.tx­t.

But... how does one do that us­ing CMake?

I start­ed think­ing of us­ing a FILE (GLOB *.­man.tx­t) and then a FORE­ACH over that, and then... then what? Re­al­ly, I am stumped. I am a new­bie, though, and get­ting the big, dif­fi­cult stuff done is enough to switch. I should gen­er­ate these be­fore dis­tri­bu­tion any­way.

So, I wrote a wee Make­file.­man­pages and added this for CMAKE:

ADD_CUSTOM_TARGET ( manpages make -f Makefile.manpages )

But I am cu­ri­ous about find­ing the cmakeish way.

Alex / 2006-08-11 21:23:

Currently you can do it e.g. this way:

# add a target, but with no rules:
add_custom_target(man)

# use foreach to generate the rules using the 2nd type of
# add_custom_command(), so that each of these commands
# is executed when the target "man" is built:
foreach(file a.txt b.txt c.txt)
add_custom_command(TARGET man POST_BUILD
COMMAND cp ${file} ${file}.man )
endforeach(file)

(you will have noticed that the cp is not really appropriate to generate man pages, but I guess you get the idea)

It would be easier if it would be possible to use cmake code as command in add_custom_command() and add_custom_target(). I think I'll file a feature request for cmake.

Then you could do something like:

add_custom_target(man
SCRIPT "
FOREACH(file a.txt b.txt c.txt)
EXEC_PROGRAM(cp ${file} ${file}.man)
ENDFOREACH(file a.txt b.txt c.txt)
" )

Alex

P.S. The better way to get a response than blogging is to post either to
1) cmake@cmake.org
2) kde-buildsystem@kde.org
3) post a bug at b.k.o. for product "Buildsystem", component "KDE(cmake)"

Roberto Alsina / 2006-08-11 22:42:

Actually, that doesn't work. txt2man works by redirecting stdin and stdout. Of course I could write a wrapper, but in that case I could just write a shell script to generate the things ;-)

As about how it's a better idea to post to those places:

It's not at all KDE related, so 2 and 3 are out.

And I don't want to subscribe to mailing lists anymore, anyway, much less for a product I am just playing with.

So, I just post in my little page, and see if someone can help me. If noone can, I don't bother anyone.

Alex / 2006-08-12 14:48:

Can you please post a plain example command ?

Roberto Alsina / 2006-08-12 15:14:

txt2man -t rcptchecks < rcptchecks.man.txt > rcptchecks.8

Alex / 2006-08-12 23:29:

No problem there, the redirecting does work in add_custom_command(). You also need get_filename_component() to get the basename of the files.

Alex

Roberto Alsina / 2006-08-14 15:50:

Just in case someone googles this someday:

ADD_CUSTOM_TARGET ( manpages )
FILE (GLOB MANSOURCES *.man.txt)
FOREACH ( MANSRC ${MANSOURCES} )
GET_FILENAME_COMPONENT ( MANDST ${MANSRC} NAME_WE )
ADD_CUSTOM_COMMAND ( TARGET manpages POST_BUILD
COMMAND LANG=C txt2man -t ${MANDST} < ${MANSRC} > ${MANDST}.8 )
ENDFOREACH ( MANSRC )