I use a CMakeLists.txt like the following
cmake_minimum_required(VERSION 3.5)
project(generate_files_from_tool)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_custom_command(
OUTPUT generated_config.cpp
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/writeSourceFileFromConfigXml.sh ${CMAKE_CURRENT_SOURCE_DIR}/config.xml > ${CMAKE_CURRENT_BINARY_DIR}/generated_config.cpp
DEPENDS config.xml writeSourceFileFromConfigXml.sh
)
add_executable(tool_with_generated_file main.cpp generated_config.cpp)
which generates a file (here generated-config.cpp) in the build process using a custom script (writeSourceFileFromConfigXml.sh).
I can open it using QtCreator 4.4.1 just fine: Compile and run works -- but I cannot see the file generated_config.cpp in the Projects view, only CMakeLists.txt and main.cpp is visible there.
If I open the file "manually", QtCreator displays a warning "This file is not part of any project." -- but it uses the file for the compilation. And after opening the file, I'm able to switch between definition and implementation using Ctrl+Klick or F2 (and get to/come from generated_config.cpp)
So my question is: How can I make QtCreator understand, that this generated file is part of the project and add it to the Projects view?
Note: changing the last line to add_executable(tool_with_generated_file main.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated_config.cpp) did not change anything.
I am using a workaround to show generated sources located outside of build directory:
I have symlinks created in PROJECT_SOURCE_DIR to directories where generated sources are located, say src1, src2 (it is important to not use real paths). Then I use :
file(GLOB SOURCE_FILES ${PROJECT_SOURCE_DIR}/src1/*.[ch] ${PROJECT_SOURCE_DIR}/src2/*.[ch])
add_custom_target(
all_src
SOURCES ${SOURCE_FILES}
)
Related
I run a python script over each of my source files in order to generte additional code. The generated code can then be included in the source file and its content be used.
#include <Main.cpp.generated.hpp>
In order to make it work with CMake, I've added this python script as a custom cmake, because it seems to be the common way to make it work.
My CMake script looks like this (ignore the hardcoded paths, it's a proof of concept).
cmake_minimum_required (VERSION 3.20)
project(test)
add_executable(target Main.cpp test.h for_each.hpp ${CMAKE_CURRENT_BINARY_DIR}/gen/Main.cpp.generated.hpp)
add_custom_command(
OUTPUT gen/Main.cpp.generated.hpp
COMMAND python D:/Projects/clang-plugins/test-gen/test-gen.py ${CMAKE_CURRENT_SOURCE_DIR}/Main.cpp ${CMAKE_CURRENT_BINARY_DIR}/gen/Main.cpp.generated.hpp
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Main.cpp)
target_compile_features(target PRIVATE cxx_std_17)
target_include_directories(target PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/gen)
Everytime I modify my Main.cpp file, the generated file is rebuilt. Which is good. However, if a file included by Main.cpp changes, the generated file is not rebuilt. Which is a problem because then the generated code can be outdated. I can fix it by adding those headers into the DEPENDS arg, but I don't want to do this my hand.
I don't want to trigger my custom command everytime the file Main.cpp changes, but everytime the file Main.cpp is rebuilt.
I want to start building a project and I have the following folder structure:
lib
|---class1.cpp
|---class1.hpp
src
|---main.cpp
I have the MinGW compiler and I don't know how to compile all .cpp files. I know the command g++ *.cpp -o main for compiling all the files, but works only for files in the same folder.
Should I move all my files to the src folder? Should I change the project structure?
Also, I'm really doubtful if I should use CMake or not.
FINAL:
I decided to go with CMake which made my life easier.
For a barebones project, your structure is fine. Just add the following CMakeLists.txt file to the root of your directory:
cmake_minimum_required(VERSION 3.5)
# Given your project a descriptive name
project(cool_project)
# CHoose whatever standard you want here... 11, 14, 17, ...
set(CMAKE_CXX_STANDARD 14)
# The first entry is the name of the target (a.k.a. the executable that will be built)
# every entry after that should be the path to the cpp files that need to be built
add_executable(cool_exe src/main.cpp lib/class1.cpp)
# Tell the compiler where the header files are
target_link_libraries(cool_exe PRIVATE lib)
Your directory should now look like
CMakeLists.txt
lib
|---class1.cpp
|---class1.hpp
src
|---main.cpp
Then to build the project, you will typically
Make a folder where you build everything (often called build, but it's up to you). Now the directory looks like
CMakeLists.txt
lib
|---class1.cpp
|---class1.hpp
src
|---main.cpp
build
Go into the build folder and on the command like, configure your project with the command cmake .. (just to reiterate... this needs to be done from inside the build folder).
Build your project with the make command (again from inside the build folder).
After that, you should have an executable called cool_exe in the build folder.
I am trying to automatically have my Makefiles written for my C++ project using CMake with GLOB. The code and headers are however located in two separate folders.
/Users/username/Coding/Major Projects/ProjectName/Backend
and
/Users/username/Coding/Major Projects/ProjectName/Terminal
The backend has platform independent code. Just a bunch of c and c++ source files. And the Terminal folder has some code that uses the objects specified in Backend to run some tests on them. The reason these are in separate folders is that the Backend code is Multiplatform. So an Xcode project imports it etc. The Terminal folder has the testing code because that is the only one that is trying to compile it into a linux binary.
Anywho, I have the following CMakeList.txt file that I am trying to build to generate the Makefile.
cmake_minimum_required(VERSION 2.8.9)
project(terminalTest)
set(MainSource "/Users/username/Coding/Major Projects/ProjectName/Backend")
set(TerminalSource "/Users/username/Coding/Major Projects/ProjectName/Terminal")
#Bring the headers, such as Student.h into the project
include_directories(${MainSource} ${TerminalSource})
#Can manually add the sources using the set command as follows:
#set(SOURCES src/mainapp.cpp src/Student.cpp)
#However, the file(GLOB...) allows for wildcard additions:
file(GLOB SOURCES "./{${MainSource},${TerminalSource}}/*.cpp")
add_executable(terminalTest ${SOURCES})
And the result of this when I run this from the CMake GUI is a successful configure but an error No SOURCES given to target: terminalTest meaning that my file() command is not working properly.
I think it could have something to do with the fact that I have spaces in my paths but that doesn't seem to do it either. By the way I am putting this file in the Terminal folder and attempting to build from Terminal/Build.
Is there any way to debug and see what sources the GLOB command is bringing in? Can I actually do a multi directory GLOB like this?
Your file(GLOB ...) path looks malformed. You can list the paths to your sources separately in this command to grab all the source files in both directories.
file(GLOB SOURCES
${MainSource}/*.cpp
${TerminalSource}/*.cpp
)
I've I'm trying to build this "Hello World" wxWidgets example on Linux, using the following cmake script:
cmake_minimum_required (VERSION 2.6)
project (wxL)
find_package(wxWidgets 3.0.0 REQUIRED
COMPONENTS base core net xml html adv qa richtext
)
file(GLOB SOURCES "src/*.cpp")
add_executable(wxL ${SOURCES})
Building the project yields this error:
src/wxL.cpp:3:10: fatal error: wx/wxprec.h: No such file or directory
The file specified in the include, wx/wxprec.h can be found on disk at this location:
/usr/include/wx-3.0/wx/wxprec.h
Furthermore, another program that I have built from source includes the same file (also using cmake) and builds just fine.
So, how do I use cmake to tell the compiler that the file should be included from somewhere in the system directories?
I know I'm missing something basic, but I can't figure out what.
Although you've found the package, your executable does not know anything about it.
For the executable to compile correctly, it needs to find header files for your package together with the .so / .a files. Following example should get you started:
include_directories(${wxWidgets_INCLUDE_DIRS})
add_executable(wxL <add-source-files-here>)
target_link_libraries(wxL ${wxWidgets_LIBRARIES}) // links wxWidgets libraries to your executable
Please note that using glob is not a recommended way of adding source files to your project.
As a follow up to this question:
Add Source in a subdirectory to a cmake project
What is the best way (perhaps using the FILE directive?) to select all the .cpp and .h files in the subdirectory and add them to the SOURCE variable defined in the parent directory?
Example from answer to question above:
set(SOURCE
${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/file1.cpp
${CMAKE_CURRENT_SOURCE_DIR}/file2.cpp
PARENT_SCOPE
)
set(HEADERS
${HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/file1.hpp
${CMAKE_CURRENT_SOURCE_DIR}/file2.hpp
PARENT_SCOPE
)
Is it possible to do something like this?
FILE(GLOB SUB_SOURCES *.cpp)
set(SOURCE
${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/${SUB_SOURCES}
PARENT_SCOPE
)
What is the best way (using CMake) to compile all the sources in a directory and a subdirectory into a single output file (not multiple libraries?)
I think what you are looking for is the aux_source_directory command.
aux_source_directory Find all source files in a directory.
aux_source_directory( )
Collects the names of all the source files in the specified directory
and stores the list in the provided. This command is
intended to be used by projects that use explicit template
instantiation. Template instantiation files can be stored in a
"Templates" subdirectory and collected automatically using this
command to avoid manually listing all instantiations.
It is tempting to use this command to avoid writing the list of source
files for a library or executable target. While this seems to work,
there is no way for CMake to generate a build system that knows when a
new source file has been added. Normally the generated build system
knows when it needs to rerun CMake because the CMakeLists.txt file is
modified to add a new source. When the source is just added to the
directory without modifying this file, one would have to manually
rerun CMake to generate a build system incorporating the new file.
Your CMakeLists.txt within the subdirectory could look like this:
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SUB_SOURCES)
set(SOURCE
${SOURCE}
${SUB_SOURCES}
PARENT_SCOPE
)
The recommended practice is however, as you see from the documentation, to list the files individually within CMakeLists.txt as changes to the CMakeLists.txt file triggers running cmake.
I hope this was helpful and to the point.