In a project generating protobuf files with cmake, is it possible to separate the headers from the source files with the protobuf_generate command?
Currently used is the following:
protobuf_generate(
TARGET
my_target
LANGUAGE
cpp
GENERATE_EXTENSIONS
.pb.h
PROTOC_OUT_DIR
${CMAKE_CURRENT_SOURCE_DIR}/gen/src
PROTOS
${PROTO_SOURCES}
)
protobuf_generate(
TARGET
my_target
LANGUAGE
cpp
GENERATE_EXTENSIONS
.pb.cc
PROTOC_OUT_DIR
${CMAKE_CURRENT_SOURCE_DIR}/gen
PROTOS
${PROTO_SOURCES}
)
Which generates both cc and h files into both directories. Is there a way to only generate the headers with the protobuf cmake commands, or the only way to solve it is to
move the generated files into a different folder?
Related
TL;DR
How do I configure CMake and Emscripten to build my static library to produce a WASM and JS bootstrap file?
I have a static library being built with CMake that I want to build as a WASM library (and JS bootstrap) using Emscripten. Simply using the Emscripten CMake toolchain and adding the appropriate compiler/linker flags result in only a .a file being built - even if -o <project name>.js is added to the compiler and/or linker flags.
The reason is that because I've told CMake I want a static library, it uses CMAKE_AR to build. CMAKE_AR (if undefined) is defined as emar in the Emscripten toolchain file, and emar cannot produce .wasm and .js output.
I have tried creating a new executable target that has a dependency on the library, and otherwise just sets up the compiler/linker settings. However this causes a CMake error, because I've defined an executable target that has no source files (they're associated with the library target). If I add a stub main file, I get an Emscripten warning:
system_libs:WARNING: main() is in the input files, but "_main" is not in EXPORTED_FUNCTIONS, which means it may be eliminated as dead code. Export it if you want main() to run.
I could get round by adding an empty file to exe source file list (probably, I haven't tried), but this feels very much like a hack.
You are correct in that you need to create an executable target in order to produce a .wasm file.
If cmake insists on you creating a dummy source file because it doesn't understand that all the code for your program can come from libraries then I guess you that is your best option.
See CMake: Is it possible to build an executable from only static libraries and no source? for how to work around this limitation of cmake.
I am trying to build a ROM image using CMake. I have a project root directory CMakeLists.txt file which calls add_subdirectory() to build the different components for the ROM image. These components are output in binary format. Once this is done I wish to combine the resulting binaries into a single image.
Currently I have a final add_subdirectory() call that is meant to use objdump to convert the binary output of the other modules to an object file and then link these into a unified elf that is then converted with objdump.
add_executable(rom_image.bin)
foreach (COMPONENT ${COMPONENTS})
set(COMPONENT_BINARY_FILENAME "${CMAKE_BINARY_DIR}/${COMPONENT}/output.bin")
set(COMPONENT_OBJECT_FILENAME "${COMPONENT}.o")
add_custom_command(
TARGET rom_image.bin
PRE_BUILD
OUTPUT ${COMPONENT_OBJECT_FILENAME}
DEPENDS ${COMPONENT_BINARY_FILENAME}
COMMAND ${OBJCOPY_PROGRAM}
ARGS --input-target=binary --output-target=elf32-littlearm --binary-architecture=arm ${COMPONENT_BINARY_FILENAME} ${COMPONENT_OBJECT_FILENAME}
)
endforeach()
This does not work as CMake complains that the target (rom_image.bin) has no source files.
In my CMake file I've specified an object library:
add_library(core OBJECT ${sourcefiles})
I refer to this set of object file in a shared library further on:
add_library(sharedlib SHARED $<TARGET_OBJECTS:core>)
This works fine, however I would like to reuse the build artefacts between different project.
By setting the LIBRARY_OUTPUT_PROPERTY on the sharedlib I can direct the generated .so file to a common directory:
set_target_properties(sharedlib PROPERTIES LIBRARY_OUTPUT_NAME /commondir)
However, I cannot seem to do the same thing for the core (OBJECT) library - the .o files always end up in the (project-specific) generated cmake-build directories.
This means every project will have to rebuild the (large) shared library anyway...
Am I doing something wrong, or is this not (yet?) possible with CMake?
You can't change the output directory of object/intermediate files in CMake. That's by design (to allow several identical output names in one project):
"There is no way to change that name.
CMake creates an exact copy of the source tree in
the binary tree."
But with version 3.9 CMake learned to export object libraries:
cmake_minimum_required(VERSION 3.9)
project(CorePorject)
file(WRITE "core.cpp" "")
file(WRITE "helper.cpp" "")
set(sourcefiles "core.cpp" "helper.cpp")
add_library(core OBJECT ${sourcefiles})
export(
TARGETS core
FILE core.cmake
NAMESPACE Core_
)
References
Set C++ object file output location with CMake
Set the directory for Intermediate files (like .obj) in CMake
Making cmake library accessible by other cmake packages automatically
I have a project developed under FORTRAN. To organize the project I have decomposed it in subdirectories. Then, I would use Cmake files to generate Makefiles.
The hierarchy of the project is:
Main_directory
|____lib
|____inc
|____src
|__src1
|__src2
|__src3
|____tests
|___test1.f90
|___test2.f90
The lib directory content compiled static lib files (. a), Inc contain include files (. h), and src content Fortran source files. Thus, source files in src folder depend between them during compilation, and file in src2 can use variables or function, from file in src1 and uses also lib and include files. Since, the source files in the source directory (src) are compiled they will be used by a source file(test1.f90 or test2.f90) that generate executable in test directory.
I'm newbie with Cmake so I would like to know how to write Cmake files for the main folder and subdirectories.
thank you.
I'm using cmake, and I just added new source files and I want to include that new source files in the cmake generated makefiles to include in the building. I tried rebuild_cache but nothing happens.
Thanks!
It depends how your cmake file was built. If you use GLOB, you must run cmake manually any time you add or remove a source file. If you explicitly list your source files, just run make again. CMake will detect the changed CMakeLists.text.
CMake suggests the latter for this reason:
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
CMake documentation