CMake: generate sources during CMake script execut

2019-09-07 12:15发布

问题:

I'm trying to migrate my Visual Studio solution to CMake.

I have two projects - generator (generator.exe generates C++ sources from text files) and myProj (includes some text files that have to be processed by generator.exe).
What I want is:

  1. build generator project
  2. use generator.exe from step1 to generate C++ source files from text files in project myProj
  3. put those generated source files in resulting VS project for myProj

So, how to do this?

EDIT what I've tried so far:

###################################################################
# in root/generator/CMakeLists.txt:
set(SRC_LIST .... )
set(HDR_LIST .... )
add_executable(generator ${SRC_LIST} ${HDR_LIST})    

###################################################################
# in root/my_proj/CMakeLists.txt:

add_subdirectory(../generator/  ../generator/cmake_out)
add_subdirectory(src)

###################################################################
# in root/my_proj/src/CMakeLists.txt:    

ADD_CUSTOM_COMMAND(
   OUTPUT ../include/SomeSource.h SomeSource.cpp
   COMMAND generator ../definitions/SomeDefs1.txt
   DEPENDS generator ../definitions/SomeDefs1.txt
   )

set(SRC_LIST SomeSource.cpp .... )
set(HDR_LIST SomeSource.h .... )

add_library(myProj STATIC ${SRC_LIST} ${HDR_LIST} )

###################################################################
###################################################################

CMake's output:

.....
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler using: Visual Studio 12 2013
-- Check for working CXX compiler using: Visual Studio 12 2013 -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
CMake Error at src/CMakeLists.txt:145 (add_library):
  Cannot find source file:

    ../include/SomeSource.h

  Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
  .hxx .in .txx

回答1:

Start with CMake's add_custom_command() and take it from there:

add_executable( generator ${generator_SOURCES} )
add_custom_command( OUTPUT source1.cpp source2.cpp
    COMMAND generator args1 args2
    COMMENT "Generating sources..." )

Whether or not to integrate myProj into your other project, or keep it external is up to your individual needs, and influences how the final setup would look like.


Reply to your edit:

First off, it is an extremely bad idea to include header files in the list of sources. CMake, in cooperation with the compiler, is supposed to figure out the dependencies of source files on the header files they include, and they do a much better job at it than most humans. C++'s #include already tells the compiler to process the header!

Second, the CMake code you are showing is not the one you are executing. Your add_library() lists SomeSource.h, but CMake complains about ../include/SomeSource.h. The directory names also do not work out. This makes it hard to say what exactly is wrong.

My generic suggestion when familiarizing yourself with a new tool: Do not immediately try to make it dance in the context you eventually want it to work in (myProj, in this case). Instead, set up a simple test environment (with directories X and Y, source files foo.cpp and bar.cpp, you get the idea), and test the concepts (like, having echo create a file instead of generator, so you do not need to build generator first -- that's the next step).

That way, if any problems pop up, you can ask for help in the abstract, and you can provide complete example code for others to figure out without having to wiggle through your project's setup.

Also, you avoid problems that arise from faulty preconceptions. Quite often, your first attempt will result in an awkward setup, and real elegance only arises from the lessons learned. Invest the time to learn the tool properly.


If you didn't know about it already, source_group() allows CMake to create a MSVC project file with the given source files grouped together, so you can have your project under CMake control but still work comfortably inside MSVC.


I've set up a "framework" CMake setup I am working from in various projects, perhaps you're interested in it (for inspiration or actual use): JAWS.



标签: c++ cmake