[CMake] Hi and some newbie questions
Jack Kelly
endgame.dos at gmail.com
Fri Sep 14 06:57:31 EDT 2007
Goswin von Brederlow wrote:
> Jack Kelly <endgame.dos at gmail.com> writes:
> What happens when CFLAGS is already set in the environment or when I
> need to just extend it. I guess what I'm looking for is the Makefile
> syntax
>
> CFLAGS += something
# Try this:
SET(CMAKE_C_FLAGS "$ENV{CFLAGS} -fno-builtin ...")
>
>> # One way would be to have a file i486.cmake:
>> SET(ARCH i486)
>> # and whatever else...
>
> And cmake automatically includes the right file then?
>
>> # A file called x86_64.cmake:
>> SET(ARCH x86_64)
>> # ...
>>
>> # Put this in the CMakeLists.txt:
>> INCLUDE(${PLATFORM})
>>
>> # and invoke cmake like so:
>> # cmake -DPLATFORM=x86_64 /path/to/build
>
> That would be stupid. It should know itself what architecture to pick.
I agree, but I can't see a way to let CMake do that. Anyone else have
any ideas? If you were on a *ix system you could FIND_PROGRAM a copy of
config.guess and parse its output. Yuk.
>>> # Now here is my first big problem. CMake doesn't know how to handle
>>> # any of these:
>>> #add_executable (mini-os.gz mini-os.elf x86_64.o)
>> # I don't think ADD_EXECUTABLE is what you're looking for here.
>> # If you can set up the build steps with ADD_CUSTOM_COMMAND you should
>> # be able to add those with an ADD_CUSTOM_TARGET
>
> 'add_executable (mini-os.elf ....)' at least should work. The target
> is a normal elf binary. The x86_64.o object file just doesn't tell
> cmake enough to know how to link it. I figure it wants to know whether
> this is C or C++ or some other language needing special flags. Once I
> add some *.c file there or if I could teach cmake about *.S then it
> should work.
# To teach CMake about *.S I believe you'd need 4 files:
# CMakeASMCompiler.cmake.in
# CMakeASMInformation.cmake
# CMakeDetermineASMCompiler.cmake
# CMakeTestASMCompiler.cmake
# There are similar ones for C, CXX and Java. You'd then be able to
# write:
PROJECT(MOOSE C ASM)
# Or whatever the list of languages you use is.
>>> # How do I make a rule for assembler files? Doesn't seem to be preset.
>>> ADD_CUSTOM_COMMAND (OUTPUT x86_64.o
>>> COMMAND gcc -D__ASSEMBLY__ -Iinclude -Iinclude/x86 -Iinclude/x86/x86_64 -c x86_64.S -o x86_64.o
>>> COMMENT Assembler pass)
>>>
>>> # Or define my own linker script?
>>> ADD_CUSTOM_COMMAND (OUTPUT mini-os.elf
>>> COMMAND ld -N -T minios-x86_64.lds -m elf_x86_64 x86_64.o -L. -lminios -o mini-os.elf
>>> DEPENDS x86_64.o minios
>>> COMMENT Link kernel into shape)
>>>
>>> # And a rule to gzip the result?
>>> ADD_CUSTOM_COMMAND (OUTPUT mini-os.gz
>>> COMMAND gzip -f -9 -c mini-os.elf >mini-os.gz
>>> DEPENDS mini-os.elf
>>> COMMENT compress kernel)
>> # These look reasonable, apart from the fact that you should be looking
>> # for the executables with FIND_PROGRAM because not everyone will have
>> # the right versions at the front of the system path. Just allows a user
>> # override, that's all. Are they giving you a specific problem?
>
> Just that they disapear when I don't have a ADD_CUSTOM_TARGET
> depending on them. The rest is just taste. They look dirty.
# What else would you expect them to do? Without an ADD_CUSTOM_TARGET,
# there's no way to know when or why to run them.
> For the mini-os.elf I thought I could set some LDFLAGS (for -T
> minios-${ARCH}) and have it fill in the remaining parts automatically
> as it would with ADD_EXECUTABLE in some way.
# You could add $ENV{LDFLAGS} to the COMMAND part of the
# ADD_CUSTOM_COMMAND, or set it up to use one of the
# CMAKE_..._LINKER_FLAGS variables (there's a variable for EXE, MODULE,
# SHARED and STATIC, and again, variables for DEBUG, RELEASE, etc.)
> I think what I was really asking here was how to make a pattern rule
> here. In Unix Makefile terms:
>
> %.gz: %
> gzip -9 $<
>
> %.o: %.S
> gcc -D__ASSEMBLY__ <incude paths> <ASFLAGS> -c $< -o $@
# The best way I've found so far is to define a macro to gzip what you
# want:
IF(NOT DEFINED GZIP_EXECUTABLE)
FIND_PROGRAM(GZIP_EXECUTABLE gzip)
SET(GZIP_EXECUTABLE CACHE FILEPATH "Path to GZip executable")
ENDIF(NOT DEFINED GZIP_EXECUTABLE)
IF(NOT GZIP_EXECUTABLE)
MESSAGE(FATAL_ERROR "Gzip is required for building.")
ENDIF(NOT GZIP_EXECUTABLE)
MACRO(GZIP_FILE INFILE GZIPFILE)
ADD_CUSTOM_COMMAND(
OUTPUT "${GZIPFILE}"
COMMAND "${GZIP_EXECUTABLE} -f -9 -c ${INFILE}>${GZIPFILE}"
MAIN_DEPENDENCY "${INFILE}"
COMMENT "Compress ${INFILE} to ${GZIPFILE}"
VERBATIM)
ENDMACRO(GZIP_FILE)
# You can probably make this smarter (e.g., derive the gzipped file name
# from the input file name, but I didn't bother.
>> # You may also want to add explicit paths
>> # (like gcc -c ${MOOSE_SOURCE_DIR}/x86_64.S) and see if it's possible to
>> # do away with that redirection in the gzip.
>
> Yes to the first part. Why to the redirection? Is it worth splitting
> that in 'gzip mini-os.elf' and 'mv mini-os.elf.gz mini-os.gz'.
# To my mind (though I could well be wrong here) is that you mutate your
# source files as little as possible so redirecting would be better than
# gzip and move/copy (hint, you can use
${CMAKE_COMMAND} -E copy file dest
# to copy a file in a platform independent way, as part of an
# ADD_CUSTOM_COMMAND or so.
# The redirection seems unwise because it relies on the shell in which
# it executes supporting it. However, I can't find a way to do
# redirection at build time (at configure time, it's easily done with
# EXECUTE_PROCESS, but to make it work at build time you need to then
# configure a cmake file and run ${CMAKE_COMMAND} -P on it, which gets
# very messy very quickly. I gave up and just went with the >.
# -- Jack
More information about the CMake
mailing list